The trust boundary between the signer and the wallet layer
nullroute is designed around two assurance tiers. One of them exists.
packages/wallet has not been written, phase 5 has not been opened, and the
verifier reports the literal signer, so there is nothing to distinguish and
the lock screen does not distinguish it. This section described the boundary in
the present tense, which is the wrong tense for a boundary with one side. What
follows is the design the phase ordering exists to protect, and INV-WALLET-1 is
enforced today by a lint rule in the direction that can be enforced without the
second package.
Tier 1, the signer (packages/core, packages/daemon, packages/ui) is
small on purpose. Every parser and every branch that runs near a private key is
a place where a bug becomes a loss. This tier is verified to the standard
described in VERIFICATION.md, and it is what a default build contains.
Tier 2, the wallet layer (packages/wallet) adds UTXO tracking, coin
control, and transaction construction. It roughly doubles the code on the
device, and most of that new code processes attacker-influenceable data: UTXO
snapshots, labels, and transaction history that arrived across the air gap from
a machine that is on the internet.
That is an acceptable trade only because the boundary is enforced rather than promised:
packages/walletmay import frompackages/core. Never the reverse. A lint rule enforces the direction and CI tests it. (INV-WALLET-1)- The wallet layer proposes transactions. It cannot sign them. Signing is reached only through the same review and confirmation path as an externally supplied PSBT, with no shortcut for self-constructed transactions. (INV-WALLET-2)
- Removing
packages/walletfrom the build yields a fully functional signer with no code changes anywhere else, and changes the manifest root hash so you can prove which one you are running. - Wallet-tier invariants are about correctness and clarity. Key-safety invariants live in core and hold regardless of what the wallet layer does.
If you want the smallest attack surface, run a default signer-only build and keep your wallet software on a separate machine.
Rendered from docs/THREAT-MODEL.md, the same bytes that ship with the code. SHA-256 d932f13db7fe836f45194ab98069c47dc556d4f29b2cfbf0ef1ab3bf7b334ffd