SwiftPay

Instant crypto payments via state-channel clearing, settled later in USDC—Visa-style for Web3.

SwiftPay

Created At

HackMoney 2026

Winner of

ENS

ENS - Integrate ENS

Prize Pool

Project Description

What is SwiftPay? SwiftPay is a next-generation, crypto-native point-of-sale (PoS) payment infrastructure that enables instant, cross-chain USDC payments between consumers and merchants. Think of it as "Apple Pay for crypto", users scan a QR code at a coffee shop, and the payment clears in under 200 milliseconds, regardless of which blockchain they have funds on.

The Problem We Solve Traditional crypto payments suffer from three critical pain points:

Slow Finality: Bitcoin takes 10+ minutes, Ethereum up to 12 seconds for a single confirmation, far too slow for retail checkout. Chain Fragmentation: Users hold assets on different chains (Arbitrum, Base, Polygon, etc.), but merchants want funds in one place. Poor UX: Current solutions require copy-pasting addresses, selecting networks, and waiting for confirmations. SwiftPay eliminates all three.

Architecture Overview SwiftPay is a full-stack Web3 payment platform consisting of:

┌─────────────────────────────────────────────────────────────────┐ │ SWIFTPAY ARCHITECTURE │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ LAYER 1: USER INTERFACE (Next.js 15 Frontend) │ │ ├── User Wallet Panel (MetaMask/RainbowKit) │ │ ├── QR Code Scanner (jsQR + BarcodeDetector) │ │ ├── Merchant Dashboard │ │ └── ENS-Powered Merchant Discovery │ │ │ │ LAYER 2: INSTANT CLEARING (Yellow Network) │ │ ├── Nitrolite SDK State Channels │ │ ├── Off-chain Payment Aggregation │ │ └── <200ms Clearing Time │ │ │ │ LAYER 3: SETTLEMENT ORCHESTRATION (Express.js Backend) │ │ ├── ENSService (Merchant Preferences) │ │ ├── AvailBridgeService (Cross-chain via Avail Nexus) │ │ ├── ArcVaultService (Final Settlement) │ │ └── WebSocket Real-time Notifications │ │ │ │ LAYER 4: BLOCKCHAIN LAYER │ │ ├── Ethereum Sepolia (ENS + Yellow Channels) │ │ ├── Avail Nexus (Cross-chain Bridge) │ │ ├── Arc Testnet (USDC Settlement Vault) │ │ ├── Base Sepolia, Arbitrum Sepolia (Multi-chain Support) │ │ └── SwiftPayVault.sol (ERC-4626 Compliant) │ │ │ └─────────────────────────────────────────────────────────────────┘

Core Technology Stack Component Technology Purpose Frontend Next.js 15 + TypeScript + wagmi v2 + RainbowKit User/Merchant interfaces Backend Express.js + WebSocket + EventEmitter Settlement orchestration Smart Contracts Solidity (ERC-4626 Vault) USDC custody on Arc Payment Clearing Yellow Network Nitrolite SDK Instant off-chain clearing Cross-Chain Bridge Avail Nexus SDK Move USDC between chains Merchant Identity ENS with Custom Text Records Human-readable merchant names QR Scanning jsQR + BarcodeDetector API Camera-based QR payments

Key Innovations

  1. Instant Payment Clearing (<200ms) Using Yellow Network's Nitrolite SDK, payments are cleared off-chain through state channels. The user's payment is instantly recognized without waiting for blockchain confirmations. This enables true point-of-sale experiences.

  2. ENS-Based Merchant Identity Merchants register ENS names like coffee.swiftpay.eth with custom text records:

swiftpay.endpoint = "https://api.merchant.com/payments" swiftpay.vault = "0xVaultAddress" swiftpay.chain = "arc-testnet" swiftpay.schedule = "daily" Users simply scan a QR or search "coffee.swiftpay.eth" instead of dealing with hex addresses.

  1. Cross-Chain Settlement Automation The Settlement Orchestrator automatically:

Reads merchant preferences from ENS Aggregates all cleared payments from Yellow Network Bridges USDC to Arc via Avail Nexus Deposits into merchant's SwiftPayVault Notifies merchant via WebSocket 4. Multi-Chain Balance Display Users see their USDC balances across Arc Testnet, Base Sepolia, and Arbitrum Sepolia in a single unified view. Pay from any chain — settlement handles the rest.

User Flow

  1. CONNECT WALLET └─ User connects MetaMask/WalletConnect
  2. SCAN QR CODE └─ Open camera → Scan merchant QR → swiftpay:// protocol decoded
  3. CONFIRM PAYMENT └─ See merchant name, amount, chain → One-tap confirm
  4. INSTANT CLEAR (<200ms) └─ Yellow Network clears payment off-chain instantly
  5. AUTOMATIC SETTLEMENT └─ Backend bridges USDC → Arc Vault → Merchant notified
  6. MERCHANT WITHDRAWS └─ Merchant claims from vault at any time

Technical Deep Dive Frontend (/frontend) Next.js 15 with App Router wagmi v2 for Web3 hooks RainbowKit for wallet connection Custom hooks: useMultiChainUSDCBalances, useYellowNetwork, useWallet Components: QRScanner, PaymentConfirmationModal, UserPanel, MerchantDashboard QR Protocol: swiftpay://base64(JSON) for secure, compact payment requests Backend (/backend) Express.js HTTP API + WebSocket server 4 Core Services: ENSService — Resolve merchant names, read text records AvailBridgeService — Cross-chain USDC bridging with retry logic ArcVaultService — Deposit USDC to merchant vaults SettlementOrchestrator — Coordinates the 6-stage settlement flow 7 API Endpoints for settlement management Automatic Scheduler — Checks merchant settlement schedules every 5 minutes Smart Contracts (/contracts) SwiftPayVault.sol — ERC-4626 compliant vault for merchant USDC deposits Deployed on Arc Testnet (Chain ID: 5042002) Supports multi-merchant deposits and withdrawals

API Endpoints Settlement Orchestration: POST /api/settlement/merchant/:id → Trigger settlement GET /api/settlement/jobs/:id → Get job status GET /api/settlement/stats → Get statistics POST /api/settlement/settle-all → Settle all due merchants Payment Channels: POST /api/channels/merchant → Create merchant channel POST /api/channels/user → Create user channel POST /api/payments/clear → Clear payment (<200ms) GET /api/payments/history → Get payment history ENS Resolution: GET /api/ens/resolve/:name → Resolve ENS to merchant details

Security Features State Channel Collateral — Yellow Network requires locked collateral ENS Verification — Merchants verified via ENS ownership ERC-4626 Standard — Industry-standard vault security Private Keys in Env — Never hardcoded, always in .env Retry Logic — 3 attempts with exponential backoff for blockchain ops

Prize Track Alignment Sponsor Track Integration Yellow Network $15,000 Real Nitrolite SDK state channels, instant <200ms clearing Arc (Circle) $5,000 SwiftPayVault on Arc Testnet, USDC settlement ENS $5,000 Custom text records, merchant identity, schedule automation Avail Bridge Prize Cross-chain USDC via Nexus SDK

Project Structure swiftpay/ ├── frontend/ # Next.js 15 + wagmi + RainbowKit │ ├── app/ # App Router pages │ ├── components/ # UI components (75+ files) │ ├── hooks/ # Custom React hooks │ └── lib/ # Web3 config, ENS, QR utils ├── backend/ # Express.js + Yellow Network │ ├── src/ │ │ ├── services/ # ENS, Avail, Arc, Orchestrator │ │ └── index.ts # Main server │ └── test-*.ts # Integration tests ├── contracts/ # Solidity smart contracts │ └── src/ │ └── SwiftPayVault.sol # ERC-4626 merchant vault └── docs/ # Architecture documentation

What Makes SwiftPay Special Production-Ready: 1,000+ lines of core code, 2,700+ lines of documentation Real Integrations: Not mock data — actual Yellow SDK, Avail Nexus, Arc testnet Complete Flow: End-to-end from wallet connect → QR scan → instant clear → settlement Beautiful UI: Cyberpunk-themed glassmorphism design with micro-animations Multi-Chain: Pay from any supported chain, settle on Arc

Future Roadmap Production mainnet deployment Multi-currency support (USDT, DAI, ETH) Mobile native apps (iOS/Android) Merchant analytics dashboard Push notifications for payments Batch settlement optimization Gas abstraction via ERC-4337 SwiftPay: Pay coffeeshop.eth instantly from any chain. Settle in USDC. Zero friction.

How it's Made

Architecture Overview SwiftPay is built as a three-tier architecture connecting a Next.js frontend, an Express.js settlement backend, and multiple blockchain networks:

┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ Next.js 15 │◄───►│ Express.js │◄───►│ Blockchains │ │ (wagmi v2) │ WS │ (Settlement) │ RPC │ (Multi-chain) │ └──────────────────┘ └──────────────────┘ └──────────────────┘

Frontend Stack Core Framework:

Next.js 15 with App Router — Server-side rendering for initial page loads, client components for Web3 interactions TypeScript — End-to-end type safety across 150+ frontend files Tailwind CSS — Custom cyberpunk design system with glassmorphism effects Web3 Integration:

wagmi v2 — React hooks for wallet connection, balance fetching, contract reads RainbowKit — Pre-built wallet modal with MetaMask, Coinbase Wallet, WalletConnect support viem — Low-level Ethereum client for ENS resolution and contract interactions Notable Frontend Hacks:

Multi-Chain Balance Fetching: We use useReadContracts from wagmi to batch-fetch USDC balances across Arc Testnet, Base Sepolia, and Arbitrum Sepolia in a single hook call: typescript const contracts = testnetChains.map(chain => ({ address: chain.usdcAddress, abi: parseAbi(['function balanceOf(address) view returns (uint256)']), chainId: chain.id, })); const { data: balances } = useReadContracts({ contracts }); jsQR Fallback for Firefox: The BarcodeDetector API isn't available in Firefox. We detect this and fall back to the jsQR library: typescript if ('BarcodeDetector' in window) { const detector = new BarcodeDetector({ formats: ['qr_code'] }); barcodes = await detector.detect(canvas); } else { const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const code = jsQR(imageData.data, canvas.width, canvas.height); } Demo Auto-Trigger Timer: For hackathon demos, we added a hidden 10-second timer that auto-detects a demo QR payload if no real QR is scanned — the countdown runs silently in the background without showing any UI. Yellow Network Integration (Nitrolite SDK) Yellow Network provides instant off-chain payment clearing via state channels. Here's how we integrated it:

How It Works:

User and merchant each open state channels with the SwiftPay Hub When user pays, the Hub updates both channel balances off-chain (no blockchain tx) Clearing happens in <200ms — faster than credit card networks At settlement time, channels are closed and funds move on-chain Implementation:

typescript // Create user state channel const userChannel = await yellowClient.createChannel({ userAddress: wallet.address, hubAddress: HUB_ADDRESS, depositAmount: '100', // USDC }); // Clear payment instantly (off-chain) await yellowClient.clearPayment({ channelId: merchantChannel.id, amount: '5.00', currency: 'USDC', }); Benefit: This enables true point-of-sale experiences where the merchant sees "Payment Received" before the user even puts their phone away.

ENS Integration (Custom Text Records) We use ENS not just for naming, but as a decentralized merchant configuration store. Each merchant has text records like:

coffee.swiftpay.eth ├── swiftpay.endpoint = "https://api.coffee.com/payments" ├── swiftpay.vault = "0x1234..." ├── swiftpay.chain = "arc-testnet" ├── swiftpay.schedule = "daily" └── swiftpay.settlement.time = "00:00" Implementation:

typescript const ensProfile = await publicClient.getEnsText({ name: 'coffee.swiftpay.eth', key: 'swiftpay.schedule', }); // Use schedule to determine auto-settlement timing if (ensProfile === 'instant') { await orchestrator.settleMerchant(merchantAddress); } Benefit: Merchants control their settlement preferences on-chain without any centralized database. The backend reads ENS every 5 minutes to trigger scheduled settlements.

Avail Nexus Bridge Cross-chain USDC movement is handled by Avail Nexus SDK:

typescript class AvailBridgeService { async bridgeUSDC(amount: string, fromChain: 'sepolia', toChain: 'arc') { const nexus = new NexusSDK({ privateKey: HUB_PRIVATE_KEY });

// Bridge with retry logic (3 attempts, exponential backoff)
for (let attempt = 0; attempt < 3; attempt++) {
  try {
    const txHash = await nexus.bridge({
      token: 'USDC',
      amount,
      source: fromChain,
      destination: toChain,
    });
    return txHash;
  } catch (e) {
    await sleep(2000 * Math.pow(2, attempt));
  }
}

} } Benefit: Users can pay from any supported chain. The orchestrator automatically bridges to Arc for final settlement.

Arc Blockchain (SwiftPayVault) The final settlement destination is an ERC-4626 compliant vault on Arc Testnet:

solidity contract SwiftPayVault is ERC4626, Ownable { mapping(address => uint256) public merchantBalances;

function depositForMerchant(
    address merchant, 
    uint256 amount
) external {
    IERC20(asset()).transferFrom(msg.sender, address(this), amount);
    merchantBalances[merchant] += amount;
    emit MerchantDeposit(merchant, amount);
}

function withdraw(uint256 amount) external {
    require(merchantBalances[msg.sender] >= amount);
    merchantBalances[msg.sender] -= amount;
    IERC20(asset()).transfer(msg.sender, amount);
}

} Benefit: Arc provides sub-second finality and native USDC support from Circle.

Settlement Orchestrator (The Brain) The 6-stage settlement pipeline coordinates all services:

typescript class SettlementOrchestrator extends EventEmitter { async settleMerchant(merchantId: string) { const job = this.createJob(merchantId);

// Stage 1: Read ENS preferences
job.stage = 'reading_ens';
const profile = await this.ensService.getMerchantProfile(merchantId);

// Stage 2: Aggregate payments from Yellow
job.stage = 'aggregating_payments';
const total = await this.yellowService.getChannelBalance(merchantId);

// Stage 3: Close Yellow channel (on-chain)
job.stage = 'closing_yellow';
const closeTxHash = await this.yellowService.closeChannel(merchantId);

// Stage 4: Bridge to Arc via Avail
job.stage = 'bridging';
const bridgeTxHash = await this.availBridge.bridgeUSDC(total, 'sepolia', 'arc');

// Stage 5: Deposit to vault
job.stage = 'depositing';
const vaultTxHash = await this.arcVault.depositForMerchant(merchantId, total);

// Stage 6: Notify
job.stage = 'complete';
this.emit('settlement_complete', job);

} } 🔌 Real-Time WebSocket Updates Merchants receive live settlement progress via WebSocket:

typescript // Backend wss.on('connection', (ws, req) => { const merchantId = req.query.merchantId; merchantConnections.set(merchantId, ws); }); orchestrator.on('settlement_update', (job) => { const ws = merchantConnections.get(job.merchantId); ws?.send(JSON.stringify({ type: 'SETTLEMENT_UPDATE', job })); }); // Frontend const ws = new WebSocket('wss://api.swiftpay.app?merchantId=0x...'); ws.onmessage = (e) => { const { type, job } = JSON.parse(e.data); if (type === 'SETTLEMENT_COMPLETE') { toast.success(Settlement complete! $${job.totalAmount} deposited); } };

Notable Hacks & Tricks QR Protocol Design: We designed a custom swiftpay:// protocol with base64-encoded JSON: swiftpay://eyJwYXltZW50SWQiOiJTUC0xMjM0IiwiYW1vdW50IjoiNS4wMCIsIm1lcmNoYW50IjoiY29mZmVlLnN3aWZ0cGF5LmV0aCJ9 This is more compact than URL-encoded JSON and works seamlessly with QR scanners. Public RPC Fallback: To avoid Alchemy API key issues, we default to publicnode.com RPCs: typescript transport: http(process.env.ENS_RPC_URL || 'https://ethereum-rpc.publicnode.com') Graceful Degradation: If BarcodeDetector isn't available AND jsQR fails, we show a manual text input field for pasting QR data. Automatic Demo Mode: The QR scanner has a hidden 10-second timer that auto-fires a $1 USDC demo payment — perfect for quick hackathon demos.

Tech Stack Summary Layer Technology Purpose Frontend Next.js 15, wagmi v2, RainbowKit, Tailwind User interface Web3 Client viem Low-level blockchain interactions QR Scanning jsQR, BarcodeDetector API Camera-based QR reading Payment Clearing Yellow Network Nitrolite SDK Instant off-chain clearing Cross-Chain Avail Nexus SDK USDC bridging Settlement Arc Testnet Final USDC custody Smart Contracts Solidity (ERC-4626) Merchant vault Backend Express.js, WebSocket Settlement orchestration Identity ENS (Custom Text Records) Merchant configuration

Partner Technology Benefits Partner How It Benefits SwiftPay Yellow Network Enables <200ms payment clearing — impossible with on-chain only ENS Decentralized merchant identity + config without a database Avail Nexus Seamless cross-chain USDC movement for multi-chain support Arc (Circle) Native USDC + sub-second finality for final settlement The result: A complete, end-to-end payment system where users pay from any chain, merchants receive USDC in their Arc vault, and the entire flow from scan to settlement is under 30 seconds.

background image mobile

Join the mailing list

Get the latest news and updates