Pay with your palm in 2 seconds — USDC settled on-chain. No card, no phone, just you.
Velt is a biometric payment system that turns your palm into your wallet. You enroll your hand once, and from then on you pay at any Velt merchant by simply placing your palm on the sensor — no card, no phone, no PIN, no app to open. Payment confirms in about two seconds. Behind the scenes the funds move as USDC settled on-chain, but to the person paying it's just: place your hand, done.
There are two sides:
For the customer (payer): You register your palm and identity once. After that, your body is your wallet — there's nothing to pull out, carry, charge, or remember. You can top up your balance, and scanning your palm also lets you instantly check your wallet: balance, your ENS name, and your full transaction history.
For the merchant: You accept palm payments through the Velt sensor — no expensive terminal. You see your balance update in real time as customers pay, and you can withdraw your funds whenever you want, to wherever you want. Withdrawals can even be private, so the link between your business account and the destination is broken on-chain.
Under the hood, every user gets their own non-custodial wallet and a human-readable ENS identity (e.g. cafe.velt.eth), payments are protected by conditional on-chain escrow (funds are held and released on delivery, or auto-released after a timeout), and balances are backed by USDC, a stable digital dollar. All of that crypto machinery is invisible to the user.
The result is the fastest, most frictionless way to pay or get paid: secure biometrics, verified identity, instant settlement, and self-custody — with an experience as simple as showing your hand. The future of payments is in your hands.
Velt has two halves: a Kotlin + Jetpack Compose Android app driving the Velt palm sensor, and a Node 20 / TypeScript (strict) / Fastify backend that orchestrates everything on-chain. The app wakes the sensor over BLE, captures the biometric template over SPP/RFCOMM (parsing the sensor's JSON event stream by balanced braces), and identifies the palm against the OpenPalm bioserver with HMAC-SHA256-signed requests, yielding a stable personId.
The backend's core abstraction is a single Signer interface, which turned out to be the most valuable design decision: it let us swap the entire custody model in essentially one file. We moved from custodial ERC-4337 smart accounts to Dynamic Server Wallets (@dynamic-labs-wallet/node-evm) — TSS-MPC EOAs where the private key never exists whole. Crucially, Dynamic's getWalletClient() returns a viem WalletClient, so the backend signs Arc transactions with the exact same chain code it already had. Every actor (merchant, payer, escrow operator) gets one MPC wallet, persisted in Supabase (PostgreSQL via PostgREST).
Payments settle in USDC on Arc (Circle) through a custom VeltEscrow.sol contract (hold → release/refund) — the payer's wallet does an approve+hold, funds sit on-chain, and the merchant releases via confirm or an automatic timeout sweep. The whole flow is 202 + background settlement + WebSocket event, never throwing — a pattern we reused for payments, withdrawals, and ENS. With no Foundry on the build machine, we compiled and deployed the contract with the solc npm package + viem.
Partner tech, and how it helped:
Hacky bits worth mentioning: (1) ENSv2 is alpha and undocumented, so wissionedRegistry/Resolver interface from the ensdomains/namechain repo+ on-chain spelunking to issue subnames programmatically. (2) We bridged Dynamic's viem wallet into Unlink's EvmProvider (evm.fromViem), so a single MPC wallet signs both the Arc escrow and the Permit2 deposit into Unlink's privacy pool. (3) Dynamic migration happen without touching a line of escrow, payment,or withdrawal logic.

