zero storage · zero custody · first-party, adapter-native
🗝 the BNR wallet — one soul, every chain
One identity, every chain. Your bzDiD is your wallet — connect it once
and see your balances across all your chains, sign transactions, and hold your keys.
Nothing leaves your browser.
the multi-chain wallet — bzDiD soul connects, keyless reads show every
balance, derived keys sign. First-party, adapter-native, zero custody.
bzDiD masterPRK → near-infinite per-context derived keys
(secp256k1 for Vaulta AND 0x/EVM, ed25519 for bzDiD rails) → client-side eosjs serialization +
signed here → sent onward via a public door. Your keys stay in this tab's memory — nothing saved, nothing held for you.
New accounts are forged bzDiD-native — no exports, no imports, no manual keys, ever.
🔗 CONNECT — your bzDiD is the wallet
Connect your soul (your .b name or account). New here?
Create your bzDiD — the held-hand ceremony takes 2 minutes.
— not connected —
🗝 THE KEYCHAIN — your bzDiD holds every key
Automatic: your first tap or keypress anywhere on this page connects the
keychain by itself (the WebAuthn ceremony needs one touch of yours — browsers' law, not ours).
The PRF ceremony re-derives your masterPRK in this tab's memory (never stored, never
sent). From it we derive: the ed25519 soul record key (context bnr.b, same as
onboarding), the Vaulta K1 signing key (context vaulta:yourname), your 0x/EVM
and nostr npub rails (your two addresses) — and as many
more as you forge below. No passkey here, or it lacks PRF? Use your 24-word recovery phrase —
same soul, same keys.
📷 QR BRIDGE
🛡 DEVICE MANAGER
every device that permanently holds this soul, as a seal under its own
passkey — the registry is a soul-signed nostr event (kind 30078) any device can read, extend, revoke.
Revoke de-syncs a device (its cached seal keeps working offline — honest limit; a full kill is the recovery-rotate
lane). Sessions via the QR bridge never enter this list.
— registry not loaded —
Which devices and keys can make your bzDiD — the full compatibility check
The passkey must live in a PRF-capable authenticator:
platform ones (Windows Hello, the Chrome profile, Google Password Manager, iCloud Keychain) work;
most third-party managers (Bitwarden, 1Password & friends) don't yet. Create never takes a
manager's word for it: after the "confirmed" the wallet immediately re-touches the exact
passkey just made and demands a real PRF secret from it — if it can't, you're told plainly and
that dead passkey should be deleted (Chrome: ⋮ → Passwords and autofill → Passkeys). A software
passkey confirming instantly is fine; PRF is proven by the touch, not the speed. Hardware keys
must be FIDO2.1-class with a PIN set and room for a resident credential — older U2F keys won't
be offered. If Windows said "unrecognized" when you inserted your key, use the dedicated
🔑 create on a hardware key button — it routes through the browser's native USB lane
(no Windows passkey picker at all), which is the fix for exactly that error. Cross-device (the phone-camera QR) works only when the phone's provider has
PRF — on the phone set the default passkey provider to Google/iCloud, or simply open this wallet
on the phone itself. After a successful create, this wallet re-touches that same passkey
automatically — no "which passkey?" picker ever again.
Passkeys are origin-bound: one made at another site (an Anchor/wallet passkey for your
account, say) can never connect here — it signs at its own site only. Your account's existing
key still bridges you in: paste it once below.
Already hold a bzDiD elsewhere? Don't create a second — import it with your recovery phrase
instead (a new passkey = a new soul).
— keychain not connected —
SOUL FINGERPRINT (ed25519 record · bnr.b)
—
—
VAULTA K1 SIGNING KEY (vaulta:…)
—
chain authority: checking…
🔐 THE VAULT — one keypass, every secret
Bringing keys you already hold — formats, and how they get sealed
The keys you already hold — seed phrases from any wallet
(12 · 15 · 18 · 21 · 24 words) and Vaulta ACTIVE private keys
(5K… · L… · K… · PVT_K1_…) — sealed under a single keypass so you never handle
them raw again. Sealed with PBKDF2-SHA-256 ×600 000 → AES-256-GCM, header
authenticated, salt and IV fresh on every write. Only the ciphertext is stored; it is safe
to back up anywhere. Every phrase is checksum-verified before it goes in — a mistyped
word is caught now, not on the day you need it.
Stated honestly: this is hot storage. It ends the
plaintext juggling; it does not turn a browser key into a cold one, and it cannot protect you
from a page that has been tampered with. For balances you would not accept losing, the answer
is still a signing device.
Choosing your keypass — the one decision to take slowly
① Choose your keypass.
This is the only thing standing between anyone with this browser and every secret inside.
Generate one — eight words from the BIP-39 list is 88 bits of real entropy, which no one
is brute-forcing. Write it on paper. There is no reset:
lose the keypass and the vault is unrecoverable by design.
—
UNLOCKEDauto-locks after 5 minutes idle
② Put a secret in.
Paste it and the type is detected for you — the phrase is checksum-verified, the key is
checksum-verified and curve-checked, before anything is sealed.
— nothing entered —
③ What is inside.
Secrets stay hidden until you ask for one. 0 entries
④ Your devices.
Every one of these opens this vault on its own, and none of them can read the others.
Add each device you own — that is what makes losing one a non-event, and it is how your
bzDiD survives a lost laptop. Revoking one leaves every other device working.
Evidence class follows T3 §6b — a credential is ranked by where its private key
actually lives, not by brand. E3 = device-bound in a hardware keystore (Windows
Hello, Apple/Google platform passkey on its own hardware, Bitwarden device-bound mobile).
E2 = synced or software-held (iCloud Keychain / Google Password Manager / Bitwarden
vault / a keypass in any manager) — only as strong as that vault account’s own auth.
This page requests no attestation statement, so slots sit at the E2 floor unless you
tell it the authenticator is device-bound.
⑤ Your bzDiD.
Seal your soul’s recovery phrase in here and it stops living on one device’s passkey.
Any device in the list above can then restore the same bzDiD — same soul, same keys,
same .b name. The DID persists; keys rotate under it.
—
♾ THE KEY FORGE — near infinite keys, one soul
How each context gets its own key — derivation, on demand
Every context derives its own key from your masterPRK: vaulta:names for
Vaulta account keys, evm:names for 0x addresses, any adapter context you can name.
Derivation is instant, free, deterministic — the same context always yields the same key on
every device. We persist only the context list (this browser), never a key; keys exist
only while your keychain is connected. Tap a key to copy it.
connect your keychain above to see your derived keys — or forge new ones below
— the forge is unlimited; contexts are names, keys derive on demand —
⚡ BALANCES — every chain, keyless, live
Read from public RPCs in your browser. Nothing stored, nothing sent.
The chain is the source of truth.
⚓ Vaulta A
—
core balance + RAM + resources
waiting…
🐝 Hive HIVE/HP
—
liquid + Hive Power + HBD
waiting…
🔵 Arbitrum ETH
—
ETH of your derived bzDiD 0x address (evm:yourname)
connect keychain to derive
🐜 Autonomi ANT
—
ANT on Arbitrum — of your derived 0x address
connect keychain to derive
🕸 Arweave AR
—
of the vault-held JWK — the address is public metadata, reads stay keyless
vault holds no arweave key
🌉 THE BRIDGE — one time, then never manual again
Your bzDiD-derived K1 key is not on your account yet. Paste your existing
active private key once — we build an updateauth that adds your bzDiD keys
alongside every key already on your account (nothing removed, threshold 1: the derived key
AND the account passkey can both sign), sign with your old key, broadcast, and this field
disappears from your life. The old key stays in tab memory only and is scrubbed the moment the
transaction is sent.
— waiting for your existing key —
🏭 THE ACCOUNT FORGE — Vaulta accounts born from your bzDiD
How a new account is born — your bridged key signs it into being
Your bridged account signs newaccount; the new account's owner and
active keys derive from your bzDiD (contexts vaulta:name/owner and
vaulta:name/active) — no key is exported, written down, or imported, ever.
Vaulta economics, stated honestly: broadcasting draws on staked CPU/NET, not liquid
(a 0.0000 liquid balance does not block transactions); the RAM purchase draws from liquid
(live price below). Near infinite: every account born this way signs with your keychain.
RAM cost: reading live market…
— creator liquid: reading… —
💸 PAY — send · receive · swap
receive needs nothing (addresses below are yours to hand out) ·
send signs with your bzDiD keys exactly like every lane here · swap rides the chain's own market
spend cap · optional, owner's tool:unset — no limit
One soul, every rail. Each address above falls out of the
same masterPRK by context tag — Vaulta, one 0x address serving both EVM rails (Base and
Arbitrum share it), Solana, Bitcoin L1, Lightning, nostr. There is no second seed, no import, and no
"connect a wallet" step anywhere: a new bzDiD is never a keyless supplicant. A fresh address for any
rail can be forged in the key forge above (evm:name, sol:name, btc:name …).
QRs are drawn locally — nothing leaves this page. Where a rail cannot be derived honestly the card says
so and shows no address: a wrong receive address is the one mistake that cannot be undone.
liquid: —
derived address: — · gas: reading…
nothing pasted yet — reading happens entirely in this tab.
Both standards, one door: the prefix decides which is read, and
the read is offline — no node, no lookup, nobody told what you are about to pay. Your
spend cap runs on the decoded amount in sats before anything could be sent. Honest limit,
stated because it is one: paying from this page is not wired — the estate's LN seam pays through
an NWC connection whose budget lives at the hub, and its live leg is parked at a relay ACL
(tools/ln-rail/README.md). A BOLT-12 offer priced in a fiat currency has no satoshi price
until its invoice comes back, so a sats cap refuses it here rather than pretending to check it.
your silent-payment address derives from your soul — the record is built here, in this tab.
Self-hosted by construction. A payment name is a
DNS TXT record on a domain you already own — no service, no account, nothing to depend on.
This builds the exact record; you publish it. The offer must be minted by your own node
(the estate's LDK / Alby-Hub per RAIL-FORMULARY-1) — this page will not mint one for you and will
not put a third party's offer under your name. Honest limit: this page holds your
silent-payment address but does not scan for payments to it — BIP-352 scanning walks every
transaction and wants an indexer. Your keys stay reproducible from the two contexts printed on the
card, so any BIP-352 wallet holding this soul can scan and spend. Nothing is stranded; it is simply
not watched from here.
nothing looked up yet.
Resolution is the one leg that cannot be first-party in a
browser: a page cannot validate a DNSSEC chain without shipping a validating resolver. So this asks
a DNS-over-HTTPS resolver and reports whether that resolver says the answer was
authenticated. Trusting that flag is trusting the resolver — and the resolver sees which name
you looked up. An unauthenticated answer is shown as such and must not be paid on. The
sovereign path is the estate's own validating resolver.
the EVM lane sends from your derived 0x address — fund it via
📥 receive first (it is not your Vaulta account wrapped; it's a bzDiD-forged keypair). ETH moves native;
ANT rides its Arbitrum contract. Gas is estimated live before you confirm the broadcast.
quote: reading rammarket…
—
the chain's own market (Bancor-shaped RAM curve — the bmesh-ram
receipts measured it): buy RAM for your account with liquid A, sell RAM you own back for A.
Token-for-token DEX swaps land on this lane next — same law, no third-party router in your face.
— choose a lane above —
🧾 bPay — the preservation invoice
the chooser comes first — every figure is carried from a live, keyless network quote; this panel renders, it cannot spend
the audience choice is yours, in the chooser, before any quote; selecting 🌐 Public and
asking for a fresh quote sends your resolved policy to the keyless bridge — no hidden network
default gets promoted into a choice. 🔒 private audiences stay visibly unavailable until their
paths are qualified. the view toggle (newbee / raver / cypherpunk) only changes what you can
inspect — never the audience, never your authority. no ANT figure is typed by anyone: the bridge
hashed the exact file and quoted every chunk; those quotes — each a quote hash + amount
pair — are the carried commitment (INVOICE-1 law: owed is derived, never asserted). native
gas is a separate wallet-side obligation. when the authorization surface is earned, your own
button press — and only that — crosses the waiting state; no chat text, no terminal, no agent
receipt substitutes for it.
…
🎨 INSCRIPTIONS — your garden, drawn on-chain
ERC-20i: the art lives in the token, and its tier is your balance. Drawn at
true tier through the estate's one level-truth module — the same one the market and the museum
use. Keyless, read-only, nothing signed.
— connect your keychain, or type an address —
The level law, enforced not labelled: every piece's tier is
checked against the collection's own getMeta at read time. A disagreement prints as a
GATE FAILURE on the card, never smoothed into a number that looks fine.
🎟 THE VOUCHER — prepay compute, metered fair
Prepay for compute work — models, vRAM, whatever the estate meters —
and watch every last drop of it itemized here. Top up from either chain, spend at metered
rates, and the estate's 10% tithe is always visible, never buried.
Two rails in, one A balance, receipts with the tithe line — the same
hash-chained ledger the till meters with, rendered live from the estate oracle
(skaists.buzz). Refusals read as sentences, not codes.
voucher_escrow semantics, live: balances DERIVED from a
hash-chained append-only event log (never stored), refuse-before-write enforced at the
engine, memo-native binding on the A rail (memo = meter key, no binding table), binding
table on the USDC rail, every deposit cites its tx. This panel is a read-only view over
that ledger via the estate oracle; the box owns the writes.
—
0.0000A—
A · Vaulta — gasless
send any amount of A to:
—
with this EXACT memo (the memo IS the binding —no memo, no credit, money lost):
—
USDC · Base — tiny gas
send USDC (Base) to:
—
credited at — A per USDC (rate cited below)
rate: —
no memo needed on this rail — your bound address credits you
spent total: 0.0000 Atopped up: 0.0000 Atithe in there: 0.0000 A(the estate's 10%, shown never buried)
itemized — every receipt, every line
—
—
🧾 THE RECEIPTS — every bill recomputed here
How this panel checks every bill — recomputed here, never trusted
the voucher panel above reads your balance live from the estate oracle; this panel
reads the estate's public spend-receipt record (SPEC-SPEND-RECEIPT-1, the same shape the b-meter
writes) and recomputes every bill in-page — price × burned = owed, summed from the line items,
never from a stored total. each receipt's verdict is drawn as a comb cell:
PENDING_ANCHOR = honey · PASSED = capped, sealed ⬡ · FAILED = the flag hue #c07f1c
(the validated failure colour — never a new red) · INCONCLUSIVE = nectar. verification carries
no keys: content hash, exact arithmetic and the forward-only chain are checked from the public
record alone. private receipts never appear here — visibility is storage law (§3a): only rows marked
public live in a public store. paste any receipt and the same auditor checks yours.
💳 FUND — buy USDC, land it on an address you hold
How the card checkout works — who holds what at each step
The one lane this wallet cannot forge itself: licensed fiat. The buy runs on
Meld's hosted checkout — it opens in its own tab; this page only builds the link.
No server of ours: no BNR endpoint sits in this lane; this wallet signs nothing and
stores nothing. Your address rides in the checkout URL (the fiat rail's law) and Meld sees
what any checkout sees. The key in the config below is PUBLIC
(a publishable Checkout key) — a secret key never touches a page, by Meld's law and ours.
Names welcome: type a .eth name (Basename or ENS-style) and the button resolves
it to its raw 0x address on Base's own resolver before anything launches — a keyless
read from your browser to public Base RPCs picked at random per lookup, so no single
operator profiles who funds what. Honest limit: whichever provider you land on can see
the lookup — your IP plus the name you asked about. Pasting a raw 0x address skips
resolution entirely — if you'd rather not be seen asking, that is a real choice.
The fiat funnel’s role — the estate sells, it never operates
the estate is a seller, not an operator: its Base address below is a bare
to on Peer's live escrow (EscrowV2 + OrchestratorV3 on Base) — it signs nothing, grants
no allowance, runs no relayer. a customer's fiat (Venmo & co.) settles as USDC straight
into it. the estate is never the LP — a third party holds the USDC and takes the fiat;
if the estate played LP its own USDC would just come home (a fiat receipt, not new money).
the 10% tithe rides the customer's intent itself as one referralFees entry — paid
inside Peer's settlement before the balance lands, no second transaction; when no referral
was attached, the split still happens as ONE estate-side exact-multi instruction (seller +
tithe in a single payment — the fallback, SPEC §receive). settlement finality is one vendor
signature until the estate's own witness set exists — priced as such, never hidden.
the receive call is keyless: USDC Transfer logs from the orchestrator, public Base RPC picked at random — the page only reads.
the intent shape — tithe attached at signal time
the customer's signalIntent carries the split itself (≤10 referral
recipients, ≤50%, paid from the release before the net lands — ReferralFeeLib, read at source):
to: 0x89881F83…d7C6 ← the estate, bare recipient
referralFees: [ { recipient: 0x8fD7252A29FB759755E30A15E966932EaAD91b75,
basisPoints: 1000 } ] ← the 10% law, one entry
the recipient is the founder-filed tithe address (docs/dispatches/tithe-address.txt).
📡 ARWEAVE — publish & anchor, no middleman
The Arweave lane — built and signed inside this page
Another adapter on the wallet shell — balance, receive address, send, and
one new capability: PUBLISH. The transaction is built and signed in this page
with WebCrypto (format-2 data tx, RSA-PSS-SHA256, proven byte-equivalent to arweave-js),
posted to public gateways picked at random per call — no single operator learns who
anchors what. No bundler, no Turbo, no third-party UI (founder ruling): we dropped
the free tier to keep the rail first-party. The JWK lives in the vault — sealed
under your keypass, structurally verified before sealing, revealed only into the signing
call. Reads are keyless; the gateway sees what any Arweave read sees.
…
✍ COMPOSER — the BNR contract surface, no Unicove
What the composer shows you before anything is signed
Give it contract + action and it fetches the live ABI, renders
one field per argument, and shows you exactly what you will sign — action, authorization,
parsed args, signer, endpoint — before anything broadcasts. ABI-driven: the six bnames actions
and anything after work the same way. Mainnet signs with your bridged bzDiD key, zero paste;
the Jungle4 lane rehearses with a test key you paste (TESTNET-ONLY, memory-only). The Unicove
dependency is dead — this is ours, on the adapter contract: the worker builds, the vault signs,
the outbox persists, and nothing is called "sent" until the rail is read back.
the receipt ladder — every state is a first-class visual · the order is law
1
BUILDdone
the live ABI renders one field per argument — you see exactly what you will sign: action, authorization, parsed args, signer, endpoint.
2
SIGNdone
your derived bzDiD key signs in tab memory — zero paste. the signature is yours, the bytes are final.
3
PERSISTdone
the signed bytes land in the outbox BEFORE any network. persistence precedes submission — the order is law.
…
SUBMITSUBMITTED — awaiting read-back, not done
the stored bytes broadcast to the rail. a retry resubmits the identical bytes — it never re-signs, never rebuilds. submitted is NOT done.
✓
CONFIRMCONFIRMED — read back from the rail
a block read says so, or nothing does. the receipt names what was read — only the read-back earns the terminal look.
FIELDS — from the live ABI
EXACTLY WHAT YOU ARE SIGNING
📤 OUTBOX — signed bytes persist here BEFORE they submit
The order is law: build → sign → persist → submit → confirm by reading the
rail. A retry resubmits the identical stored bytes — it never re-signs, never rebuilds.
Nothing shows "sent" until a block read says so; the receipt names what was read.
🗺 CHAIN MATRIX — the sixteen rails, from data
Every rail, one row each — how it is read and signed
Every rail the wallet will ever owe you, one row each: how it's read
(first-party path first), how it's signed (custody tier), and tonight's honest state.
Rendered from the data block below the fold — never typed prose — and every count you see is
computed from it at render. The doctrine: PROTOCOL paths may be core, SERVICE degrades
gracefully, gaps say they are gaps.