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