Skip to content

feat: sovereign-mode direct contract writes (CPL-267 Phase 1)#310

Merged
GTC6244 merged 2 commits into
nextfrom
feature/cpl-267-self-sovereign-mode
Apr 22, 2026
Merged

feat: sovereign-mode direct contract writes (CPL-267 Phase 1)#310
GTC6244 merged 2 commits into
nextfrom
feature/cpl-267-self-sovereign-mode

Conversation

@GTC6244
Copy link
Copy Markdown
Contributor

@GTC6244 GTC6244 commented Apr 21, 2026

Summary

Wires the dashboard for direct AccountConfig writes from the user's own wallet when sovereign mode is enabled, preserving the existing API-server path for everyone else. Phase 1 of CPL-267 per the CEO plan (plan-eng-review cleared).

What ships in this PR:

  • Full admin-write ABI bundle (16 write fns + 17 custom errors, ABI version pinned)
  • ABI drift hard-block via keccak-hashed runtime bytecode per (chainId, contractAddress)
  • Tx lifecycle state machine: preparing → previewing → signing → pending → confirming → confirmed | failed | reorged
  • Revert decoder: Error(string)Panic(uint256) → custom errors → hex fallback; walks the ethers v6 nested error graph
  • Wallet connect (EOA, EIP-3326 chain switch + EIP-3085 add fallback, accountsChanged / chainChanged listener lifecycle)
  • Required preview+confirm modal before every wallet pop, decoded calldata + arg labels from the full ABI
  • 14 SDK write methods branched on mode === 'sovereign'; usage API keys generated client-side (contract only stores hash)
  • Dashboard getClient() Proxy auto-injects the sovereign lifecycle, zero call-site changes in groups.js / actions.js / wallets.js / keys.js

Deferred to Phase 1 follow-ups (intentional, per plan):

  • WalletConnect v2 / Safe Transaction Service integration
  • Playwright + Synpress E2E harness for the 15+ writes
  • Live-stack validation against real AccountConfig

Out of scope (Phase 2+):

  • newAccount as direct contract write
  • Hybrid createWallet with server-prepared key + registerWalletDerivation
  • One-way API → sovereign account conversion

Test plan

  • Node-level smoke passed locally (ABI load, lifecycle states, revert decoding standard + custom + nested + hex fallback, Proxy auto-inject on writes only, runContractWrite state transitions on success/failure/cancel)
  • Load dashboard in browser, flip sovereign toggle, confirm reads still work (Phase 0 path)
  • Create a group in sovereign mode against local_test.sh stack + MetaMask — preview modal shows, wallet pops, tx confirms, group lists
  • Delete a group in sovereign mode — same flow
  • Revert path: attempt a write with a non-master wallet, confirm NotMasterAccount(…) decodes in the error banner
  • Chain-switch path: connect wallet on wrong chain, confirm switch prompt fires and succeeds

🤖 Generated with Claude Code

Wires the dashboard for direct AccountConfig writes from the user's own
wallet when sovereign mode is enabled, preserving the existing API path
for everyone else.

- Full admin-write ABI bundle + 17 custom errors, ABI drift detection
  via pinned bytecode hash per (chainId, contractAddress)
- Tx lifecycle state machine: preparing → previewing → signing → pending
  → confirming → confirmed | failed | reorged; revert decoder chains
  Error(string) → Panic → custom errors → hex fallback and walks the
  ethers v6 nested error graph
- Wallet connect helpers: EOA, EIP-3326 chain switch with EIP-3085 add
  fallback, accountsChanged / chainChanged listener lifecycle
- Required preview+confirm modal before every wallet pop
- 14 SDK write methods branched for sovereign mode; usage API keys are
  generated client-side (contract only stores hash)
- Dashboard auto-injects the sovereign lifecycle via Proxy so existing
  call sites need zero changes

Deferred to Phase 1 follow-ups: WalletConnect v2 / Safe integration,
Playwright + Synpress E2E harness, live-stack validation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “sovereign mode” plumbing to the static dashboard + JS SDK so reads can go directly to the AccountConfig contract over RPC and writes can be executed as wallet-signed contract calls with a UI lifecycle (preview → sign → pending/confirming → terminal) and revert decoding.

Changes:

  • Introduces wallet connect helpers, tx lifecycle state machine, and a tx preview/confirm modal for wallet-signed writes.
  • Extends LitNodeSimpleApiClient with mode: 'api'|'sovereign', RPC/contract wiring, ABI drift pinning hooks, and sovereign read/write method branches.
  • Adds AccountConfig ABI bundles (view subset + full write/errors) and updates the dashboard login UI to toggle modes and preload ethers.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
lit-static/wallet_connect.js New EOA wallet-connect + chain switching + listener lifecycle helpers for sovereign mode.
lit-static/tx_lifecycle.js New tx lifecycle runner with state callbacks and revert-data decoding (standard + custom errors).
lit-static/dapps/dashboard/tx_preview_modal.js New required preview+confirm modal that blocks before opening the wallet popup.
lit-static/dapps/dashboard/index.html Loads ethers v6 UMD and adds a sovereign-mode toggle + updated login hint text.
lit-static/dapps/dashboard/auth.js Adds mode persistence + wraps SDK client calls with a Proxy to auto-inject sovereign lifecycle for write methods.
lit-static/core_sdk.js Adds sovereign-mode RPC read path + wallet-signed write path with ABI drift checking and lazy ethers loading.
lit-static/account_config_view_abi.js Adds view-only ABI subset for sovereign reads.
lit-static/account_config_full_abi.js Adds full ABI bundle (views+writes+custom errors) + ABI version and deployment pinning map.
TODOS.md Adds CPL-267 follow-up tasks (cache invalidation, GC, docs, billing notes, etc.).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lit-static/dapps/dashboard/auth.js
Comment thread lit-static/dapps/dashboard/tx_preview_modal.js
Comment thread lit-static/core_sdk.js Outdated
Comment thread lit-static/core_sdk.js Outdated
Comment thread lit-static/dapps/dashboard/index.html Outdated
Comment thread lit-static/account_config_full_abi.js Outdated
Comment thread lit-static/wallet_connect.js
- auth.js ensureSovereignSigner: recreate signer after switchChain so
  ethers BrowserProvider doesn't sign against the pre-switch network
- tx_preview_modal.js: resolve promise on #modal-close-btn and overlay
  backdrop clicks so closing via X no longer hangs the write flow in
  PREVIEWING
- core_sdk.js listActions (sovereign): only treat groupId > 0 as
  in-group; match server semantics where groupId == 0 is account-level
- core_sdk.js module header: remove stale "writes still use HTTP until
  Phase 1" language; writes are now wallet-signed when a signer is
  connected
- index.html login hint: same stale-copy update
- account_config_full_abi.js: freeze empty ACCOUNT_CONFIG_DEPLOYMENTS
  and add isAbiDriftDevOverrideEnabled() so _verifyAbiIntegrity hard-
  blocks on unpinned deployments unless
  window.LIT_ACCOUNT_CONFIG_ALLOW_UNPINNED_DEPLOYMENTS is set
- wallet_connect.js switchChain: re-issue wallet_switchEthereumChain
  after wallet_addEthereumChain and assert final chainId matches
  target

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@GTC6244 GTC6244 merged commit 8f72dba into next Apr 22, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants