on Robinhood Chain · testnet

Docs · 06 / 07 · Privacy guide

No funding link. Keep it that way.

Unlinked removes one leak: the transaction that funds a fresh address from your main wallet. Everything else is up to how you use the address. This page lists what can still link it to you and what to do about each.

Threat model#

An observer reads the public ledger. The one thing Unlinked removes from it is the funding transaction: a fresh address never needs ETH, so nothing ever connects it to the wallet that would have paid for its gas.

Clear · the funding linkFunding a fresh address from your main wallet writes the link on the public ledger. Anyone can read it, forever.

Sealed · no funding txA proof of work pays instead. The main wallet stays public but is never connected: there is no link to read.

No funding transaction. Never sent. The fresh address stands alone.

0ETH · never funded
Example addresses. The fresh address holds 0 ETH before and after its first op, and nothing links it to the main wallet.

Do and don't#

  • Do create a fresh key for each identity, in a browser profile you don't use with your main wallet.
  • Do export the key (or save it encrypted) before closing the tab, and burn the identity when you are done.
  • Don't connect your main wallet in the same session. The app never asks you to.
  • Don't send ETH or tokens to the fresh address from your main wallet, and don't send them straight back. Either recreates the link Unlinked removes.
  • Don't use a unique amount. Round, common amounts blend in; 1,337.42 doesn't.
  • Do use Tor, or your own relay, if the relay operator seeing your IP address matters to you.

What leaks where#

What can leak, and what the stack does about it
LeakMitigation
IP address at the relayOne relay for everyone, no IP or body logs, zero retention. Use Tor, or run your own relay.
IP address at the chain RPCReads keyed to your address go only to the relay, and only when you ask. The chain RPC gets address-free reads.
EntryPoint nonce keyAlways key 0. viem's default key embeds Date.now(), your clock to the millisecond, on-chain; the relay rejects it.
Timing on-chainRelay-held delay (pow_sendUserOperation) and optional batch windows. Wait several epochs after funding a stealth address.
Timing and hashrate at the relayNo estimation call; the epoch is polled on a fixed interval, and any relay read a send must make first (a refetch after waiting for the next epoch, a resync) is followed by a random pause before mining.
PoW nonce patternsEach mining chunk starts at a random nonce.
Gas and fee fingerprintGas limits from fixed per-template profiles, fees from the epoch: every op of one template in one epoch looks the same, except PVG, shared per 30 s quote.
DelegateEveryone shares one delegate, Simple7702Account v0.9, enforced on-chain.
Authorization nonceVisible on-chain; a fresh key has 0. An imported key with history is already linkable by that history.
BrowserNever connect your main wallet. Burn the identity when done. A separate browser profile helps.
AmountsAvoid unique amounts and round trips back to your main wallet.

Reads keyed to your address#

A balance or nonce read tells whoever answers it that someone at your IP cares about that address. So:

  • The app sends every address-keyed read (pow_getAccountState) to the relay, which already sees your sends, and only when you import a key, press Refresh, or after a failed send (one read to resync the nonces). Nothing is polled.
  • A fresh key needs no read at all: its state is known locally (freshAccountState), and confirmed ops advance it.
  • The chain RPC only receives public, address-free reads: epoch parameters, stats and logs.
  • The epoch is polled on a fixed 60-second interval. A send normally mines from the last poll, so no read precedes mining. When the SDK must read the relay itself first (it waited for the next epoch and refetches it, its own first fetch without a shared poller, or a resync after a failure), it waits a random time (up to 20 s, less near the end of an epoch) before mining, so the relay can't time your mining from that read.

Relay-held delay#

pow_sendUserOperation asks the relay to hold your op for up to the epoch's remaining window before forwarding it, so its time on-chain is not the time you mined it. In the app: Privacy options → Relay-held delay. In the SDK: delaySec.

Exposure states#

Resolution is exposure. Everything Unlinked shows is in one of three states, always drawn as a glyph and a word, never by colour alone: crisp cells anyone can read, a seeded mosaic that only the owner can lift, and a notched seal for what never exists or is never shown.

Exposure states: resolution is exposure
StateMeansUsed forHow to lift it
ClearAnyone can read it.Transaction and userOp hashes, blocks, epochs, explorer links, “0 ETH · never funded”, gas paid, work in bits, and the review table before you send.Nothing to lift: it is public.
MosaicWithheld from anyone looking at the screen. The owner can lift it.In the app: your address, balances, amounts and counterparties. On /stats: the senders of sponsored ops (public on-chain, not displayed).Press and hold, or press Space or Enter on the Hold button. It reseals when you let go, change screens, switch windows or hide the tab. Private view off shows values in full after a confirm.
SealedNever exists, or is never shown.The funding transaction (never sent). Your private key: Copy without display, or Show once for 10 s.It can't be lifted: there is nothing behind it, or it leaves only through Copy or Show once.
Example values · not an account
3px cells text under 15px
Example address: 0x9c4e2b7fd01e88a0…a041 (hidden on screen)
6px cells text from 15 to 35px
Example address: 0x9c4e2b7fd01e88a0…a041 (hidden on screen)
12px cells Doto numerals
Example balance: 1,204 (hidden on screen)mNVDA
Sealed never sent
No funding tx · never sent
Sealed the private key
Private key · sealed
Masks are seeded noise, never a downsampled copy of the value: pixelated text can be recovered; noise cannot. Widths are fixed per value class, so length never leaks.

Revealing is always your act, and always brief: nothing lifts on hover or focus, copying never reveals, and every value reseals when you let go, change screens, switch windows or hide the tab. The mosaic hides values from people looking at your screen; it does not hide anything on-chain. What is on-chain is public, which is why the funding link is sealed rather than masked: it is never written at all.

Nonce key 0#

Standard ERC-4337 tooling (including viem's default) puts Date.now() in the EntryPoint nonce key, which publishes your clock, to the millisecond, on-chain. The SDK always uses key 0 and the relay rejects any other key.

Fingerprints#

Gas limits come from fixed per-template profiles and fees from the epoch, so every op of one template in one epoch is identical apart from the shared PVG quote. Everyone delegates to the same Simple7702Account v0.9. The miner starts each chunk at a random nonce, so solutions reveal nothing about your device.

The browser#

The key is generated in the tab and held in memory. Encrypted persistence is optional: AES-GCM under a key derived from your passphrase (PBKDF2-SHA256, 600,000 iterations), stored in IndexedDB without the address in the clear. Burn identity erases the key, the saved copy and the session's activity.