Skip to main content
In March 2022, the Lazarus Group drained $625M from Ronin Bridge in a single attack. The deposit address was already flagged—but no one checked. Don’t make the same mistake. This guide shows you how to screen every deposit and withdrawal in real-time, across 12 chains, with one API.

Why Wallet Screening Matters

Compliance

Stay ahead of OFAC and AML requirements—sanctions lists update daily

Risk Management

Stop bad actors at the door, not after they’ve moved funds

User Protection

Catch address poisoning before your users lose millions
Why exchanges choose Webacy:
  • One integration, 12 chains — ETH, SOL, BTC, and 9 more. No vendor sprawl.
  • Sub-500ms responses — Screen in real-time without blocking transactions
  • Sanctions + fraud in one call — Compliance and security, unified
  • Address poisoning detection — The threat most providers miss

Prerequisites

Before implementing wallet screening, ensure you have:
  • A Webacy API key (sign up here)
  • Basic familiarity with REST APIs or the Webacy SDK
  • Your application’s deposit/withdrawal flow identified for integration points

Deposit Screening

Every deposit is a potential liability until you verify the source. Screen every incoming deposit address to catch sanctioned entities, mixer activity, and high-risk wallets.

Sanctions Check

The fastest compliance check—verify if an address is on OFAC or other sanctions lists.
curl -X GET "https://api.webacy.com/addresses/sanctioned/0x098B716B8Aaf21512996dC57EB0615e2383E2f96?chain=eth" \
  -H "x-api-key: YOUR_API_KEY"
Try it now: Paste 0x098B716B8Aaf21512996dC57EB0615e2383E2f96 into the sanctions endpoint. This is the actual Lazarus Group wallet from Ronin Bridge—instant hit.

Full Risk Analysis

For addresses that pass sanctions screening, perform a comprehensive risk analysis.
curl -X GET "https://api.webacy.com/addresses/0x722122dF12D4e14e13Ac3b6895a86e84145b6967?chain=eth" \
  -H "x-api-key: YOUR_API_KEY"
Response fields to use:
FieldDescriptionAction
overallRisk0-100 risk scoreSet your threshold (e.g., >50 = review)
issues[]Array of risk tagsCheck for specific threats
labels[]Entity labelsIdentify mixers, exchanges, etc.
Try it now: Test 0x722122dF12D4e14e13Ac3b6895a86e84145b6967—the Tornado Cash Router. You’ll get high risk scores and mixer tags in the response.

Multi-Chain Support

The same endpoints work across all supported chains—just change the chain parameter.
curl "https://api.webacy.com/addresses/{address}?chain=eth" -H "x-api-key: YOUR_KEY"

Withdrawal Protection

Your users trust you to protect their funds—even from their own mistakes. Protect users from sending funds to risky destinations, including address poisoning attacks.

Address Poisoning Detection

Address poisoning is a sophisticated attack where scammers create lookalike addresses to trick users into sending funds to the wrong destination.
Real Case: In May 2024, a victim lost $68 million in WBTC by copying a poisoned address from their transaction history. The legitimate and scam addresses looked nearly identical.
The Attack Pattern—Can You Spot the Difference?
Address
✅ Legitimate0xd9A1b0B1e1aE382DbDc898Ea68012FfcB2853a91
❌ Attacker0xd9A1C3788D81257612E2581A6ea0aDa244853a91
Both start with 0xd9A1. Both end with 53a91. The victim couldn’t tell them apart—and lost $68 million.
curl -X GET "https://api.webacy.com/addresses/0xd9A1C3788D81257612E2581A6ea0aDa244853a91/poisoning?chain=eth" \
  -H "x-api-key: YOUR_API_KEY"
One API call, millions saved: Add this check before every withdrawal. Your users won’t notice the 300ms latency—but they’ll notice when you save them from a $68M mistake.

Withdrawal Destination Check

Screen withdrawal destinations for general risk factors.
async function screenWithdrawal(destination: string, chain: Chain) {
  // 1. Sanctions check (immediate block)
  const sanctions = await client.addresses.checkSanctioned(destination, { chain });
  if (sanctions.is_sanctioned) {
    return { allowed: false, reason: 'Sanctioned address' };
  }

  // 2. Address poisoning check (warn user)
  const poisoning = await client.addresses.checkPoisoning(destination, { chain });
  if (poisoning.is_poisoned) {
    return {
      allowed: false,
      reason: 'Potential address poisoning attack',
      warning: 'Please verify this address carefully'
    };
  }

  // 3. Risk analysis (flag high risk)
  const risk = await client.addresses.analyze(destination, { chain });
  if (risk.overallRisk >= 50) {
    return {
      allowed: true,
      warning: `High risk destination (score: ${risk.overallRisk})`,
      issues: risk.issues
    };
  }

  return { allowed: true };
}

Complete Integration Workflow

Here’s how it all fits together.

Implementation Example

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

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

// Deposit screening
async function screenDeposit(address: string, chain: Chain) {
  // Step 1: Sanctions (must block)
  const sanctions = await client.addresses.checkSanctioned(address, { chain });
  if (sanctions.is_sanctioned) {
    return {
      action: 'BLOCK',
      reason: 'Sanctioned address',
      report: true
    };
  }

  // Step 2: Risk analysis
  const risk = await client.addresses.analyze(address, { chain });

  if (risk.overallRisk >= 80) {
    return {
      action: 'BLOCK',
      reason: 'Extremely high risk',
      riskScore: risk.overallRisk,
      issues: risk.issues
    };
  }

  if (risk.overallRisk >= 50) {
    return {
      action: 'REVIEW',
      reason: 'High risk - manual review required',
      riskScore: risk.overallRisk,
      issues: risk.issues
    };
  }

  return {
    action: 'ACCEPT',
    riskScore: risk.overallRisk
  };
}

// Withdrawal screening
async function screenWithdrawal(destination: string, chain: Chain) {
  // Step 1: Sanctions
  const sanctions = await client.addresses.checkSanctioned(destination, { chain });
  if (sanctions.is_sanctioned) {
    return {
      action: 'BLOCK',
      reason: 'Cannot withdraw to sanctioned address'
    };
  }

  // Step 2: Address poisoning
  const poisoning = await client.addresses.checkPoisoning(destination, { chain });
  if (poisoning.is_poisoned) {
    return {
      action: 'WARN',
      reason: 'Possible address poisoning attack detected',
      requireConfirmation: true,
      message: 'Please verify this is the correct address. It appears similar to addresses that have been used in phishing attacks.'
    };
  }

  // Step 3: Risk analysis
  const risk = await client.addresses.analyze(destination, { chain });
  if (risk.overallRisk >= 50) {
    return {
      action: 'FLAG',
      reason: 'High risk destination',
      riskScore: risk.overallRisk,
      showWarning: true
    };
  }

  return { action: 'PROCEED' };
}

Example Addresses for Testing

Use these addresses to test your integration:

OFAC Sanctioned Addresses

AddressChainAttribution
0x098B716B8Aaf21512996dC57EB0615e2383E2f96ETHLazarus Group (Ronin Bridge heist)
0x566f827a4988d4a3eb9da469d8d3d0b536da196eETHOFAC SDN List
0x55da7813a4314cc896bf0cf61886529b7769be81ETHOFAC SDN List
bc1qy78e6ml7f3p438jqrrlzsewx625y0sr7jsesa7BTCOpenSanctions
115p7UMMngoj1pMvkpHijcRdfJNXj6LrLnBTCWannaCry Ransomware
1295rkVyNfFpqZpXvKGhDqwhP1jZcNNDMVBTCSuex (OFAC)

Known Hackers

AddressChainAttribution
0x3b09A3c9aDD7D0262e6E9724D7e823Cd767a0c74ETHBittensor Hack
0x7a503e3ab9433ebf13afb4f7f1793c25733b3ccaETHGANA Hack
0xd967113224c354600b3151e27aaba53e3034f372ETHWazirX Malware/Spear Phishing
0x889b49ef0bf787c3ddc2950bfc7d1d439320004bETHWoo X Exploiter
0x44f887cfbd667cb2042dd55ab1d8951c94bb0102ETHLoopring Guardian 2FA Exploit
bc1ql9r9a4uxmsdwkenjwx7t5clslsf62gxt8ru7e8BTCTrust Hack

Mixers & Money Laundering

AddressChainType
0x722122dF12D4e14e13Ac3b6895a86e84145b6967ETHTornado Cash Router
0x5614987586c15f4e9b3ebcbec07c477b58f2e59bETHTornado Cash Router (Primary)
0x561376c5c8313bd742083d42e6b8b6d8da701fffETHTornado Cash Pool (100 ETH)

Phishing & Scam Addresses

AddressChainAttribution
0x84672cc56b6dad30cfa5f9751d9ccae6c39e29cdETHAI Protocol User Permit Phishing
0x1aDf5DAc035AE7FEC116e8345e005FB88d542f53ETHPhishing scammer
0xe7d13137923142a0424771e1778865b88752b3c7ETHMailer Lite/WalletConnect Phishing Campaign
0x624Fc3Dc249E37E8BFd3e834C4dF81Ff2dA1D0CaBSCMalicious Permit scammer

Address Poisoning

AddressChainType
0xd9A1C3788D81257612E2581A6ea0aDa244853a91ETHKnown poisoned address ($68M WBTC attack)
0xCF03Aa88AfDA357C837b9DDD38A678E3Ad7Cd5D7ETHPoisoning victim
0x5f90e59d0a03fd2f8c56b8cc896c5b42594eb3a0ETH$50M address poisoning drain
AddressChainAttribution
0x0fa09c3a328792253f8dee7116848723b72a6d2eETHNorth Korean entities (High Risk)
0x6eedf92fb92dd68a270c3205e96dccc527728066ETHNorth Korean entities (High Risk)
0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516ETHNorth Korean entities (High Risk)

Clean Addresses (for comparison)

AddressChainType
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045ETHVitalik’s wallet (low risk)
For a complete list of test addresses, see Example Addresses.

API Quick Reference

EndpointUse CaseResponse Time
GET /addresses/sanctioned/{address}Sanctions screening~100ms
GET /addresses/{address}Full risk analysis~500ms
GET /addresses/{address}/poisoningAddress poisoning check~300ms
Authentication:
Header: x-api-key: YOUR_API_KEY
Base URL: https://api.webacy.com

Ready to Ship?

You’ve seen how it works. Now integrate it:
  1. Get your API key — Takes 2 minutes
  2. Test with the example addresses — Verify your integration
  3. Go live — Start screening deposits today

Next Steps