@rhinestone/sanctions
v2.0.0
Published
Self-hosted sanctioned-address screening (OFAC SDN, UK OFSI, Japan MoF). is-sanctioned utilities for EVM / Solana / Tron.
Readme
@rhinestone/sanctions
Fast, self-hosted sanctioned-address screening. Bundles a sanitized list of
sanctioned crypto addresses (compiled from official government sources by the
pipeline in this repo) and exports zero-latency isSanctioned utilities.
Matching is a bundled in-memory Set lookup — no network calls, no API keys.
Install
pnpm add @rhinestone/sanctionsZero runtime dependencies. The exported Address type is 0x${string} (the
same shape as viem's Address, so viem values are assignable) — no viem install
required.
Usage
import {
isSanctioned,
isSanctionedEvmAddress,
isSanctionedSolanaAddress,
isSanctionedTronAddress,
assertNotSanctioned,
SanctionedAddressError,
sanctionsMeta,
} from "@rhinestone/sanctions";
// Auto-detects the chain from the address shape:
isSanctioned("0x098B716B8Aaf21512996dC57EB0615e2383E2f96"); // true
// Throw on a hit — catch it at the API boundary and map to a 403:
try {
assertNotSanctioned(recipient);
} catch (err) {
if (err instanceof SanctionedAddressError) {
// err.address is the offending address
}
}
// Provenance for audit logging:
sanctionsMeta.sources[0].publishDate; // e.g. "2026-07-23"
sanctionsMeta.contentHash; // "sha256:…"API
| Export | Description |
|---|---|
| isSanctioned(address) | True if sanctioned on any supported chain (auto-detect). |
| isSanctionedEvmAddress(address) | EVM check; checksum-insensitive. Accepts viem Address or string. |
| isSanctionedSolanaAddress(address) | Solana check (case-sensitive). |
| isSanctionedTronAddress(address) | Tron check (case-sensitive). |
| assertNotSanctioned(address) | Throws SanctionedAddressError if sanctioned. |
| SanctionedAddressError | Error carrying .address. |
| sanctionsMeta | { generatedAt, counts, sources[], contentHash }. |
| bundleAgeDays() | Age of the bundled list in days (since generatedAt). |
| assertFresh(maxDays) | Throws StaleSanctionsListError if the list is older than maxDays, or if its timestamp is unparseable or in the future. |
| StaleSanctionsListError | Error carrying .ageDays and .maxDays. |
All lookups trim / NFC-normalize input and return false on malformed or
non-string input (never throw). The package throws at import if the bundled
list is empty or malformed (fails closed).
Coverage
EVM, Solana, and Tron addresses from US OFAC SDN, UK OFSI, and Japan
MoF (the lists overlap heavily on DPRK designations). EVM addresses are stored
lowercased and matched checksum-insensitively; Solana/Tron are base58 and matched
verbatim. sanctionsMeta.sources lists exactly which snapshots are bundled.
Data freshness
The list is baked into the package at publish time. Update cadence is driven by
the pipeline / CI in the repo root — pin a range like ^2.0.0 to pick up data
updates. sanctionsMeta tells you exactly which snapshot you're running.
License
AGPL-3.0-only — see LICENSE. If you run a modified version of this package
as part of a network service, the AGPL obliges you to offer that service's
Corresponding Source to its users. If that is incompatible with your project,
do not use this package.
Because the upstream repository is private, this package's own Corresponding
Source ships inside the npm tarball: see src/ alongside dist/.
The bundled address data is not covered by the AGPL. It is compiled from
official government publications and retains their terms — US OFAC (public
domain), UK OFSI (Open Government Licence v3.0, attribution required), Japan MoF
(政府標準利用規約, CC BY 4.0-compatible). Full attribution is in NOTICE, which
ships with the package.
This project does not accept outside contributions.
