System Architecture
WizPay is a monorepo containing a NestJS backend, a Next.js frontend, and shared protocol configuration. The testnet bridge is a direct External Wallet CCTP V2 lifecycle: the browser wallet signs approval, burn, and destinationreceiveMessage, while the backend validates receipts, retrieves and validates attestations, and restores the persisted lifecycle without a generic retry workflow.
Component Topology
Component Responsibilities
Frontend (Next.js)
- Composes payment payloads from user input
- Calls backend HTTP endpoints to create tasks
- Polls
GET /tasks/:idfor progress and renders status - Manages wallet sessions (W3S userToken / passkey)
- In PASSKEY mode: signs and broadcasts transactions client-side
- For External Wallet bridge routes: signs exact USDC approval, CCTP V2 burn, and destination
receiveMessagetransactions in the browser
/bridge/intents lifecycle; the backend never signs or submits bridge transactions.
Mobile Shell
The frontend adapts to mobile viewports through a dedicated shell layer:- Bottom Navigation — 4-tab fixed bar (Home, Swap, Liquidity, Profile). Visible on mobile; hidden at the
mdbreakpoint and above. Desktop navigation is rendered separately in the sidebar. - Mobile Faucet Card — A compact card on the home screen (mobile-only) that displays the user’s wallet address with a one-tap copy action and a direct link to the testnet faucet. Hidden on desktop.
- Profile / Account Center — A dedicated
/profileroute (ProfileHubPage) containing wallet identity, wallet address display, linked social metadata, and the PWA install prompt on eligible devices.
Progressive Web App (PWA)
WizPay ships a complete PWA surface for add-to-home-screen installability on mobile and desktop:
The install prompt shown in the Profile hub gates visibility on a real installability signal (
nativePromptAvailable || manualInstallAvailable) in addition to the mobile/not-installed/not-dismissed checks, preventing the prompt from appearing on platforms where installation is not possible.
Circle Mobile Session Recovery
On mobile devices, Circle W3S SDK sessions can silently expire when the browser is backgrounded. The frontend implements a provider-owned recovery layer:useMobileRecovery— Listens tovisibilitychange,focus,pageshow, andonlinebrowser events. On each trigger (throttled) it callsrearmSdkForSessionto re-hydrate the SDK with the current auth token.rearmSdkForSession— Sets the current user token on the Circle SDK instance without a full re-initialisation.ensureSessionReady— Exposed onCircleWalletContextValue. Called byuseTransactionExecutorand the bridge screen before every Circle-mode operation. If the session is expired, arms the SDK and refreshes wallets before proceeding.withRecoveredSession— Wrapper insideuseChallengeActions. Catches recoverable Circle session errors (code155706and related invalid-device codes), callsensureSessionReady, and retries the failed operation exactly once.
Orchestrator
OrchestratorService.handleTask()— HTTP entry point. Creates task, sets status toassigned, enqueues to BullMQ.OrchestratorService.executeTask()— Worker entry point. Idempotency guard → status toin_progress→ route to agent → finalize.- Legacy
type: bridgetask submissions fail closed before task creation.
Task Module
Execution Layer
ExecutionRouterService— ReadswalletModefrom task payload. Routes toAgentRouterService(W3S) orPasskeyEngineService(PASSKEY).PasskeyEngineService— Handles its remaining non-bridge task types. Bridge is not routed through an execution engine.
Agents
Each agent implements theTaskAgent interface:
Adapters
Queue
Trust Boundaries
- All user input crosses the trust boundary at
TaskControllerand is validated before reaching the orchestrator. - The bridge lifecycle cannot access Circle entity secrets, backend signing keys, or treasury wallets.
- In PASSKEY mode, the backend has no signing authority over the user’s wallet. The trust model shifts — the backend produces unsigned intents, the client signs.
- In external-wallet bridge mode, the backend also has no signing authority. It validates the submitted bridge metadata, records the audit trail, and leaves the burn/mint execution to the connected browser wallet.