Files
nick-doc/PRD - AML Screening Provider Options.md
Siavash Sameni dceaf82934 audit: 2026-05-30 full-codebase audit — report, issues, docs, runbooks
Full-codebase-audit 2026-05-30 outputs:
- Audit report: 09 - Audits/Full Codebase Audit - 2026-05-30.md
- 81 issue files ISSUE-055..135 (decisions + 1 skipped no-brainer).
- Scanner docs from scratch (was zero): architecture, data model, API ref, payment
  flow, operations runbook + repo README.
- Doc-sync updates across API reference, data models, flows, design system.
- Secret Rotation Runbook (08 - Operations) for the exposed credentials.
- Reusable workflow guide (07 - Development) + .claude/workflows/full-codebase-audit.js.

Issues remain status:open intentionally — the code fixes are uncommitted-then-committed
working-tree changes per repo and aren't "resolved" until merged/deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 18:48:04 +04:00

9.4 KiB
Raw Permalink Blame History

PRD — AML Screening Provider Options

Status: Draft
Date: 2026-05-29
Context: Task #10 added ofacProvider as the first working free AML provider. The Chainalysis free public API was ruled out (Cloudflare blocks all non-browser IPs). This document maps all options and recommends what to add next at zero cost.


Current State

What Status
OFAC SDN provider Live (ofacProvider.ts)
amlScreeningService.ts Live — pluggable provider interface
amlConfigRoutes.ts Admin can switch provider + force-refresh
Chainalysis KYT (paid) Code ready, key required
Chainalysis free public API Blocked by Cloudflare on all server IPs

TRANSACTION_SAFETY_AML_PROVIDER=ofac covers the US regulatory minimum: 97 sanctioned EVM addresses (Tornado Cash, Lazarus Group, sanctioned exchanges).


The Gap

OFAC alone is narrow. A buyer could be:

  • On the EU, UN, or UK sanctions lists but not OFAC
  • Flagged by on-chain intelligence (stolen funds, mixer outputs, exploit proceeds) without being formally sanctioned anywhere
  • A known scammer address catalogued by community databases

For a marketplace doing cross-border escrow, the OFAC gap is meaningful and several free alternatives exist.


Option Map

Tier 1 — Free, Self-Hosted (Same Pattern as OFAC)

These are official government-issued sanctions lists available as bulk XML/CSV downloads with no API key and no IP restrictions. Identical implementation pattern to ofacProvider.ts.

1A. EU Consolidated Sanctions List

  • Source: European External Action Service (EEAS)
  • URL: https://webgate.ec.europa.eu/fsd/fsf/public/files/xmlFullSanctionsList_1_1/content
  • Format: XML, updated daily
  • EVM addresses: ~4080 (growing; includes Hydra Market operators, Garantex exchange)
  • Effort: ~2h — copy ofacProvider, change regex to match EU XML schema
  • Overlap with OFAC: ~60% (most major entities are dual-listed)
  • Why add it: EU operators have a compliance obligation to the EU list independently of OFAC

1B. UK OFSI Consolidated List

  • Source: UK Office of Financial Sanctions Implementation
  • URL: https://ofsistorage.blob.core.windows.net/publishlive/2022format/ConList.xml
  • Format: XML, updated daily
  • EVM addresses: ~2040 (post-Brexit separate list; includes Garantex, some Tornado Cash)
  • Effort: ~2h — same pattern
  • Why add it: required for any UK-person counterparty

1C. UN Security Council Consolidated List

  • Source: UN Security Council
  • URL: https://scsanctions.un.org/resources/xml/en/consolidated.xml
  • Format: XML, updated ~weekly
  • EVM addresses: low (~515), but includes DPRK entities (Lazarus Group basis)
  • Effort: ~2h
  • Why add it: many jurisdictions require UN list compliance as the baseline floor

Tier 2 — Free API Tier (Rate-Limited, No IP Block)

These providers offer a free developer/community plan with meaningful rate limits.

2A. GoPlus Security API

  • Endpoint: https://api.gopluslabs.io/api/v1/address_security/{address}?chain_id={chainId}
  • Auth: None for basic tier (1000 req/day free); API key for higher volume
  • Returns: { malicious_address, phishing_activities, blackmail_activities, stealing_attack, fake_token, honeypot_related_address, ... } — 15+ risk categories
  • Coverage: On-chain intelligence across BSC, ETH, Polygon, Arbitrum, Base — exactly our 5 chains
  • IP restrictions: None — tested from SepehrHomeserverdk (community-maintained list served normally)
  • Latency: ~150ms average
  • Effort: ~3h (new provider class + admin toggle)
  • Why add it: Catches non-sanctioned but known-bad addresses (drainers, phishing deployers, stolen-fund mixers) that no government list covers
  • Limitation: Community-sourced, not legally authoritative; use as advisory block, not hard block

2B. Etherscan Address Tags (ETH only)

  • Endpoint: https://api.etherscan.io/api?module=account&action=txlist&address=... + label check
  • Auth: Free API key (no credit card, 5 req/s)
  • Returns: Known scammer/phisher labels from Etherscan's community tag system
  • Coverage: Ethereum mainnet only
  • Effort: ~4h (needs scrape of label endpoint, which is unofficial)
  • Why skip for now: Unofficial, ETH-only, limited EVM address coverage. GoPlus is strictly better.

Tier 3 — Paid / Enterprise

Provider Model Est. Cost Notes
Chainalysis KYT Per-request + annual $10k+/yr Gold standard; blocked on free tier
TRM Labs Per-request ~$0.050.20/check Developer sandbox available; no IP block
Elliptic Per-request ~$0.100.50/check Strong EU coverage
Sardine Per-request Custom Adds fraud scoring beyond AML
AMLBot Per-request ~$0.10/check Telegram-native AML bot; has API
Scorechain Annual SaaS ~$5k+/yr Good EU/CIS coverage

TRM Labs is the strongest paid option after Chainalysis — has a developer sandbox, no Cloudflare blocking, and competitive pricing. If a paid provider is chosen later, TRM is the recommended starting point.


Tier 4 — On-Chain / Decentralized

4A. Forta Network

  • Decentralized threat detection; bots emit alerts for known exploiter addresses
  • Free: Yes, public alert feed via GraphQL
  • Latency: 15 minutes (block-based, not real-time per request)
  • Fit: Better for monitoring than pre-payment screening; not recommended for this use case

4B. Harpie Address Blocklist

  • Blocklist maintained by Harpie (web3 security); some public exposure
  • Coverage: Mostly phishing and drainer addresses on ETH
  • API: Not public/stable
  • Verdict: Skip — GoPlus covers the same space with a proper API

Phase A — Sanctions breadth (1 day of work)

Add EU + UN list providers, run all three (OFAC + EU + UN) in parallel, merge results:

OFAC SDN     → 97 EVM addresses
EU List      → ~60 EVM addresses  
UN SC List   → ~15 EVM addresses
─────────────────────────────────
Total unique → ~140160 addresses (after dedup)

Implementation: add euSanctionsProvider.ts and unSanctionsProvider.ts following the exact same pattern as ofacProvider.ts. Add a combinedSanctionsProvider.ts that fans out to all three in parallel and merges results. Admin can enable combined as the provider.

Phase B — On-chain intelligence (½ day of work)

Add goplusProvider.ts:

  • Checks GoPlus free API for the 15 risk categories
  • Returns clean: false for malicious_address, phishing_activities, stealing_attack, blackmail_activities
  • Returns clean: true with a warning note for lower-severity flags
  • Admin configurable: advisory (warn but allow) vs blocking mode

Composite provider (final step)

A compositeProvider.ts that runs sanctions lists + GoPlus in parallel:

  • Any sanctions hit → hard block
  • GoPlus malicious hit → configurable (default: hard block)
  • GoPlus advisory flag → pass with risk note in payment record

Provider Interface (no changes needed)

// Already in amlProvider.ts — all new providers just implement this
export interface AmlProvider {
  name: string;
  screenAddress(address: string, chainId?: number): Promise<AmlScreenResult>;
}

export interface AmlScreenResult {
  clean: boolean;
  verdict: 'clean' | 'sanctions' | 'high-risk' | 'unknown';
  categories?: string[];
  raw?: any;
  error?: string;
  providerUnavailable?: boolean;
  provider: string;
}

Admin Config Changes

New env vars (none required, all optional):

# Provider options (expanded):
#   'none'     — disabled
#   'ofac'     — OFAC SDN only (current)
#   'combined' — OFAC + EU + UN (Phase A)
#   'goplus'   — GoPlus on-chain intelligence only
#   'full'     — combined + goplus (Phase A + B)
#   'chainalysis' — paid KYT API
TRANSACTION_SAFETY_AML_PROVIDER=ofac

# GoPlus (Phase B)
GOPLUS_API_KEY=          # optional; upgrades from 1k/day free to higher limit
GOPLUS_BLOCK_THRESHOLD=malicious  # or: advisory (warns but allows)

# EU / UN list URLs (leave blank for defaults)
EU_SANCTIONS_URL=
UN_SANCTIONS_URL=

Priority Recommendation

Phase Work Benefit Do it?
Phase A: EU + UN sanctions ~1 day Closes EU/UN legal gap Yes — do first
Phase B: GoPlus ~½ day Catches non-sanctioned bad actors Yes — do second
Composite provider ~½ day Single toggle for all Yes — do with Phase B
TRM Labs paid ~1 day Full on-chain risk scoring If/when compliance requires it
Chainalysis KYT ~1 day Gold standard + legal defensibility If enterprise clients demand it

Total estimated effort for Phase A + B + Composite: ~2 days.


Risk Notes

  • GoPlus community data: community-sourced, can have false positives. Recommended to run in advisory mode first, switch to blocking after monitoring.
  • Sanctions list lag: all three government lists are updated daily/weekly; the 24h cache is appropriate.
  • Fail-open policy: all providers fail-open by default (payment proceeds if provider unreachable). Seller's amlBlockOnFailure flag overrides this per-offer.
  • Not legal advice: this document describes technical options. Jurisdiction-specific compliance obligations (EU's AMLD6, UK's MLR 2017, US BSA) should be reviewed with legal counsel.