Wallet Drain Detection: Address Webhooks for Custody Teams

Wallet Drain Detection: Address Webhooks for Custody Teams

Crypto APIs Team

Oct 16, 2026 • 5 min

A tampered hardware signer can authorize outflows without any software compromise, so the only place the theft becomes visible is on-chain. Custody teams can subscribe every derived address to confirmed and unconfirmed transaction webhooks, alert on any outflow their own systems did not initiate, and screen the destination with an AML (anti-money laundering) check within seconds. This post shows how to wire that detector with Crypto APIs and where it can fail.

Cointelegraph reported on hardware wallet tampering, with losses cited at up to $93 million across more than 300 wallets. The detail that matters for engineers is where the compromise sat. It was at the key layer. Endpoint protection, API gateway logs and access controls see nothing when a signer itself has been altered. The transactions are validly signed. They look like any other withdrawal until you compare them with what your platform actually requested.

We monitor the chain. We make no claims about the security of any device, and nothing here is a statement about a specific vendor. The point is narrower: when the signer cannot be trusted, the chain is the only independent witness.

The problem

Picture the platform engineer at a custody provider or exchange who owns withdrawal operations. Their system issues withdrawals through a signing service, and every legitimate outflow has a matching internal record: a withdrawal ID, an approver, an intended destination. A compromised signer breaks that link. Funds leave a derived address with no internal record behind them.

The build problem is reconciliation in near real time. For every address the platform controls, the team needs to know the moment value leaves it, decide whether that outflow was expected, and if not, learn where the funds went. This is distinct from the admin-key scenario covered in Vault Outflow Alerts: Webhooks After Admin Key Changes. There is no privileged contract change to anchor on here. The only signal is the outflow itself.

What you need

  • The extended public keys (xPubs) for each hierarchical deterministic (HD) wallet you operate, per chain. Public keys only. Private material never touches the monitoring stack.
  • A complete list of derived addresses, including change addresses on UTXO (unspent transaction output) chains such as Bitcoin. Gaps in this list are blind spots.
  • An internal ledger of initiated withdrawals that your detector can query by transaction hash or by destination and amount.
  • A public HTTPS endpoint to receive webhook callbacks, with idempotent handling.
  • A Crypto APIs key, sent in the X-API-Key header.

The hard part is not the API calls. It is keeping the address set complete as new addresses are derived, and keeping the withdrawal ledger fast enough to answer a lookup in the time it takes a webhook to arrive.

How it works

Step 1: Build the address set. Register each xPub through HD Wallets Management using POST /hd-wallets/{blockchain}/{network}/{extendedPublicKey}/addresses/derive-and-sync, or derive addresses without syncing via GET /utils/{blockchain}/{network}/xpubs/{extendedPublicKey}/derive-addresses. Pull the synced list from GET /hd-wallets/{blockchain}/{network}/{extendedPublicKey}/addresses and treat it as the source of truth for what you watch.

Step 2: Subscribe every address. For each address, create subscriptions with Blockchain Events. Use address-coins-transactions-unconfirmed for the earliest warning, since a mempool alert can arrive before the drain confirms. Add address-coins-transactions-confirmed for the authoritative record, and address-tokens-transactions-confirmed on EVM (Ethereum Virtual Machine) chains so ERC-20 stablecoin outflows are not missed. Each subscription returns a referenceId you store against the address. Callbacks are delivered in under 100ms from detection. The full subscription walkthrough is in our guide to monitor addresses with webhooks.

Step 3: Classify the event. These subscriptions fire on both incoming and outgoing activity. Your handler determines direction by checking whether the monitored address is the sender. Incoming deposits route to your normal crediting flow. Outgoing transactions are checked against the withdrawal ledger by transaction hash. A match closes the loop. No match is an unexpected outflow and triggers the next step immediately.

Step 4: Screen the destination. Call Verify Address on the receiving address. It is a GET with the address in the path and no request body.

GET https://rest.cryptoapis.io/aml/addresses/{address}
X-API-Key: <your key>

A flagged destination returns the risk band, categories and attribution:

{"apiVersion":"2024-12-12","requestId":"6aa3c4642f6f68835e3dbd6c","data":{"item":{
  "blockchain":"ethereum","isFlagged":true,"riskScore":80,"riskBand":"high",
  "severity":"high","categories":["malicious","sanctions"],
  "sources":[{"provider":"graphsense","label":"tornado.cash","categories":["malicious"],
              "severity":"high","listingTimestamp":1784210009,"sanctionPrograms":[]}],
  "attribution":{"entity":"tornado-cash","type":"mixer","label":"Tornado.Cash: Donate"},
  "listingTimestamp":1784210009}}}

A clean result omits optional fields entirely:

{"apiVersion":"2024-12-12","requestId":"6aa3c48d2f6f68835e3dbf05","data":{"item":{
  "isFlagged":false,"riskScore":0,"riskBand":"low","severity":"none",
  "categories":[],"sources":[]}}}

Once the transaction has a hash, you can also screen all counterparties at once:

GET https://rest.cryptoapis.io/aml/transactions/{blockchain}/{transactionHash}

{"apiVersion":"2024-12-12","requestId":"6aa3c4a32f6f68835e3dc003","data":{"item":{
  "isFlagged":false,"riskScore":0,"riskBand":"low","flaggedAddresses":[]}}}

Step 5: Escalate. Any unmatched outflow pages the on-call engineer. A destination with riskBand of high or severe, or a categories array containing mixer-type attribution or sanctions, raises severity and should trigger a freeze on further signing from that HD wallet. The alert carries the address, amount, destination and the AML result, so responders start with context rather than a raw hash.

What to watch for

  • Coverage gaps. An address that was derived but never subscribed is invisible. Reconcile subscriptions against the HD wallet address list on a schedule, and subscribe new addresses in the same code path that derives them.
  • Change outputs on UTXO chains. A legitimate Bitcoin withdrawal spends inputs and returns change to another of your addresses. Treat outputs to your own address set as internal, or every withdrawal will look like a partial drain.
  • Unconfirmed events are not final. Mempool transactions can be replaced or dropped. Use them to page early, and use confirmed events to close or reopen the incident.
  • Token outflows. On EVM chains, a drain of stablecoins leaves the native balance untouched. Without token subscriptions, the detector stays quiet.
  • Duplicate and out-of-order delivery. Make handlers idempotent on transaction hash. Return a 2xx response quickly and do ledger and AML work asynchronously.
  • Subscription health. List active subscriptions with GET /blockchain-events/{blockchain}/{network} and reactivate any that have been deactivated with POST /blockchain-events/{blockchain}/{network}/{referenceId}/activate.
  • Detection is not prevention. A confirmed drain cannot be reversed on-chain. The value of fast detection is stopping further signing, notifying counterparties and exchanges, and starting tracing while funds are still close to the source.

If your signer is compromised, your software logs will look normal. The chain will not. Custody providers can build this detector today on Blockchain Events, HD Wallets Management and Verify Address across 20+ chains, with sub-100ms webhook delivery. The free tier requires no credit card, so you can subscribe a test wallet and fire your first outflow alert this afternoon.

Infrastructure optimized for growth

35+

Networks Supported

25ms

Avg Processing Time

25,000+ rq/s

Enterprise-ready

100+ TB

of Big Data

Related articles

Share