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
Adopt an ERC-4337 P-256 smart-account as the master, instead of the EOA msg.sender-bound model. The account's validateUserOp verifies a P-256 (K11/passkey) signature; a bundler broadcasts UserOps and an optional paymaster sponsors gas. SidecarRegistry.master becomes the smart-account address.
This supersedes the §11 fork-A-as-MVP framing in #162 and is driven by the adversarial security review (docs/plan/web-flow/wire-real-paths-security-review.md, codex 2026-06-02).
Why (what it resolves)
Removes the software-secp256k1 root [HIGH]. Every client (phone / browser / desktop) signs UserOps with the SE-sealed K11/P-256 passkey only — no exportable secp256k1 key on any device. The hardware-sealed promise in arch.md §6/§10 actually holds.
Key-free + relayer in one. Bundler broadcasts + paymaster pays gas → no HEI on device and no custodial relayer (the only relayer that worked under the EOA model). Confirms the relayer analysis: EIP-2771 only sponsors gas (still needs the secp key); ERC-4337/P-256 is what makes the phone key-free.
Multi-device + recovery [HIGH]. The account address is the stable master (survives device swaps); the account natively supports multiple authorized passkeys + quorum / social recovery, fixing the single global operatorMasterWallet.
Reuses existing crypto — AgentKeys already verifies P-256 on chain (crates/agentkeys-chain/src/K11Verifier.sol + its P256 verifier); the account's validation reuses it.
Still required — ERC-4337 does NOT auto-fix these (the residual codex findings)
[CRITICAL] Authenticated first-master bootstrap.registerFirstMasterDevice is unauthenticated first-call-wins → front-runnable operator lockout (SidecarRegistry.sol:100-123). Registering the smart-account as master still needs an on-chain authorization proof.
[HIGH] Full-intent binding in validateUserOp. The signed UserOp (and any K11 challenge) must commit the entire intent — op + target omni + scope bits + device hash + contract + chainId + nonce + expiry — so a bundler/MITM cannot substitute args. Today the add-master K11 challenge omits fields (SidecarRegistry.sol:167-193).
[HIGH] Route agent bind/revoke through the account so they inherit passkey gating (today registerAgentDevice/revokeAgentDevice are msg.sender-only, no K11 — SidecarRegistry.sol:214-251).
[MEDIUM] Replay/clone: rely on the EntryPoint nonce; reconcile AgentKeysScope signCount (it never updates lastSignCount today — AgentKeysScope.sol:211-237).
Heima infra
Deploy an ERC-4337 EntryPoint on Heima.
P-256 verify is a gas-heavy Solidity verifier — Heima is London-level EVM (no RIP-7212 P-256 precompile, no PUSH0 per CLAUDE.md). The account + EntryPoint must avoid post-London opcodes (evm_version = "london").
Bundler (+ optional paymaster) infra / endpoint.
Account factory + the migration path for SidecarRegistry.operatorMasterWallet → smart-account address.
Acceptance criteria
A phone with no secp256k1 key completes master onboarding + a scope grant by passkey-signing UserOps; a bundler lands the txs; isServiceInScope(...) == true.
First-master bootstrap cannot be front-run (authorization proof verified on chain).
A bundler/MITM cannot alter a UserOp's effect (full-intent binding holds under a substitution test).
A second device's passkey can be added + a lost device revoked via the account's multi-signer / quorum path.
Decision (2026-06-02)
Adopt an ERC-4337 P-256 smart-account as the master, instead of the EOA
msg.sender-bound model. The account'svalidateUserOpverifies a P-256 (K11/passkey) signature; a bundler broadcasts UserOps and an optional paymaster sponsors gas.SidecarRegistry.masterbecomes the smart-account address.This supersedes the §11 fork-A-as-MVP framing in #162 and is driven by the adversarial security review (
docs/plan/web-flow/wire-real-paths-security-review.md, codex 2026-06-02).Why (what it resolves)
operatorMasterWallet.crates/agentkeys-chain/src/K11Verifier.sol+ its P256 verifier); the account's validation reuses it.Still required — ERC-4337 does NOT auto-fix these (the residual codex findings)
registerFirstMasterDeviceis unauthenticated first-call-wins → front-runnable operator lockout (SidecarRegistry.sol:100-123). Registering the smart-account as master still needs an on-chain authorization proof.validateUserOp. The signed UserOp (and any K11 challenge) must commit the entire intent — op + target omni + scope bits + device hash + contract + chainId + nonce + expiry — so a bundler/MITM cannot substitute args. Today the add-master K11 challenge omits fields (SidecarRegistry.sol:167-193).registerAgentDevice/revokeAgentDevicearemsg.sender-only, no K11 —SidecarRegistry.sol:214-251).AgentKeysScopesignCount (it never updateslastSignCounttoday —AgentKeysScope.sol:211-237).Heima infra
CLAUDE.md). The account + EntryPoint must avoid post-London opcodes (evm_version = "london").SidecarRegistry.operatorMasterWallet→ smart-account address.Acceptance criteria
isServiceInScope(...) == true.Relationships
docs/plan/web-flow/wire-real-paths.md§11 (decision block) +wire-real-paths-security-review.md.crates/agentkeys-chain/src/{SidecarRegistry,AgentKeysScope,K11Verifier}.sol.