diff --git a/app/api/compliance/screen/route.ts b/app/api/compliance/screen/route.ts index cb64fcb..ebdc0d7 100644 --- a/app/api/compliance/screen/route.ts +++ b/app/api/compliance/screen/route.ts @@ -81,15 +81,14 @@ export async function POST(req: NextRequest) { } catch (error) { console.error('Compliance screening error:', error); - // Return a graceful error response return NextResponse.json( { success: false, - result: 'PASS', - message: 'Compliance screening temporarily unavailable. Proceeding with caution.', + result: 'FAIL', + message: 'Compliance screening unavailable. Transaction blocked.', error: error instanceof Error ? error.message : 'Unknown error', }, - { status: 500 } + { status: 503 } ); } } diff --git a/app/api/payout/route.ts b/app/api/payout/route.ts index a798e68..c2bbbaf 100644 --- a/app/api/payout/route.ts +++ b/app/api/payout/route.ts @@ -19,6 +19,7 @@ import { NextRequest, NextResponse } from "next/server"; import { createClient } from "@/lib/supabase/server"; import { circleDeveloperSdk } from "@/lib/circle/developer-controlled-wallets-client"; +import { screenAddress, mapComplianceResult } from "@/lib/compliance/utils"; import { signAndSubmitGatewayBurnIntent, executeGatewayMint, @@ -271,6 +272,17 @@ export async function POST(req: NextRequest) { const amountInAtomicUnits = BigInt(convertToSmallestUnit(amount)); const destinationChain: SupportedChain = requestedChain || "arcTestnet"; + // Server-side compliance enforcement — must pass before any funds move + const complianceChain = CHAIN_TO_BLOCKCHAIN[destinationChain]; + const circleComplianceResponse = await screenAddress(recipientAddress, complianceChain); + const complianceResult = mapComplianceResult(circleComplianceResponse); + if (complianceResult !== "PASS") { + return NextResponse.json( + { error: "Transaction blocked by compliance screening", result: complianceResult }, + { status: 403 } + ); + } + // Fetch user's wallets const { data: wallets, error: walletsError } = await supabase .from("wallets")