
BSA Gate
A gate that checks who may pay and whether it's safe before USDC settles over x402.
Demo
About
BSA Gate is a compliance and safety checkpoint that runs before a stablecoin payment settles. Today USDC moves blind: there is no check on who is paying, and no check on whether the counterparty is dangerous. BSA Gate inserts one gate in front of settlement and answers two questions. Who may pay. The payer holds an ENSv2 name that carries KYC attestations such as over 18 and jurisdiction. We issue these as an attestation authority: the user owns their name, but only our issuer can write the attestation keys, so the claims cannot be forged and are portable, issued once and trusted by any merchant. Real identity comes from an EU digital identity wallet (EUDI): the user presents their ID credential, and we derive the attestations from the verified birthdate and nationality without putting either on-chain. Whether it is safe. Before any money moves, the payer and payee are screened with Intercepta for sanctions, scams and mixer exposure. A risky counterparty is blocked with a clear reason, and the screen fails closed. Only if both checks pass does the payment settle in USDC over x402, gasless for the payer. The same gate protects a WooCommerce store, a Shopify store, and an autonomous AI agent paying another service, so a human shopper and an agent follow the exact same rules. An agent pays under a revocable, non-transferable delegation and a per-payment spend cap that only its principal can change, using a wallet that is its own and not the principal's. Remove ENSv2 and the product stops working: issuance, attestations, delegation, per-key write scoping and revocation all live in ENSv2.
How it's made
The gate is a TypeScript facilitator (viem, Express). One pipeline runs five ordered steps: verify the EIP-3009 authorization, enforce the agent spend cap, check ENS permission and attestations, screen with Intercepta, then settle. It fails at the first check with a precise reason and moves no money on a block. Identity and permissions (ENSv2 on Sepolia, sepolia-fix). We deploy a PermissionedRegistry for bsagate.eth and a shared resolver through VerifiableFactory, with our issuer as admin. After KYC, each principal gets their own UserRegistry and a name registered with RENEW only: no resolver swap, no sub-minting, no transfer. Attestations (over18, jurisdiction) are resolver text records only the issuer can write, so the name owner cannot forge them. That split between name owner and record writer is the core idea. We also use per-key roles (authorizeTextRoles) so an attester can be scoped to a single record key. A principal delegates a non-transferable, revocable agent (agent.alice.bsagate.eth, roleBitmap 0) that inherits the principal's attestations by living under their name, and the principal keeps ROLE_UNREGISTER as an on-chain kill switch. The gate walks the registries (getState, getSubregistry) instead of trusting a resolver, so an unregistered name serving a default record never passes. KYC from a real EU wallet (EUDI, OpenID4VP). The user scans a QR with an EU identity wallet (tested with Procivis One), presents their PID, and the public EUDI reference verifier validates it cryptographically. We decode the SD-JWT, derive over 18 from birthdate and jurisdiction from nationality, and write only those derived attestations to ENS. A self-issue demo path is kept for judges who do not have a wallet. Payments (x402, EIP-3009). The payer signs a gasless transferWithAuthorization on Circle USDC off-chain; the facilitator submits it, so the payer never pays gas. An autonomous agent client probes an x402 resource, gets 402 with the terms, signs with its own key, and retries with the X-PAYMENT header, all without a human in the loop. Spend cap. A per-agent, per-payment ceiling enforced by the facilitator. The principal signs each cap change with an EIP-712 message, so a delegated agent can pay on its own but can never raise its own limit. Safety (Intercepta). Before settling, the gate calls the Intercepta Web3 Antivirus quick-scan on both payer and payee. Sanctioned, scam, blacklisted or high-toxicity addresses are blocked. The risk data is mainnet, so we screen mainnet addresses even on a testnet build. Surfaces. A WooCommerce plugin (a PHP payment gateway with a REST settle route and a wallet order-pay flow, plus per-product required attestations), a Shopify pay service (a hosted pay page with Admin API write-back and a per-product metafield, not an installable app), an autonomous agent-to-agent x402 client, and a Next.js web app: get-verified (EU wallet plus a self-issue fallback, side by side), checkout, an agent console to delegate and spend-cap an agent, and a live activity feed of settled and blocked payments with reasons. Engineering and delivery. 36 automated tests written test-first with vitest, run against a free local Anvil fork during development. Deployed live: the facilitator on Railway (Docker, with a persistent volume) in live mode against real Sepolia and the real Intercepta API, and the web app on Vercel; both public and wired to the same gate. We proved real USDC settlements on Sepolia across the agent, Shopify and WooCommerce surfaces, and every refusal live: not 18, wrong jurisdiction, over the spend cap, and a real sanctioned payee (Intercepta toxicScore 100).