Repository navigation
feat(backend): SEP-0009 compliance & OFAC sanctions screening middleware (#1470) - #1570
Merged
K1NGD4VID merged 7 commits intoOct 8, 2026
Merged
Conversation
Aj-Kayvee
force-pushed
the
feat/sep0009-compliance-screening-1470
branch
from
September 28, 2026 14:40
3ed4934 to
62b404f
Compare
3 tasks done
Merging main into this branch unioned both sides of every conflicting file instead of combining them, so the tree did not build: `lib.rs` had an unclosed `match`, `errors.rs`/`test.rs` declared duplicate variants and fields, `sorobanService.ts` and `stream-simulation.test.ts` each contained two copies of a function, `indexerService.ts`/`pg-pool.ts`/`health.routes.ts` duplicated declarations, and several frontend files mixed both revisions (duplicate JSX props, hooks and imports). The Docker and preview jobs also failed on `EOVERRIDE` because the backend override pinned `@types/pg@8.23.1` while main had added it as a direct `8.20.0` devDependency. Take main's revision where it supersedes the branch's reconciliation (sorobanService, pg-pool, health routes, and the matching test suites), keep the branch's intentional fixes (actual-toast helper, useSyncExternalStore network provider, `nativeToScVal` vec element type, webhook fetch cancellation), and align the `@types/pg` override with the direct dependency so the standalone container install resolves a single copy again. cargo fmt/clippy/test, the wasm release build, backend build + vitest + OpenAPI drift, and frontend lint/tsc/vitest are all green. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com> # Conflicts: # contracts/stream_contract/src/errors.rs # contracts/stream_contract/src/lib.rs # frontend/src/app/streams/[id]/__tests__/stream-details-content.test.tsx
… 70% The merge dropped `mod acceptance_tests`, so the seven tests that exercise `batch_create_streams`, `create_stream_with_cliff`, `transfer_recipient` and `extend_stream_ttl` stopped running and contract coverage fell to 67.85%, below the 70% tarpaulin gate. The crate compiles and the whole 230-test suite passes with the module restored, so re-declare it. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
The `ec79991f` merge unioned both sides of the contract crate again: `test.rs` kept a duplicate fee test whose body lost its closing brace, `errors.rs` redeclared variants 28–33, and `events.rs` re-emitted `StreamClosedEvent` at its old position. `cargo fmt` aborted on the unterminated function, so Soroban Contracts CI failed before running a single test. The SEP-0009 feature is backend-only, so restore the contract crate to main's already-green revision. `cargo fmt`/`clippy` and all 230 contract tests pass. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1470
Adds an opt-in compliance / sanctions screening layer to the backend so institutional payroll and regulated token distributions can prove participating wallets were screened before funds move.
What's included
Screening middleware (
backend/src/middleware/compliance.middleware.ts) guards stream creation, top-up (deposit) and withdrawal routes. Sanctioned or over-threshold addresses receive a structured403:{ "error": "COMPLIANCE_RESTRICTION", "message": "Address restricted under compliance policy" }Screening service (
backend/src/services/compliance.service.ts) returns theScreeningResultshape from the issue, supports alocaldenylist/allowlist provider (inline env + optional JSON sanctions feed) and anexternalprovider (Chainalysis / TRM Labs / Elliptic style HTTPS API) with an abort-based timeout, and caches results with a configurable TTL.Config (
backend/src/config/compliance.config.ts) —COMPLIANCE_ENFORCEMENT_ENABLED(default false, so local testing and self-hosted deployments stay permissive), risk threshold, fail-open / fail-closed mode, cache TTL and provider settings. All documented inbackend/.env.example.Audit trail — new
ComplianceAuditLogPrisma model records every blocked interaction (address, request IP, risk score, tags, action) plus a structuredlogger.infoline. KYC submissions are audited too.SEP-0009 KYC —
POST /v1/compliance/kyc-attestationaccepts a SEP-0009 identity payload plus a cryptographic proof and stores it as aKycAttestation.POST /v1/compliance/screenandGET /v1/compliance/screen/{address}expose screening results for audit tooling.Migration
20260928000000_add_compliance_tables, plus regenerated OpenAPI spec and frontend API types.Tests —
backend/tests/compliance.test.ts(31 tests) covers config parsing, allowlist/blocklist behaviour, the risk-threshold boundary, cache hits, external-provider success/failure, fail-open vs fail-closed, audit persistence and the SEP-0009 route.Acceptance criteria
Base branch note
upstream/maincurrently does not build:backend/prisma/schema.prismadefinesIndexerDeadLetterEventtwice (failsprisma validate/generate) and there are pre-existing type errors acrosssorobanService,health.routes,indexerServiceandadmin.routes. Because of that, this branch is stacked onfeat/ledger-reorg-fork-recovery-1468, which carries the repair commits needed to make the tree green. The compliance changes themselves are self-contained (see the file list below) and can be rebased cleanly oncemainis repaired.Files changed
backend/src/config/compliance.config.ts(new)backend/src/services/compliance.service.ts(new)backend/src/middleware/compliance.middleware.ts(new)backend/src/routes/v1/compliance.routes.ts(new)backend/tests/compliance.test.ts(new)backend/prisma/schema.prisma,backend/prisma/migrations/20260928000000_add_compliance_tables/backend/src/routes/v1/index.ts,backend/src/routes/v1/stream.routes.tsbackend/src/config/swagger.ts,backend/swagger/flowfi.openapi.json,frontend/src/lib/api-types.generated.tsbackend/.env.exampleVerification
npx prisma generate— passnpx tsc --noEmit(backend) — passnpx vitest run --exclude='tests/integration/**'— 490 passed / 3 skippedtests/compliance.test.ts— 31 passed