Skip to main content
The ThreatClient provides access to Webacy’s threat and risk analysis APIs. Use it to analyze addresses for security risks, screen for sanctions, check smart contract vulnerabilities, and verify URL safety.

Initialization

import { ThreatClient, Chain } from '@webacy-xyz/sdk';

const client = new ThreatClient({
  apiKey: process.env.WEBACY_API_KEY,
  defaultChain: Chain.ETH, // Optional: set default chain
});

Resources

The ThreatClient provides access to these resources:
ResourceDescription
addressesAddress risk analysis, sanctions screening, poisoning detection, quick profiles
contractsSmart contract security analysis and code analysis
urlURL safety and phishing detection
walletsWallet activity and approval analysis
ledgerHardware wallet transaction scanning
accountTraceFund flow tracing
transactionsTransaction risk analysis
scanTransaction and EIP-712 message scanning
usageAPI usage statistics

Addresses

Analyze Address Risk

Get comprehensive risk analysis for any blockchain address.
const result = await client.addresses.analyze(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(result.overallRisk);  // 0-100 risk score
console.log(result.issues);       // Array of risk factors
console.log(result.isContract);   // true if smart contract
Response:
{
  "count": 1,
  "medium": 0,
  "high": 1,
  "overallRisk": 75.5,
  "issues": [
    {
      "tag": "Mixer User",
      "severity": "high",
      "description": "Address has interacted with mixing services"
    }
  ],
  "isContract": false
}
Options:
OptionTypeDescription
chainChainBlockchain to analyze (optional if defaultChain set)
modulesRiskModule[]Specific risk modules to run
detailedbooleanInclude detailed analysis data
deployerRiskbooleanInclude deployer risk for contracts

Check Sanctions

Screen an address against OFAC and other sanctions lists.
const result = await client.addresses.checkSanctioned(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

if (result.is_sanctioned) {
  console.error('Address is sanctioned!');
  console.log(result.sanction_details);
}

Check Address Poisoning

Detect address poisoning (dust attack) attempts.
const result = await client.addresses.checkPoisoning(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

if (result.is_poisoned) {
  console.warn('Address poisoning detected!');
  console.log(result.poisoning_details?.similar_addresses);
}

Get Quick Profile

Get a lightweight risk profile with optional token approvals.
const result = await client.addresses.getQuickProfile(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  {
    chain: Chain.ETH,
    withApprovals: true,  // Include token approvals
  }
);

console.log(`Risk score: ${result.riskScore}`);
console.log(`Risk level: ${result.riskLevel}`);
console.log(`Account age: ${result.accountAge} days`);

// Check approvals if requested
for (const approval of result.approvals ?? []) {
  console.log(`${approval.symbol} approved to ${approval.spenderName}`);
}
Options:
OptionTypeDescription
chainChainBlockchain to analyze (ETH, BASE, BSC, POL, OPT, ARB, SOL)
withApprovalsbooleanInclude token approval data
hideTrustFlagsbooleanHide trust flags in response

Contracts

Analyze Contract

Get security analysis for a smart contract.
const result = await client.contracts.analyze(
  '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
  { chain: Chain.ETH }
);

console.log(result.overallRisk);
console.log(result.vulnerabilities);

Get Contract Tax

Check buy/sell tax for a token contract.
const result = await client.contracts.getTax(
  '0xTokenAddress...',
  { chain: Chain.ETH }
);

console.log(`Buy tax: ${result.buyTax}%`);
console.log(`Sell tax: ${result.sellTax}%`);

Get Code Analysis

Perform static code analysis on a contract’s source code.
const result = await client.contracts.getCodeAnalysis(
  '0xContractAddress...',
  {
    chain: Chain.ETH,
    refreshCache: false,  // Use cached results if available
  }
);

console.log(`Total findings: ${result.findings.length}`);

for (const finding of result.findings) {
  console.log(`[${finding.severity}] ${finding.title}`);
  console.log(`  ${finding.description}`);
  console.log(`  Location: ${finding.location}`);
}
Response:
{
  "contractAddress": "0x...",
  "chain": "eth",
  "findings": [
    {
      "title": "Reentrancy vulnerability",
      "description": "External call before state update",
      "severity": "high",
      "location": "withdraw() line 45",
      "recommendation": "Use checks-effects-interactions pattern"
    }
  ],
  "analyzedAt": "2024-01-20T12:00:00Z"
}

URL Safety

Check URL

Analyze a URL for phishing and malware.
const result = await client.url.check('https://suspicious-site.com');

if (result.isPhishing) {
  console.error('Phishing site detected!');
}

console.log(result.riskScore);
console.log(result.categories);

Wallets

Get Approvals

List token approvals for a wallet.
const result = await client.wallets.getApprovals(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

for (const approval of result.approvals) {
  console.log(`${approval.token} approved to ${approval.spender}`);
  console.log(`Amount: ${approval.amount}`);
}

Get Transactions

Get risk-scored transaction history for a wallet.
const result = await client.wallets.getTransactions(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(`Risk score: ${result.overallRisk}`);
console.log(`Issues found: ${result.count}`);

for (const issue of result.issues) {
  console.log(`[${issue.severity}] ${issue.tag}: ${issue.description}`);
}
Response:
{
  "count": 2,
  "overallRisk": 45,
  "issues": [
    {
      "tag": "Risky Interaction",
      "severity": "medium",
      "description": "Interacted with flagged address"
    }
  ]
}

Account Trace

Trace Fund Flows

Trace multi-hop fund flows for compliance and forensics.
const result = await client.accountTrace.trace(
  '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
  { chain: Chain.ETH }
);

console.log(`Total connections: ${result.summary.totalConnections}`);
console.log(`High-risk: ${result.summary.highRiskConnections}`);

for (const conn of result.connections) {
  console.log(`${conn.address}: ${conn.relationship} - ${conn.riskFlags.join(', ')}`);
}
Response:
{
  "summary": {
    "totalConnections": 15,
    "highRiskConnections": 3
  },
  "connections": [
    {
      "address": "0xabc...",
      "relationship": "direct_transfer",
      "riskFlags": ["mixer_user", "high_risk"],
      "depth": 1
    }
  ]
}

Usage

Get API Usage

Monitor your API usage and quotas.
const usage = await client.usage.get();

console.log(`Requests used: ${usage.requestsUsed}`);
console.log(`Requests remaining: ${usage.requestsRemaining}`);
console.log(`Reset date: ${usage.resetDate}`);

Get Max RPS

Get maximum requests per second for an organization over a time period.
const maxRps = await client.usage.getMaxRps({
  organization: 'my-org',
  from: Date.now() - 86400000, // 24 hours ago
  to: Date.now(),
});

console.log(`Max RPS: ${maxRps}`);
Options:
OptionTypeRequiredDescription
organizationstringYesOrganization identifier
fromnumberYesStart time as Unix timestamp in milliseconds (e.g., Date.now() - 86400000)
tonumberYesEnd time as Unix timestamp in milliseconds (e.g., Date.now())

Transactions

Analyze Transaction

Get risk analysis for a blockchain transaction.
const result = await client.transactions.analyze(
  '0xTransactionHash...',
  { chain: Chain.ETH }
);

console.log(`Risk score: ${result.riskScore}`);
console.log(`Risk level: ${result.riskLevel}`);

for (const tag of result.riskTags ?? []) {
  console.log(`Risk: ${tag.tag} - ${tag.description}`);
}
Supported chains: ETH, BASE, BSC, POL, OPT, ARB, SOL, STELLAR Options:
OptionTypeDescription
chainChainBlockchain to analyze
hideTrustFlagsbooleanHide trust flags in response

Scan

Scan Transaction

Scan a raw transaction for risks before signing.
const result = await client.scan.scanTransaction(
  '0xSignerAddress...',
  {
    tx: {
      from: '0xSignerAddress...',
      raw: '0xRawTransactionData...',
    },
    chain: 1, // Chain ID (1 = Ethereum)
    domain: 'app.example.com',  // Optional: dApp domain
  }
);

console.log(`Risk level: ${result.riskLevel}`);  // low, medium, high
console.log(`Warnings: ${result.warnings.length}`);

// Check asset changes
for (const change of result.assetChanges ?? []) {
  console.log(`${change.type}: ${change.amount} ${change.symbol}`);
}
Supported chain IDs: 1 (ETH), 56 (BSC), 137 (POL), 10 (OPT), 42161 (ARB), 8453 (BASE)

Scan EIP-712 Message

Scan an EIP-712 typed data message before signing.
const result = await client.scan.scanEip712(
  '0xSignerAddress...',
  {
    msg: {
      from: '0xSignerAddress...',
      data: {
        types: {
          EIP712Domain: [
            { name: 'name', type: 'string' },
            { name: 'version', type: 'string' },
            { name: 'chainId', type: 'uint256' },
          ],
          Permit: [
            { name: 'owner', type: 'address' },
            { name: 'spender', type: 'address' },
            { name: 'value', type: 'uint256' },
          ],
        },
        primaryType: 'Permit',
        domain: {
          name: 'MyToken',
          version: '1',
          chainId: 1,
        },
        message: {
          owner: '0x...',
          spender: '0x...',
          value: '1000000000000000000',
        },
      },
    },
    domain: 'app.example.com',
  }
);

console.log(`Risk level: ${result.riskLevel}`);
console.log(`Message type: ${result.messageType}`);

Full Example

import { ThreatClient, Chain, ValidationError, RateLimitError } from '@webacy-xyz/sdk';

const client = new ThreatClient({
  apiKey: process.env.WEBACY_API_KEY,
  defaultChain: Chain.ETH,
});

async function analyzeWallet(address: string) {
  try {
    // Get overall risk
    const risk = await client.addresses.analyze(address);

    if (risk.overallRisk > 70) {
      console.warn(`High risk wallet: ${risk.overallRisk}`);

      // Check sanctions
      const sanctions = await client.addresses.checkSanctioned(address);
      if (sanctions.is_sanctioned) {
        throw new Error('Sanctioned address - cannot proceed');
      }

      // Check for address poisoning
      const poisoning = await client.addresses.checkPoisoning(address);
      if (poisoning.is_poisoned) {
        console.warn('Address may be a poisoning attempt');
      }
    }

    return { safe: risk.overallRisk < 50, risk };

  } catch (error) {
    if (error instanceof ValidationError) {
      console.error('Invalid address:', error.message);
    } else if (error instanceof RateLimitError) {
      console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
    }
    throw error;
  }
}

Next Steps