You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(walletbeat): add architecture fit & core-expansion map
Validate the code-fit layer from a four-cluster read of the actual
codebase: per-item crate placement, seam-vs-expansion, size, and risk,
plus an EIP-7702 spike brief.
Key findings:
- deckard-core already has the right seams (multi-account derivation,
reserved enclave flag, alloy/7702-ready builder-agnostic broadcast)
- Un-gating Send is UI-only (daemon path tested) and the dependency hub
- deckard-contract (frozen) is the higher-ceremony expansion point;
batch RevokeApproval/Intent::Batch/session-token changes together
- Re-tier #13 RPC-before-first-request UP to L (provider spawns with
DEFAULT_RPC before the auth gate); re-tier #8/#9 multi-identity DOWN
(core already derives accounts)
Reworks the sequencing tiers with the measured sizes.
Copy file name to clipboardExpand all lines: docs/WALLETBEAT-COMPATIBILITY.md
+86-16Lines changed: 86 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -106,7 +106,7 @@ plus #26/#27 (account abstraction / batching) gated behind a 7702 spike. We opti
106
106
107
107
| # | Attribute | What Walletbeat wants (PASS) | Deckard now | Requirement to pass |
108
108
|---|---|---|---|---|
109
-
| 13 |**L1 provider independence**| Self-hosted node configurable **before any request hits a default RPC**; all basic ops work through it |**PARTIAL→PASS-able** — RPC is overridable (`eth.rs`, `settings.rs`); Helios verifies against the user endpoint | Ensure a **custom RPC can be set during onboarding before the first request**to clear the strict `YES_BEFORE_ANY_REQUEST` bar. Small, high-value change.|
109
+
| 13 |**L1 provider independence**| Self-hosted node configurable **before any request hits a default RPC**; all basic ops work through it |**PARTIAL — bar not yet met** — RPC overridable (`eth.rs`, `settings.rs`) but the provider spawns with `DEFAULT_RPC` at `Shell::new()`*before* the auth gate; custom RPC only applies on settings-blur, so the first read hits the default unless `DECKARD_RPC_URL` is set | Add an **onboarding RPC step or lazy provider spawn**so a custom RPC binds before the first request (`YES_BEFORE_ANY_REQUEST`). **Re-tiered to `L` (app-flow change), not a quick win (2026-06-14).**|
110
110
| 14 |**Account portability**| Standards-compliant **BIP-39 + BIP-32 + BIP-44** with exportable seed/key |**PASS** — BIP-39 keystore, hold-to-reveal seed export (`keystore.rs`, `DESIGN.md`) | Maintain. Confirm full BIP-32/44 derivation path is standard and documented. |
111
111
| 15 |**Transaction inclusion** (censorship resistance) | Withdraw L2 funds to L1 without intermediaries (force-withdraw); mempool independence |**OUT OF SCOPE (2026-06-14)** — L1-focused, no L2 force-exit |**Deliberately out of scope for v0** (no L2 roadmap yet). Stage-2 item; revisit if/when L2s are supported via **permissionless L2→L1 withdrawal**. |
112
112
| 16 |**Chain verification**| Verify integrity of the Ethereum chain (light client) |**PASS** — **Helios** light-client verified reads with a Verified/Unsynced badge (`helios.rs`, `shell_chrome.rs`) | Maintain. A standout strength most wallets fail. |
@@ -134,28 +134,98 @@ plus #26/#27 (account abstraction / batching) gated behind a 7702 spike. We opti
134
134
135
135
---
136
136
137
+
## Architecture fit & core-expansion map
138
+
139
+
Validates the **code-fit layer**: where each item lands in the crate boundary, whether the seam already
140
+
exists or the engine must be **expanded**, rough size, and risk. From a four-cluster read of the actual
141
+
code (2026-06-14). Altitude only — no line-level diffs. This is the answer to "did we read our own
142
+
infra correctly, and does the core need expanding?"
143
+
144
+
**Headline: `deckard-core` was built with the right seams.** Most items need *new typed surfaces*, not
145
+
*new crypto* — multi-account derivation already exists, the keystore header already reserves an
146
+
enclave/biometric flag, the shield builder is key-less (reusable for simulate), and the signerd
147
+
broadcast path is alloy/7702-ready and builder-agnostic. Two findings correct the first survey:
148
+
149
+
-**Re-tiered UP — #13 "custom RPC before first request" is NOT a quick win (now L).** The provider is
150
+
spawned at `Shell::new()` with `DEFAULT_RPC`*before the auth gate*; a custom RPC only applies on
151
+
settings-blur, so the first read after unlock hits the default RPC unless `DECKARD_RPC_URL` is set.
152
+
Passing the literal bar needs an onboarding RPC step or lazy provider spawn (an app-flow change).
153
+
-**Re-tiered DOWN — #8/#9 multi-identity is cheaper (no core crypto).**`deckard-core` already derives
154
+
any account (`account_signer(index)`/`account_address(index)`, Railgun per-index too); the daemon
155
+
hard-wires index 0. It's a daemon `active_account` + a `SelectAccount` wire request + a switcher UI.
|**#2** simulate + scam warnings | core + app (+contract maybe) |**Expansion** — key-less `simulate_intent` (eth_call) app-side; heuristic address checks | L | high — racy + detection is heuristic, not cryptographic; UX must be honest |
162
+
|**#18** approvals viewer + revoke | core + app + contract + signerd | Partial (`PendingPayloadView::Approve` exists); **expansion** — `enumerate_approvals` + likely new `IntentKind::RevokeApproval`| M | med — ERC-20 has no `allApprovals`; curated-spender list is fast but incomplete |
163
+
|**#5** enclave / Touch ID unlock | core + app |**Seam reserved** (keystore header `flags` bit); **expansion** — pluggable `UnlockBackend` (passphrase-only today); enclave wraps the DEK, not the secp256k1 key | M | med — secret-handling edge |
164
+
|**#7** idle auto-lock | signerd + app |**Seam exists** — add TTL to daemon + app keepalive | S | low — pure state |
165
+
|**#8/#9** multi-identity | signerd + contract + app (**core ready**) | Core seam exists; expansion in daemon (`active_account`) + `SelectAccount` wire request + UI | L | med-low — no new secrets (index is public) |
166
+
|**#13** RPC-before-first-request | app + core | Partial (respawn-on-blur); **expansion** — onboarding RPC step or lazy provider spawn |**L**| high — currently **not met** (first read hits `DEFAULT_RPC`) |
167
+
|**#24** ENS forward resolve | core + app |**Seam exists** but isolated to the watch-address field; surface in Send/Receive | M | low |
168
+
|**#24** ENS reverse + verified badge | core + app + contract |**No seam** — no `ReverseResolveName`; name results aren't wrapped in `Read<>` for the badge | M | low-med |
169
+
|**#26** EIP-7702 on-chain policy | signerd + core (+app); contract can stay policy-blind |**Seam** (alloy `TransactionBuilder7702`, builder-agnostic broadcast); **expansion** — session-key derivation + `broadcast_7702`| L (spike) | med — new on-chain delegation trust surface |
11.**External security audit + funded bug bounty** (#1, and Stage-2 bug bounty) — *the* highest-leverage item. **Decision spike — budget/vendor undecided (2026-06-14); not yet an actionable issue.**
157
-
12.**EIP-7702 spike** (#26) → if adopted, unlocks **atomic batching** (#27) and on-chain scoped agent permissions. **Research-spike first** (weigh the delegation-contract trust surface).
158
-
13.**Per-agent isolation** (#11) → scope each agent/session in the policy gate (the agent-paradigm analog of app isolation).
226
+
12.**External security audit + funded bug bounty** (#1, and Stage-2 bug bounty) — *the* highest-leverage item. **Decision spike — budget/vendor undecided (2026-06-14); not yet an actionable issue.**
227
+
13.**EIP-7702 spike** (#26, ~4–6 dev-days) → if adopted, unlocks **atomic batching** (#27) and on-chain scoped agent permissions. See the spike brief above. Batch its wire-contract changes with #18/#27/#11.
228
+
14.**Per-agent isolation** (#11, `M`) → session-token in the wire contract; policy is global/immutable today.
159
229
160
230
### Out of scope / deferred for v0 (decided 2026-06-14 — acknowledge, don't chase)
0 commit comments