When a cardholder swipes their card, the card network sends an authorization webhook to your backend. You have ~2 seconds to check credit, execute an on-chain draw, and respond.
Card swipe → Visa → Card issuer → Your webhook endpoint ├─ Validate signature ├─ Look up wallet from card ID ├─ GET /credit/accounts/{account}/info → check credit ├─ GET /credit/accounts/{account}/draw → build draw calldata ├─ Execute on-chain via delegated signer └─ Respond: approved / declined
This example uses Rain as the card issuer. Adapt signature validation and response format for your card program.
Users deploy a smart account (ERC-4337) and grant your backend a scoped session key or module that can only call the credit draw function. The user retains full custody.
ERC-7579 Session Keys
User grants a scoped session key that can only call the credit draw function. Expires automatically.
Pre-signed Permits
User pre-signs EIP-2612 permits for USDC transfers up to a spending limit.
Smart Account Modules
User’s smart wallet delegates draw authority to your backend via a custom module.
Deploy an ExclusiveOperator contract that lets your backend draw credit on behalf of opted-in users. This is the pattern used by card programs that need server-side control over credit draws.Setup (one-time):
// Deploy with your backend address as the authorized callerExclusiveOperator operator = new ExclusiveOperator( creditHubAddress, // Sprinter Credit Hub controllerAddress, // Credit Hub Controller adminAddress, // Contract admin (your multisig) callerAddress, // Your backend's signing address 7 days // Revoke delay — users must wait 7 days to revoke);
User onboarding:
// 1. User sets the operator on their credit positioncreditHub.setOperator(address(operator));// 2. User whitelists your settlement address as a credit receiveroperator.addCreditReceiver(settlementAddress);
Drawing credit at swipe time:
// Your backend calls this directly — no user signature neededoperator.openCreditLine( borrowerAddress, // User's wallet settlementAddress, // Whitelisted receiver amount // USDC amount in wei);
Safety guarantees:
withdraw() is disabled — the operator can never touch collateral
Credit can only go to whitelisted receivers the user has explicitly approved
Revocation has a time delay (e.g. 7 days) — prevents users from revoking mid-billing-cycle while the operator still has outstanding credit exposure
Users can schedule revocation at any time via revoke(), then finalize after the delay with finalizeRevoke()
The caller address can draw credit from any opted-in user account. Secure the private key with HSM or KMS in production — never store it in environment variables on shared infrastructure.