Docs
How Velumtools works.
Velumtools is a pay-as-you-go privacy network on Robinhood Chain Testnet: a WireGuard tunnel from independent nodes, end-to-end encrypted Messenger and Mail on XMTP, and per-token AI. What makes it different is where the money waits — in a payment-channel contract, not a company wallet.
01 /What it is
Three products share one identity (your 0x) and one settlement layer. The website is only a shop window: it reads the chain, helps you sign, and then gets out of the way. Tunnels run device → node. Prompts run device → GPU node. Messages are sealed on your device and relayed as ciphertext. Payments move between your wallet, the escrow contract and the node — never through a Velumtools server.
02 /Four planes
| Plane | What lives there | What it never sees |
|---|---|---|
| Device | Wallet, per-channel session key, WireGuard private key, XMTP installation key | — |
| Control | This website: reads NodeRegistry, builds transactions, signs vouchers locally | Your traffic, your prompts, your messages, your funds |
| Data | Tunnel nodes, GPU nodes, XMTP relays | Your wallet funds; plaintext messages |
| Settlement | NodeRegistry, PaymentChannels, AccessGate on Robinhood Chain Testnet | What you browsed, asked, or wrote |
03 /Payment channels
Every paid session is a unidirectional channel from you to one node. You deposit once; as service flows your browser signs cumulative vouchers with a throwaway session key the wallet named when opening the channel. The node can redeem the latest voucher any time before expiry; you can reclaim the rest after it.
// EIP-712, domain { name: "Velum Channels", version: "1", chainId, verifyingContract: PaymentChannels }
Voucher(uint256 channelId, uint128 cumulativeAmount)
open(payee, service, token, amount, signer, duration) // user
claim(id, cumulativeAmount, sig) // node, pays only the delta
claimAndClose(id, cumulativeAmount, sig) // node, refunds the rest now
reclaim(id) // user, after expiry- Bounded risk. Nodes serve at most a small grace window ahead of the newest voucher (50 MB for tunnels, $0.01 for Infer) and pause otherwise. Users pre-pay nothing beyond the deposit and sign nothing beyond what was metered.
- Fee on-chain. The protocol fee (5% by default, capped at 10% in code) is split out at redemption, in the same transaction.
- Session keys. A leaked session key can sign away at most that channel's deposit — never your wallet.
04 /Tunnel
You pick a node from NodeRegistry (the dashboard pings each endpoint directly for latency). After the deposit, the browser generates a WireGuard keypair locally, signs velum-vpn-session:chainId:channelId:publicKey with the session key, and posts the public key to the node. The node verifies the channel on-chain, attaches the peer, and returns its public key and UDP endpoint. You import the config into the official WireGuard app.
The node meters bytes per peer (wg show transfer) and publishes what it is owed; the open dashboard signs vouchers as it grows. Closing freezes the bill first, then asks for one final voucher, then settles and refunds in a single transaction.
05 /Messenger & Mail
Both run on XMTP with MLS (RFC 9420): per-device installation keys, forward secrecy and post-compromise security. A letter is a custom content type velumtools.xyz/mail:1.0 (subject, body, inline attachments) inside the same conversation as chat, so the two never mix in the UI.
Sending needs a pass in AccessGate: hold 300,000 VELUM or pay once. Relays can't enforce that — so every recipient's app checks the sender with hasAccessBatch and routes senders without a pass to Requests. The rule is public and identical for everyone.
06 /Infer
Nodes expose an OpenAI-compatible POST /v1/chat/completions. Send x-velum-channel and, optionally, the latest voucher in x-velum-voucher: amount:signature. Before any GPU time is spent the node checks earlier answers are covered and the deposit can pay for this request's worst case. The SSE stream ends with a velum.receipt event carrying the new cumulative total to sign.
Prompt tokens bill at half the output rate. Open-lane GPUs see your prompt in the clear — don't send secrets to Infer.
07 /Contracts
| Contract | Role | Address (chain 46630) |
|---|---|---|
| VelumToken | Fixed 1B supply, no mint, no owner. Stake + access. | 0xd523c61495FE8FF69254b625980798b636b756aa |
| NodeRegistry | Staked directory: register, update, unbond (7d), slash (owner → treasury). | 0x6C7e104224476872a17fc10CA6B510D596A61c56 |
| PaymentChannels | Escrow + EIP-712 vouchers, fee split on redeem. | 0x5650a99850674E164ec55041ad460dD8Ea5C22Df |
| AccessGate | Hold-or-pay-once passes for Messenger and Mail. | 0x1C89B2926c09414EbBe0aa05E0360e4D3ad462db |
| MockUSD (tUSD) | Testnet stablecoin with an open faucet. | 0xD517A0453176fbA3001A0D2350ce0c29EfEDC7E0 |
Source and tests live in contracts/ (Foundry). 21 tests including a fuzz test that the escrow always ends empty.
08 /Node API
| Route | Purpose |
|---|---|
| GET /info | Operator address, services, city, prices, backend (wireguard / simulated, ollama / simulated). |
| POST /vpn/session | {channelId, publicKey, signature} → WireGuard peer config. |
| GET /channels/:id | What the node thinks is owed, vouchered and claimed; state and reason. |
| POST /channels/:id/voucher | {amount, signature} — cumulative EIP-712 voucher. |
| POST /channels/:id/close | Signed close request. 402 with the frozen bill if a final voucher is needed. |
| GET /v1/models | Models this GPU node serves. |
| POST /v1/chat/completions | OpenAI-shaped, billed through the channel in x-velum-channel. |
09 /Threat model
| Party | Can see | Cannot see |
|---|---|---|
| Chain observers | That a wallet funded a channel to a node, and how much was redeemed | Sites, prompts, messages |
| Tunnel node | Your IP, traffic volume, and — like any VPN exit — unencrypted traffic leaving it | Your wallet funds; your WireGuard private key |
| GPU node (open lane) | Your prompt and the answer | Anything outside that request |
| XMTP relays | That two installations exchanged ciphertext, and when | Message content, subjects, attachments |
| This website | Nothing it doesn't render in your own browser | Keys: they stay in your browser storage |
Metadata is not nothing: which node you paid is public on-chain. Use a fresh wallet if that link matters to you. Session keys and WireGuard keys are kept in this browser's storage; a compromised browser is a compromised session.
10 /Known limits (testnet)
- Slashing is decided by the registry owner — a multisig on mainnet, but still a trusted role. Proof-of-bandwidth challenges are future work.
- Vouchers are signed while the dashboard is open. Close the tab and the node pauses after the grace window.
- Mail attachments are inline and capped at ~600 KB; larger files need encrypted remote attachments.
- No private (attested) Infer lane yet — we won't label an ordinary process an enclave.
- Contracts are unaudited. Testnet tokens only.