Skip to content

Onboarding: register master device on-chain (un-stub chain_tx_hash) + local HEI subsidy — last gap to a self-contained web memory demo #196

@hanwencheng

Description

@hanwencheng

Goal

Fold the master device on-chain registration into the web onboarding flow so that every master, on login, gets its K10 device registered on SidecarRegistry with the CAP_MINT role — and un-stub chain_tx_hash. After this, login → (register happens) → the existing memory plant button works end-to-end with no manual bootstrap.

Builds on (merge first): #191 (daemon real memory chain) + #195 (master-self scope skip). With both merged, on-chain master-device registration is the only remaining gap to a live web plant→S3 demo.

Why it's required (irreducible — it is NOT the scope check #195 removed)

Real cap-mint has two separate on-chain checks; #195 only removed the scope one:

Both read the on-chain device by device_key_hash. No on-chain device → rejected at both layers. So the master device MUST be registered on-chain for real memory/credential ops. #195 removed the scope requirement (operator==actor skip); it did not remove the device requirement — they're different checks.

The one open design decision: msg.sender / key custody

registerFirstMasterDevice sets operatorMasterWallet[omni] = msg.sender. Under the W1 managed-wallet model the daemon does not hold the master's EVM key (the signer derives K4 = HKDF(K3, O_master)), so msg.sender is ambiguous:

  • (α) old-model / dev — RECOMMENDED for this issue. OPERATOR_KEY_FILE is msg.sender (exactly what scripts/heima-register-first-master.sh + the wire demo do). Works today. operatorMasterWallet[omni] = a local key, not the managed wallet — fine for cap-mint (which checks the device, not msg.sender); the divergence only matters for future master mutations (scope grants check msg.sender == operatorMasterWallet).
  • (β) managed-wallet. The signer signs the tx — but its surface is /sign/siwe-style payloads, not arbitrary EVM txs; likely needs new signer work.
  • (γ) ERC-4337 (clean end-state). This is W2 / chain-plan E7 — currently cutover-blocked (the thinned account-auth registry isn't deployed to mainnet). Out of scope here; this issue is the old-model CLI interim path.

Point-1 subsidy (folded in — local, NOT broker)

The register tx needs gas. Add a local operator-run script scripts/heima-fund-master.sh: deployer → master account, ~0.2 HEI, idempotent (skip if balance ≥ threshold). Deliberately NOT a broker endpoint and NOT auto-on-login — broker auto-funding every login is a Sybil drain on the deployer. The operator runs it once.

device_key_hash plumbing

The daemon must register its own K10 (the same hash cap-mint will send) — see docs/plan/web-flow/w3-real-memory.md §3.5. #191 added --master-device-key-hash as an explicit stopgap; this issue should make the daemon register + use its own K10 consistently (derive the hash from the daemon's K10, register that, cap-mint with that).

Implementation pointers

  • The stub to replace: crates/agentkeys-daemon/src/ui_bridge.rs — the K11-finish handler's chain_tx_hash TODO (search chain_tx_hash / register_master_device; currently returns None).
  • Onboarding flow: ui_bridge.rs onboarding_session + GET /v1/onboarding/state (extend to report chain: master-registered).
  • Shell-out pattern (sanctioned): wire-real-paths.md §4.2 — the daemon master plane shells out to scripts/heima-*.sh. Use scripts/heima-register-first-master.sh (old-model cast).
  • Plans: docs/plan/web-flow/wire-real-paths.md (W2 = §6), docs/plan/web-flow/w3-real-memory.md (§3.5 device-key constraint, §4 bootstrap), docs/plan/chain/erc4337-master-account.md (E7 — the clean end-state + why cutover-blocked).

Acceptance

Out of scope

  • ERC-4337 web-native register (W2/E7) — cutover-blocked; the eventual clean replacement for the old-model shell-out here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions