> ## Documentation Index
> Fetch the complete documentation index at: https://docs.webacy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange Wallet Screening

> Implement deposit and withdrawal screening for your exchange with sub-500ms sanctions checks, fraud detection, and address poisoning coverage on 13 chains.

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 13 chains, with one API.

## Why Wallet Screening Matters

<CardGroup cols={3}>
  <Card title="Compliance" icon="gavel">
    Stay ahead of OFAC and AML requirements—sanctions lists update daily
  </Card>

  <Card title="Risk Management" icon="shield-halved">
    Stop bad actors at the door, not after they've moved funds
  </Card>

  <Card title="User Protection" icon="user-shield">
    Catch address poisoning before your users lose millions
  </Card>
</CardGroup>

**Why exchanges choose Webacy:**

* **One integration, 13 chains** — ETH, SOL, BTC, and 10 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](https://developers.webacy.co/billing))
* Basic familiarity with REST APIs or the [Webacy SDK](/sdk/installation)
* 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.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/addresses/sanctioned/0x098B716B8Aaf21512996dC57EB0615e2383E2f96?chain=eth" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  import { ThreatClient, Chain } from '@webacy-xyz/sdk';

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

  const result = await client.addresses.checkSanctioned(
    '0x098B716B8Aaf21512996dC57EB0615e2383E2f96',
    { chain: Chain.ETH }
  );

  if (result.is_sanctioned) {
    console.log('BLOCKED: Sanctioned address');
  }
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.webacy.com/addresses/sanctioned/0x098B716B8Aaf21512996dC57EB0615e2383E2f96",
      params={"chain": "eth"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  data = response.json()
  ```
</CodeGroup>

<Tip>
  **Try it now**: Paste `0x098B716B8Aaf21512996dC57EB0615e2383E2f96` into the sanctions endpoint. This is the actual Lazarus Group wallet from Ronin Bridge—instant hit.
</Tip>

### Full Risk Analysis

For addresses that pass sanctions screening, perform a comprehensive risk analysis.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/addresses/0x722122dF12D4e14e13Ac3b6895a86e84145b6967?chain=eth" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const analysis = await client.addresses.analyze(
    '0x722122dF12D4e14e13Ac3b6895a86e84145b6967',
    { chain: Chain.ETH }
  );

  console.log(`Risk Score: ${analysis.overallRisk}/100`);
  console.log(`Issues: ${analysis.issues.map(i => i.tag).join(', ')}`);
  ```

  ```python Python theme={null}
  response = requests.get(
      "https://api.webacy.com/addresses/0x722122dF12D4e14e13Ac3b6895a86e84145b6967",
      params={"chain": "eth"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  ```
</CodeGroup>

**Response fields to use:**

| Field         | Description        | Action                                  |
| ------------- | ------------------ | --------------------------------------- |
| `overallRisk` | 0-100 risk score   | Set your threshold (e.g., >50 = review) |
| `issues[]`    | Array of risk tags | Check for specific threats              |
| `labels[]`    | Entity labels      | Identify mixers, exchanges, etc.        |

<Tip>
  **Try it now**: Test `0x722122dF12D4e14e13Ac3b6895a86e84145b6967`—the Tornado Cash Router. You'll get high risk scores and mixer tags in the response.
</Tip>

### Multi-Chain Support

The same endpoints work across all supported chains—just change the `chain` parameter.

<CodeGroup>
  ```bash Ethereum theme={null}
  curl "https://api.webacy.com/addresses/{address}?chain=eth" -H "x-api-key: YOUR_KEY"
  ```

  ```bash Solana theme={null}
  curl "https://api.webacy.com/addresses/{address}?chain=sol" -H "x-api-key: YOUR_KEY"
  ```

  ```bash Bitcoin theme={null}
  curl "https://api.webacy.com/addresses/{address}?chain=btc" -H "x-api-key: YOUR_KEY"
  ```

  ```bash Base theme={null}
  curl "https://api.webacy.com/addresses/{address}?chain=base" -H "x-api-key: YOUR_KEY"
  ```
</CodeGroup>

***

## 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.

<Warning>
  **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.
</Warning>

**The Attack Pattern—Can You Spot the Difference?**

|              | Address                                      |
| ------------ | -------------------------------------------- |
| ✅ Legitimate | `0xd9A1b0B1e1aE382DbDc898Ea68012FfcB2853a91` |
| ❌ Attacker   | `0xd9A1C3788D81257612E2581A6ea0aDa244853a91` |

Both start with `0xd9A1`. Both end with `53a91`. The victim couldn't tell them apart—and lost \$68 million.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/addresses/0xd9A1C3788D81257612E2581A6ea0aDa244853a91/poisoning?chain=eth" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const poisoning = await client.addresses.checkPoisoning(
    '0xd9A1C3788D81257612E2581A6ea0aDa244853a91',
    { chain: Chain.ETH }
  );

  if (poisoning.is_poisoned) {
    console.log('WARNING: Address poisoning detected!');
    console.log(`Similar to: ${poisoning.similar_addresses}`);
  }
  ```

  ```python Python theme={null}
  response = requests.get(
      "https://api.webacy.com/addresses/0xd9A1C3788D81257612E2581A6ea0aDa244853a91/poisoning",
      params={"chain": "eth"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  ```
</CodeGroup>

<Tip>
  **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.
</Tip>

### Withdrawal Destination Check

Screen withdrawal destinations for general risk factors.

```typescript theme={null}
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.

### Recommended Deposit Flow

```mermaid theme={null}
flowchart TD
    A[Deposit Received] --> B{Sanctions Check}
    B -->|Sanctioned| C[BLOCK Deposit]
    B -->|Clear| D{Risk Analysis}
    D -->|Score > 80| E["BLOCK + Report"]
    D -->|Score 50-80| F[REVIEW Required]
    D -->|Score < 50| G[ACCEPT Deposit]
```

### Recommended Withdrawal Flow

```mermaid theme={null}
flowchart TD
    A[Withdrawal Request] --> B{Sanctions Check}
    B -->|Sanctioned| C[BLOCK Withdrawal]
    B -->|Clear| D{Poisoning Check}
    D -->|Poisoned| E["WARN User + Require Confirmation"]
    D -->|Clear| F{Risk Analysis}
    F -->|Score >= 50| G["FLAG + Show Warning"]
    F -->|Score < 50| H[Process Withdrawal]
```

### Implementation Example

<Accordion title="Full TypeScript Implementation">
  ```typescript theme={null}
  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' };
  }
  ```
</Accordion>

***

## Example Addresses for Testing

Use these addresses to test your integration:

### OFAC Sanctioned Addresses

| Address                                      | Chain | Attribution                        |
| -------------------------------------------- | ----- | ---------------------------------- |
| `0x098B716B8Aaf21512996dC57EB0615e2383E2f96` | ETH   | Lazarus Group (Ronin Bridge heist) |
| `0x566f827a4988d4a3eb9da469d8d3d0b536da196e` | ETH   | OFAC SDN List                      |
| `0x55da7813a4314cc896bf0cf61886529b7769be81` | ETH   | OFAC SDN List                      |
| `bc1qy78e6ml7f3p438jqrrlzsewx625y0sr7jsesa7` | BTC   | OpenSanctions                      |
| `115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn`         | BTC   | WannaCry Ransomware                |
| `1295rkVyNfFpqZpXvKGhDqwhP1jZcNNDMV`         | BTC   | Suex (OFAC)                        |

### Known Hackers

| Address                                      | Chain | Attribution                   |
| -------------------------------------------- | ----- | ----------------------------- |
| `0x3b09A3c9aDD7D0262e6E9724D7e823Cd767a0c74` | ETH   | Bittensor Hack                |
| `0x7a503e3ab9433ebf13afb4f7f1793c25733b3cca` | ETH   | GANA Hack                     |
| `0xd967113224c354600b3151e27aaba53e3034f372` | ETH   | WazirX Malware/Spear Phishing |
| `0x889b49ef0bf787c3ddc2950bfc7d1d439320004b` | ETH   | Woo X Exploiter               |
| `0x44f887cfbd667cb2042dd55ab1d8951c94bb0102` | ETH   | Loopring Guardian 2FA Exploit |
| `bc1ql9r9a4uxmsdwkenjwx7t5clslsf62gxt8ru7e8` | BTC   | Trust Hack                    |

### Mixers & Money Laundering

| Address                                      | Chain | Type                          |
| -------------------------------------------- | ----- | ----------------------------- |
| `0x722122dF12D4e14e13Ac3b6895a86e84145b6967` | ETH   | Tornado Cash Router           |
| `0x5614987586c15f4e9b3ebcbec07c477b58f2e59b` | ETH   | Tornado Cash Router (Primary) |
| `0x561376c5c8313bd742083d42e6b8b6d8da701fff` | ETH   | Tornado Cash Pool (100 ETH)   |

### Phishing & Scam Addresses

| Address                                      | Chain | Attribution                                 |
| -------------------------------------------- | ----- | ------------------------------------------- |
| `0x84672cc56b6dad30cfa5f9751d9ccae6c39e29cd` | ETH   | AI Protocol User Permit Phishing            |
| `0x1aDf5DAc035AE7FEC116e8345e005FB88d542f53` | ETH   | Phishing scammer                            |
| `0xe7d13137923142a0424771e1778865b88752b3c7` | ETH   | Mailer Lite/WalletConnect Phishing Campaign |
| `0x624Fc3Dc249E37E8BFd3e834C4dF81Ff2dA1D0Ca` | BSC   | Malicious Permit scammer                    |

### Address Poisoning

| Address                                      | Chain | Type                                       |
| -------------------------------------------- | ----- | ------------------------------------------ |
| `0xd9A1C3788D81257612E2581A6ea0aDa244853a91` | ETH   | Known poisoned address (\$68M WBTC attack) |
| `0xCF03Aa88AfDA357C837b9DDD38A678E3Ad7Cd5D7` | ETH   | Poisoning victim                           |
| `0x5f90e59d0a03fd2f8c56b8cc896c5b42594eb3a0` | ETH   | \$50M address poisoning drain              |

### DPRK-Related (North Korea)

| Address                                      | Chain | Attribution                       |
| -------------------------------------------- | ----- | --------------------------------- |
| `0x0fa09c3a328792253f8dee7116848723b72a6d2e` | ETH   | North Korean entities (High Risk) |
| `0x6eedf92fb92dd68a270c3205e96dccc527728066` | ETH   | North Korean entities (High Risk) |
| `0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516` | ETH   | North Korean entities (High Risk) |

### Clean Addresses (for comparison)

| Address                                      | Chain | Type                        |
| -------------------------------------------- | ----- | --------------------------- |
| `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045` | ETH   | Vitalik's wallet (low risk) |

<Info>
  For a complete list of test addresses, see [Example Addresses](./getting-started/quickstart/example-addresses).
</Info>

***

## API Quick Reference

| Endpoint                              | Use Case                | Response Time |
| ------------------------------------- | ----------------------- | ------------- |
| `GET /addresses/sanctioned/{address}` | Sanctions screening     | \~100ms       |
| `GET /addresses/{address}`            | Full risk analysis      | \~500ms       |
| `GET /addresses/{address}/poisoning`  | Address poisoning check | \~300ms       |

**Authentication:**

```text theme={null}
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

<CardGroup cols={2}>
  <Card title="Get Your API Key" icon="key" href="https://developers.webacy.co/billing">
    Start screening in minutes
  </Card>

  <Card title="API Reference" icon="book" href="../api-reference/introduction">
    Every endpoint, every parameter
  </Card>

  <Card title="Install the SDK" icon="download" href="../sdk/installation">
    TypeScript bindings included
  </Card>

  <Card title="Understanding Risk Tags" icon="tags" href="../essentials/risk-tags">
    Know what you're looking at
  </Card>
</CardGroup>
