Skip to main content

The browser extension and window.varnir

Why this matters​

The extension keeps a user's Varnir keys in the browser's wallet, not in a web page. A site asks it to sign; the extension shows the user a plain summary in its own window, and nothing is signed until they approve. That is the model people already know from Ethereum wallets, so the risk of a compromised or spoofed page signing something unseen is lower than with a wallet that lives inside the page.

Status

The extension (apps/wallet-extension, Chrome Manifest V3, Chrome 116 or later) is built, and the scanner uses it when it is installed. It is not yet in the Chrome Web Store; today it is loaded unpacked from a build. The full reference is the extension's README; this page is a summary of it.

Who can use the provider​

Only Varnir's own sites. The provider is injected on https://scanner.varnir.site and https://playground.varnir.site, top frame only (a development build adds http://localhost and http://127.0.0.1 on any port). It is not injected anywhere else, and the extension refuses a request from any other origin with 4100. A third-party site cannot ask it to sign.

To build on Varnir from your own site or server, use the SDK instead. This page is for people working on Varnir's own web apps, and for anyone who wants to understand what the extension does.

What the user sees​

  • The wallet in the toolbar. The popup is the scanner's wallet dock: the same components, from the shared packages/wallet-ui package, with data kept in chrome.storage.local.
  • Approval in the wallet's own window. Every request that signs something opens an extension window with a plain summary. A send shows the amount and token, from and to (with the contact's name), network, the note, the payout speed and its credits, the network fee for a native on-chain send (Varnir fronts a token's gas), "first payment to this recipient" when it applies, and a warning for a deliberate repeat. A send is held to confirm. A request the extension has no summary for is refused.
  • Keys stay in the extension. The vault lives in the extension's service worker. Web pages get signatures and results, never a key.
  • Move to extension. A wallet saved on the scanner can be moved into the extension. The user enters their site PIN, pattern or password; the site copy is removed only for the accounts the extension took.

The provider​

window.varnir follows EIP-1193, the Ethereum provider standard, so the shape will be familiar:

function onProvider(callback) {
if (window.varnir?.isVarnir) return callback(window.varnir);
window.addEventListener('varnir#initialized', () => callback(window.varnir), {once: true});
}

onProvider(async (varnir) => {
const [identity] = await varnir.request({method: 'varnir_requestAccounts'});
const result = await varnir.request({
method: 'varnir_send',
params: {network: 'niles', to: 'TSC9KBw...', amount: '1.5', speed: 'economy'},
});
// result: { umid, settledOn, proposal?, hold?, speed?, speedRecorded? }
});

It also answers an EIP-6963-shaped handshake under Varnir's own event names (varnir:requestProvider / varnir:announceProvider), so an Ethereum wallet picker never offers it as an EVM wallet.

StandardWhere it shows up
EIP-1193request({ method, params }), on / removeListener, error objects with code
EIP-1474-32602 invalid params, -32603 internal error
EIP-1102Connect first (varnir_requestAccounts), then read accounts
MetaMaskthe varnir#initialized event, and approval in a separate notification window

Method groups​

The README has every method with its params and result. In outline:

GroupMethodsApproval window
Accountsvarnir_requestAccounts, varnir_accounts, varnir_getLockState, varnir_getEnvironment, varnir_getPublicKeyOnly the first connect
Sending and signing ledger actionsvarnir_send, key, invoice, rename, webhook, order, held-transfer, recovery and plan methodsAlways
Signed API requestsvarnir_signApiRequestWrites always; reads (GET routes) are signed without a window once the site is connected and the wallet is unlocked
Contactsvarnir_contacts_list, _add, _update, _remove, _replaceNo (nothing is signed)
Move to extensionvarnir_importWalletYes, with the site's lock

varnir_send takes { network: "niles" | "sep" | "tbnb", to, amount, token?, symbol?, ref?, speed?, repeat?, settlement? }. The amount is a human decimal, scaled by the on-ledger token registry's decimals for a token; a decimals field, or any field not listed, is -32602, and a token the registry doesn't know is refused before any window opens. It is carried out as the SDK's send(), so a Varnir address settles on the ledger and anything else is an L1 withdrawal.

Errors​

CodeMeaning
4001The user rejected the request, or closed the window
4100Not authorised: not a Varnir origin, the site isn't connected, the connected account was removed, or a contacts call or signed read while the wallet is locked
4200Unsupported method, or an API route the extension won't sign
4900Disconnected: the extension was reloaded or removed, or the user disconnected the site
4901The connection to the extension dropped before an answer; safe to retry
-32602Invalid params, checked before any window opens
-32603The approved request failed. When the ledger names the reason, data.varnirCode carries the SDK's error code, for example REPEAT_PAYMENT with the earlier payment's umid and time

Events​

accountsChanged, lockChanged, contactsChanged, environmentChanged and disconnect. There is no chainChanged: there is no chain to switch.

Not done yet​

  • The Chrome Web Store release.
  • Biometric unlock in the extension (PIN, pattern and password work).
  • Market orders through the extension (Make, Take and Cancel work).
  • A Firefox build.