Skip to main content

A Wallet Should Check Its Own Account

Robert Mao
BlockchainSecurityVerifiability

If a wallet keeps your private key safe, can you trust the balance on its screen?

The previous article covered how we are bringing Passkeys into account and authorization design. Here is the next question: a wallet should be able to check its own account, rather than simply display whatever number a server returns.

That is one of the principles behind our next-generation wallet. It performs lightweight verification of transactions relevant to its owner, and manages its own records with a verifiable ledger. Checking data deserves a place alongside protecting keys.

The product is still undergoing internal engineering validation and has not been publicly released. The local verifiable ledger has an implementation. Automatically obtaining on-chain proofs for incoming transfers and checking independent sources are still being integrated and tested. This article explains why we are taking this approach and what verification needs to establish.

Checking your statement should not require running the bank

When you check a bank statement, you want to know whether your money arrived, whether you were overcharged, and whether you recognize a purchase. You do not bring home every customer's transactions and recalculate the entire bank's books.

A wallet can work within a similar scope. Checking its owner's transactions and account usually does not require a phone to re-execute every transaction on the network. Blockchain data may be public, but the owner's needs do not require auditing everybody else's business. The bank analogy describes the scope of the check; the wallet also needs cryptographic evidence for the data it receives.

An unfamiliar credit-card charge can prompt a dispute and an investigation. That ability to question an entry is worth borrowing: a line on a statement should stand up to scrutiny. Banks, merchants, and card networks handle investigations and refunds under their own rules. On-chain transactions follow their respective protocols after finality. A wallet can reject untrustworthy data and explain an inconsistency; detecting one does not let it reverse a finalized transfer.

I want users to have a wallet that can check the account.

What would prove that a transfer arrived?

Many wallets query a remote node for balances and transactions through RPC. RPC is a way to make a call, and it can still carry the data. The important question is how the wallet evaluates the response.

Suppose a server says, “You received a transfer.” A wallet that just displays the amount relies on the server's description. A verifying wallet asks for more: what are the original transaction bytes? Which authenticated ledger state contains them? What evidence connects the two?

One common approach is to return a Merkle inclusion proof with the transaction. Think of it as a short checking path. The wallet uses the transaction and that path to calculate a digest, then compares it with an authenticated ledger digest. Changing the recipient or amount should break that match. Ethereum's light-client documentation describes the general idea of checking proofs with less data; each chain has its own protocol and security assumptions.[1]

“Authenticated” matters. A malicious server can invent a transaction, construct a tree around it, and sign its own tree. The wallet needs an established trust anchor and must check signatures, validator sets, or finality evidence according to the target chain's rules before accepting the digest.

The proof must connect to an authenticated ledger commitment. A bundle of data that looks like a proof is not enough.

In this design, the wallet is a lightweight node that checks evidence locally. It still needs the network for data and depends on the target chain's consensus and trust assumptions. Its job is to verify information relevant to its own account, without ordering transactions for the whole network.

There is another trap. Proving that one transfer exists answers only that question. A server could hide a separate outgoing transfer or keep returning yesterday's genuine ledger. The proof could be valid while the displayed balance is out of date.

Transaction inclusion, account-history completeness, and state freshness therefore need separate checks. Retaining a verified checkpoint can reveal a return to older history. Learning whether the network has advanced requires access to newer authenticated state, together with the chain's appropriate proof mechanism or independent sources. Several URLs backed by the same server do not provide several independent sources.

This is part of the work still being integrated for incoming transfers. A working proof verifier alone cannot justify claiming that the wallet detects every omission.

The records on your phone need checking too

The remote node is one layer. Local records are another.

A wallet also keeps track of application authorizations, signing operations, and account changes. Those records pass through backups, restores, and device synchronization. Reliable network data cannot fix a damaged local history or a missing segment from a sync.

We use an isomorphic verifiable ledger in the wallet: the local wallet uses the same kind of verifiable ledger structure as the chain side.

An ordinary database is good at storing and querying current values, and can be paired with auditing mechanisms. We want the wallet's history to participate directly in verification. Changes become appended events. Each event connects to the preceding digest, while Merkle digests and signed checkpoints commit to a stretch of history. A checkpoint is like a signed closing entry at a particular position in the books.

During recovery, the wallet checks these connections and signatures again, replays events under the same rules, and compares the resulting state with the saved result. An authorization then has a traceable history. A backup service can store the data while the wallet checks what it retrieves.

Both the chain side and the wallet side use explicit records, digests, and verification rules for their history. Verifiability should reach the user's device too.

Every check has a starting point. If the entire local history, checkpoints, and record of the latest position are replaced together with a complete older backup, the old signatures may still verify. In principle, detecting that rollback requires a trusted reference that was not rolled back with it, such as a newer checkpoint retained by another device or an externally verifiable commitment. A hash chain helps expose inconsistent history; it cannot discover a future it has never seen.[2]

Likewise, an attacker controlling an authorized signing key may create new records with valid signatures. Ledger integrity checks need to work together with key protection, authorization limits, and recovery design.

From protecting the key to checking the account

Passkeys address authentication and credential protection. Transaction verification checks evidence from a server. The local ledger checks the history a wallet saves and restores. These problems occur in different places, and each needs attention.

For the user, the result should be concrete. A wallet should be able to explain what it checked about a transfer. It should check continuity when restoring records. When the data does not add up, it should explain the discrepancy rather than keep displaying a reassuring number.

I do not want people to learn how to maintain a full node just to check their own account. Checking a bank statement should not require running the bank. A wallet should make that same distinction work: perform the checks on the device, and give the owner a result they can understand.

References

[1] Ethereum.org: Light clients. Background on light-client verification; this does not establish that our wallet uses Ethereum's protocol.

[2] Laurie et al.: RFC 9162: Certificate Transparency Version 2.0, sections 2.1.3 and 2.1.4 distinguish inclusion and consistency proofs. The RFC describes certificate-transparency logs; the reference here concerns verifiable-log concepts.