Why real-time and provable
Two properties make onchain monitoring different from a nightly batch screen:- Sanctions lists change without warning. When OFAC adds an address, you cannot wait for tomorrow’s redeploy. A dynamic table lets you push a new address to a running pipeline and start flagging within seconds.
- Regulators want the “why,” not just the “what.” Compose traces every external call with inputs and outputs. Each freeze, alert, or SAR trigger comes with an auditable record.
How it works
Prerequisites
- The Turbo CLI extension installed and logged in.
- A Postgres database and a Goldsky secret. This database also backs the dynamic-table watchlist, so you can keep it inside your own compliance boundary.
- The stablecoin/TIP-20 contract addresses you settle in. Confirm the Tempo dataset name in the Datasource explorer.
Step 1: Screen transfers against a live watchlist
The watchlist lives in a dynamic table. The pipeline checks both counterparties of every transfer against it withdynamic_table_check().
aml-screening.yaml
Step 2: React to a sanctions update in seconds
This is the capability that batch systems cannot match. When a new address must be watched, insert it into the dynamic table from any Postgres client. No redeploy, no re-sync:Step 3: Monitor issuer-level enforcement
TIP-20’s compliance controls emit their own events. Decode them fromraw_logs to keep a real-time view of every policy change and blocked transfer, the issuer-side counterpart to your own screening.
Decoding happens in two steps (one transform defines decoded, the next filters on it) because the SQL engine can’t reference a column alias in the WHERE of the same query.
policy-events.yaml
TransferPolicyUpdate: the token’s whitelist/blacklist policy (TIP-403) changed.TransferBlocked: a transfer was redirected by receive-policy enforcement.BurnBlocked: tokens were removed from a policy-restricted address.PauseStateUpdate: the token was paused or unpaused.
Step 4: Attest every decision with Compose
A flag is not a decision. Route each hit to a Compose task that verifies against your KYC/sanctions provider and records the outcome. Compose traces the task’s inputs and outputs, which is what makes the decision defensible.src/tasks/screen-transfer.ts
case_management webhook in Step 1, or directly from an onchain event trigger. Every run is traceable step by step in the CLI and UI.
Business outcomes
- Minutes, not days, to enforce a sanctions change: the watchlist updates a running pipeline in seconds.
- Defensible decisions: on-chain attestations and full execution traces answer “how did you decide?” with a record, not a reconstruction.
- Data stays in your boundary: the watchlist and flagged-transfer tables live in your database, easing residency and retention obligations.
- One surveillance layer across chains and tokens: the same pipeline pattern covers TIP-20 on Tempo and standard stablecoins on any supported chain.
Resources
- Build a compliance oracle: end-to-end worked example of this pattern
- Dynamic tables
- Compose task authoring and triggers
- Real-time reconciliation
- Compliance & AML monitoring on goldsky.com