Numpay is a client-heavy system. The browser app owns the user’s key and signs every payment. The backend is a directory and history service: it maps identities to wallets, stores payments and requests, and holds keys only for unclaimed (claimable) wallets. Money never passes through the backend; it moves directly between smart accounts on-chain.
What actually moves on-chain. The product pages say “crypto”. Technically, every Numpay payment is sent as USDC: sends, paid requests, NEAR deposits and claimable-wallet sweeps are all ERC-20 transfer calls of native Circle USDC on Base mainnet (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, 6 decimals). On the Elysium testnet the same calls move bridged USDC (0x7d29d8047b905000459c0e80c34a26ceedcb47b2). Balances shown in the app are the smart account’s USDC balanceOf, displayed 1:1 in dollars.

High-level diagram

Components

Design principles

Non-custodial by default

User keys never reach the backend. The backend can’t move a registered user’s funds.

Identity from verified tokens

The server reads phone and email only from Web3Auth-signed ID tokens, never from request bodies.

Deterministic addresses

A wallet address is a pure function of the user’s key, computed identically in the app and the backend.

Chain-agnostic stack

The same Kernel account gets the same address on every EVM chain, so Numpay can run on Base and Elysium with one wallet design.

Where to go next

Identity and auth

Smart accounts

Claimable wallets