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>
223 lines
9.4 KiB
Markdown
223 lines
9.4 KiB
Markdown
# 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:** ~40–80 (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:** ~20–40 (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 (~5–15), 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.05–0.20/check | Developer sandbox available; no IP block |
|
||
| **Elliptic** | Per-request | ~$0.10–0.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:** 1–5 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
|
||
|
||
---
|
||
|
||
## Recommended Free Tier Additions
|
||
|
||
### 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 → ~140–160 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)
|
||
|
||
```typescript
|
||
// 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):
|
||
|
||
```bash
|
||
# 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.
|