Where this is going
Varnir is a venue where value is exchanged, not just moved. The ergonomics people like about centralised exchanges come from settling internally, not from holding assets — those two things can be separated. The exchange running on testnet is that separation, built.
Each item is marked shipped, shipped with a limit or not built. Everything runs on public test networks, and no dates are committed.
The milestone this follows
An agent can hold a key that lets it propose a payment and never execute one. A second key confirms, on the terms the ledger stored, and cannot alter them. That is shipped, deployed to testnet, and documented in AI agent payments.
A key can also hold dual status — able to raise a transfer and to confirm one, but never the one it raised. That is what lets peers check each other rather than needing an approver above them, and it is the shape trading between agents wants.
It matters here because it is the control that made the rest safe to attempt. A venue where software initiates trades is only reasonable if the software's authority to move value is bounded by something it cannot talk its way past — and key authority read at consensus is that, in a way an API permission is not.
The idea: centralised-style, without handing over your keys
Centralised exchanges are convenient for mechanical reasons. A trade is a bookkeeping entry between two accounts on one system, so it is instant, costs no chain gas, and needs no counterparty to be online. Decentralised exchanges give that up: every trade is an on-chain transaction, priced in gas and paced by blocks.
The convenience comes from internal settlement. The risk comes from a separate property — that the venue holds the assets, and so can lose, freeze, or spend them. Varnir settled internally and held no keys before there was any exchange, which is the basis for the two coming apart:
- Deposits credit a pooled L2 balance on your identity, maintained by
Varnir.Depositas deposits confirm. Reading a balance is reading your own ledger stream. - The keys that could actually move those funds on L1 are never stored whole — Shamir 3-of-4 across the four ledger nodes, reassembled briefly inside a confidential VM only to sign, or two-party threshold ECDSA where the key is never assembled anywhere (testnet today, with a cggmp24 successor in progress). Testnet is built for speed and delivery, so Varnir runs every node; production is designed to spread them across separate operators, cloud providers and countries, so that no single party, Varnir included, can reassemble a key. See how keys are held.
So the balance is internal, and nothing moves it without your signature. What was missing was the part that turns that into an exchange. That part now exists.
What shipped: trades that settle on L2
Settlement. An identity-to-identity transfer is a single ledger
transaction — transferOnLedger in the SDK, which signs the transfer entry
of Varnir.CryptoTransfer. It debits one identity's L2 balance and credits
another's, and touches no L1 chain at all. No Varnir fee applies to either a
token or a native transfer — both move at the full amount. It is a public SDK
call now, not a path that lived only in a contract, and the exchange settles
through the same balance partitions.
A market. On top of that, Varnir.Swap settles two transfers at once,
atomically — both legs move or neither does. Two shapes are live:
- Co-signed swaps. Two identities sign one transaction between them and submit it. Nobody holds either side in the meantime.
- Resting orders. A maker signs an offer — what they give, what they want, when it expires — and posts it to an order book without moving anything. A taker settles against it later, in one atomic fill.
Matching. Pairing orders is done by an off-ledger matcher that runs in every gateway, fed the same signed orders the way deposits are. Matching is deterministic price-time priority, so each gateway arrives at the same pairs on its own; the only thing they coordinate is which of them submits the fill, in staggered windows. The matcher is deliberately a small thing: it sees the terms of resting orders and nothing else. It cannot hold funds, because it never receives any, and it cannot alter a trade, because the terms it settles are the ones the maker signed — the ledger would refuse anything else. The worst a bad matcher can do is sit on an order, and cancelling one writes an on-ledger marker signed by you, so a cancel holds even if a matcher's copy is stale.
Where you use it. The scanner's /exchange
page and the mobile wallet's Trade tab both offer Make, Take and Cancel. If
you have paired your phone with the scanner, the exchange page can route all
three through the phone, which signs on-device with a key that never leaves
it. With the browser extension installed and
connected, the extension signs them instead. The exchange guide walks through each; Swaps and
gas-free transfers has the SDK calls.
Fees. None. The exchange is free in v1, as a deliberate choice rather than an oversight — exchange pricing sets out what a fee could look like, and why nothing is charged now.
What the exchange does not do yet
These are limits, not bugs, and each is stated on the exchange guide as well:
- A market order fills at most one resting order per call. Partial
fills themselves are built —
fillOrdertakes part of an order and the matcher rests the remainder — but a market order picks the single best-ranked maker that can accept a non-trivial fill and reports what it could not spend asunfilledGive, rather than sweeping several makers in one go. A deliberate tradeoff: a multi-maker sweep means N ledger transactions and a slippage floor split across differing rates, for a result the caller gets by calling again against the refreshed book. - No market orders from the phone or the browser extension. Make, Take and Cancel work from both, token legs included; "fill now at the best price" is on the scanner only.
- No treasury approval on a trade. An identity protected by a confirming key cannot yet have a second key approve an order the way it approves a payment. Carrying the propose/confirm model over to orders is the obvious next extension, and it is not started.
- Matching is off the ledger. The order book is not consensus state. That is a deliberate trade — it is what makes posting an order free and instant — and it is safe because the matcher can only relay or withhold, never settle on its own. But "which orders are resting right now" is a gateway's answer, not the ledger's.
Why agents come before people
The first users of this are expected to be software: agents paying each other and trading with treasury approval standing behind them. That is not a sequencing accident.
An agent trading against a bounded, approvable balance is a smaller promise than a person's savings. It lets the settlement layer be exercised for real — real balances, real gas, real approval flows — while the amounts stay proportionate to a testnet's maturity. Widening to people's own funds is a different bar, and it should be cleared in that order rather than at the same time.
On the regulatory question
The reason to be careful rather than triumphant here: how keys are held is an architectural fact, not a regulatory classification. MiCA's heaviest licensing sits on entities that hold or control client assets or keys, and Varnir is built so that "trust the operator" is not a step in the flow. Whether that lands where the architecture suggests is an open question with real interpretive uncertainty, and it is not settled by us asserting it.
The MiCA position sets this out properly, including what Varnir has not done: no regulatory guidance sought, no sign-off, no compliance claim. An exchange function on a rail changes the regulatory surface rather than leaving it fixed. Now that one exists, that is a thing to get advice on, not to design around by assumption.
Status, in one table
| State | |
|---|---|
| User-held identity keys; split L1 pool keys | Shipped |
| Nodes run by separate, independent operators | Not yet — Varnir runs every testnet node; production is designed for independent operators |
| Deposits, pooled L2 balances, L1 withdrawal | Shipped |
| Tokens keyed by L1 contract address, not by ticker | Shipped, on testnet |
| Adding a token by transaction instead of by release | Shipped, on testnet — a stake-100 key only |
| Varnir fee on transfers and withdrawals | None — removed from the contracts (credit-only model); a native sender pays network gas on top of the amount, and Varnir fronts a token withdrawal's gas |
Plans and credits (Varnir.Plans: one credit balance per identity, plans bought with credits, auto-renew; credits taken for withdrawals and wallets) | Built for the testnet, live with the credits-only rollout — credits come from the testing button; buying credits (top-ups) is not built. See How credits work |
| Payout speeds (Economy, Standard, Instant) | Shipped with a limit — on Bitcoin the speed sets the fee rate; elsewhere it is recorded and nothing is batched or delayed yet. Credits are charged at Economy for every speed |
Repeat-payment guard (an identical payment within 10 minutes is refused unless the owner key says repeat) | Shipped, on testnet |
| New-recipient hold (first payment to a new address or identity held 24 hours, with a cancel link and a speed-up code) | Shipped with a limit — in the contract and the TypeScript SDK, switched off on the network until it has been checked end to end |
Browser extension with a window.varnir provider | Shipped with a limit — built and used by the scanner when installed; not yet in the Chrome Web Store. See Browser extension |
| Scanner API rate limits, per IP and per plan | Shipped — see Rate limits |
| BNB Smart Chain testnet | Shipped, on testnet |
| Base Sepolia, Arbitrum Sepolia and Polygon Amoy (deposits, withdrawals, wallet pools, faucet; USDT and VUSDC, plus Circle testnet USDC on Base Sepolia) | Shipped, on testnet — live 2026-09-29; the mainnets (Base, Arbitrum One, Polygon PoS) are not live |
| Open listing: anyone can add a token | Not built |
| Agent proposes / treasury confirms | Shipped, on testnet |
| Dual status — a key that proposes and verifies, never its own | Shipped, on testnet |
| M-of-N approval (more than one confirmer required) | Not built — see treasury limits |
| L2 identity-to-identity transfer | Shipped — transferOnLedger in the SDK |
| Quoting, matching, an off-ledger matched market | Shipped, on testnet — see the exchange guide |
| Exchange on the scanner, the mobile Trade tab, phone remote signing and the browser extension | Shipped, on testnet |
| Partial fills | Shipped, on testnet — fillOrder's fillAmount, and the matcher rests the remainder |
| Exchange fee | None — free in v1 |
| Treasury approval on an order | Not built |
| Post-quantum identity keys (Falcon-512 default, ML-DSA-65 selectable) and 12-word recovery of them | Shipped, on testnet — Activeledger 4.7. New identities only; identities made before the release and the gateway's signing key are still secp256k1. See quantum safety |
| QER: fresh-wallet, no-reuse withdrawals; private relay on Ethereum | Not built — design only |
| Real funds | No — public testnets only |