Varnir
Scanner Playground Docs

Live on Ethereum Sepolia & Tron Nile testnets

A payment rail
AI agents can be
trusted with.

Software agents are starting to make economic decisions. Varnir is the settlement layer underneath them — with a treasury-control model where one agent's intent to pay is verified by other agents before a single unit moves.

Testnet. The settlement layer, wallets, invoicing and SDK are built and running on public test networks. The multi-agent approval layer is where this is going — not something you can use today. This page says which is which.

01 — The problem

An agent that can pay is an agent that can be wrong expensively.

Give a model a key and it can move money. That is the whole security review. There is nothing between the inference and the irreversible transaction — no second opinion, no policy check that the model cannot talk its way past, and no record of why a payment was considered correct.

  • i

    One model, one signature, no recourse

    A single agent holding a private key is a single point of failure. Prompt injection, a hallucinated invoice, a compromised tool response — each of them ends the same way: a valid signature over a payment nobody sanctioned.

  • ii

    Custody is the actual risk

    The usual fix is to hand the key to a platform instead. Now the platform can move your funds, and its breach is your breach. Trading one unaccountable signer for another is not a control.

  • iii

    Nothing to audit afterwards

    "The agent decided to" is not an audit trail. Without a record of what was proposed, what checked it, and on what grounds it passed, an automated treasury cannot be reasoned about — let alone signed off by anyone accountable for it.

02 — The approach

Put agents on both sides of the transaction.

An agent proposes a payment. It does not execute one. Independent verifying agents check that proposal against treasury policy, and only an approved proposal becomes a settled transaction. The proposer never holds unilateral authority — because authority is the thing being split.

In design — not shipped Proposing agent "pay 4,200 USDT" Verifier counterparty + limits Verifier policy + budget Verifier anomaly + duplicate Settlement on-ledger, final
The proposer holds no unilateral authority. Every verifier is an independent check, and every decision — approval or refusal — is a record you can go back and read.

That is the shape it is heading for. The first rung of it is built, and running on public testnet today: two keys on one identity, and a payment that cannot happen until the second one says so.

Built — on testnet today send() polls its own identity confirmTransfer() Agent · spender key stake 0 · cannot send Proposal, not payment nothing has moved Approver · treasury key stake 80 · cannot initiate Settlement on the stored terms
The split is enforced by key authority at consensus — not by a permission check an API could get wrong, and not by the agent behaving itself. A compromised agent's payment is refused by the ledger. Nor can the approver rewrite what it approves: amount, destination and network are copied back out of the stored proposal before anything executes. Today that is one approver, and the ledger does not record who proposed, so keeping the two processes apart remains a deployment decision rather than something we enforce. How it works, in code →
Built

Your key never reaches our servers

Not a policy — a property of the code, everywhere in the stack. Keys are generated in your process and stay there. Transactions are signed locally and posted straight to a chain node, not relayed through an API that could have signed for you.

The one thing our API is asked for during wallet setup is which wallet id to claim — a public, unauthenticated read. It hands out ids. It cannot assign one to you; that takes a transaction signed by your own key.

Built

Signed requests, not bearer tokens

API credentials are a secp256k1 keypair you generate, of which we only ever store the public half. Requests carry a signature over the route, a timestamp and the exact body — so there is no secret in a header to leak through a log or a proxy, and a signature cannot be replayed against a different endpoint.

Built

Real infrastructure, not a diagram

A four-node settlement network with the wallet, transfer and onboarding logic written as on-ledger contracts. A public scanner over it. Wallets, invoicing and deposit webhooks across two L1 testnets. You can go and use it right now.

In design

Approval as a first-class record

The treasury layer's output is not just an allow or a deny — it is a durable, inspectable record of what was proposed and what each verifier concluded. An automated treasury that cannot be audited afterwards is not one a serious organisation can adopt.

03 — Live today

Testnet, and actually running.

Everything below is deployed on public test networks and reachable from this page. Nothing here handles real funds, and we would rather say so plainly than let a landing page imply otherwise.

Scanner

Public scanner over the settlement ledger and the two L1 testnets it watches — transactions, identities, wallets and deposits.

scanner.varnir.site

Web wallet

Onboard an identity, get a wallet assigned, send and receive — entirely in the browser. The private key is generated there and never leaves.

scanner.varnir.site/wallet

Invoicing & webhooks

Named, referenced invoices across one or more wallets, with payment detected from observed deposits and HMAC-signed callbacks at both pending and confirmed.

USDT and native, both networks

Settlement layer

A custom ActiveLedger fork running as a four-node network, with onboarding, wallet assignment and transfer implemented as on-ledger contracts.

Ethereum Sepolia & Tron Nile

SDK

@varnir/chain-client and @varnir/signing — everything the web wallet does, from your own code, with the same client-side signing guarantees.

TypeScript

Playground

Edit and run the SDK against a live testnet, right in the browser — onboard an identity, claim a wallet, raise an invoice, and watch each step's real result.

playground.varnir.site

Mobile wallet

A native iOS and Android wallet, built on the same SDK. In development, not yet released.

React Native

04 — Where this is going

The convenience of an exchange, without the custody.

What makes a centralised venue pleasant to use is that a trade is a bookkeeping entry between two accounts on one system — instant, no chain gas, no waiting for a block. What makes one risky is separate: it holds the assets, so it can lose them, freeze them, or spend them. Those two things can come apart, and this rail is already on the right side of both.

Built

Balances already settle internally

A deposit credits a pooled L2 balance on your own identity, maintained on-ledger as it confirms. Reading your balance is reading your own stream — not asking us what we think you have.

Built

And nobody here holds the keys

The keys that could move those funds on L1 are never whole at Varnir — split across independent node operators, or generated so the key is never assembled anywhere at all. There is no operator override to ask for, and none to compromise.

In the contracts, not exposed

Gas-free transfer between identities

The settlement half of trading is already written: a path that debits one identity's L2 balance and credits another's in a single transaction, touching no L1 chain. Real code on a deployed contract — just not reachable from the SDK yet.

Not built

Quoting, matching, a market

Moving a balance between two identities is settlement, not an exchange. Deciding who trades with whom and at what price does not exist in any form. Settlement first, matching second — that order comes from what is written, not from preference.

Agents come first here on purpose. One trading against a bounded, approvable balance is a smaller promise than a person's savings, and it exercises the settlement layer for real while the amounts stay proportionate to a testnet. Widening to people's own funds is a different bar, and it should be cleared in that order. The full roadmap, including what is missing →

05 — Build on it

Five steps from nothing to a live invoice.

Create an identity, put it on the ledger, get a wallet assigned, register a signing key, raise an invoice. Every signature happens in your process.

wallet-and-invoice-flow.ts
// 1. A key you generate, and keep.
const phrase  = generateRecoveryPhrase();
const keyPair = derivePrivateKeyFromPhrase(phrase);

// 2. Onboard it. Signed here, posted straight to a chain node.
tx.$sigs.otk = signPayloadBase64(tx.$tx, keyPair.privateKeyHex);
const identity = await sendToAnyNode(tx);

// 3. Claim a wallet, then prove ownership on-chain.
const wallet = await claimWallet('niles', 'trx');
await assignWallet(identity, keyPair, wallet.id);

// 4. Register a separate, scoped signing key.
await registerApiKey(identity, apiKeyPair, ['invoices:create']);

// 5. Raise an invoice — signed request, no bearer token.
const invoice = await createInvoice(apiKeyPair, {
  walletIds: [wallet.id],
  amount: '10',
  currency: 'native',
});

We are early, and we would rather say so.

Varnir is a working testnet with a clear thesis, not a finished product. If AI agents transacting on their own behalf is a problem you are thinking about — as something to build on, to integrate, or to argue with — the code is the honest version of the pitch.