feat(cli)!: migrate to Sequence V3 OMSClient (email-login embedded wallet)#120
feat(cli)!: migrate to Sequence V3 OMSClient (email-login embedded wallet)#120AkshatGada wants to merge 15 commits into
Conversation
Phase 1 + core Phase 2 of the migration from @0xsequence/dapp-client
(delegated browser-approved sessions) to @0xsequence/typescript-sdk
(OMSClient embedded wallet, email login). Additive and flag-gated —
the legacy path is unchanged and remains the default.
New:
- lib/oms-storage.ts: encrypted file-backed StorageManager + persisted
EthereumPrivateKeyCredentialSigner key (survives process restarts).
- lib/oms-client.ts: getOmsClient(walletName) singleton.
- lib/oms-tx.ts: runOmsTx — drop-in for runDappClientTx; maps the
{to,data,value}[] interface onto oms.wallet.sendTransaction with ported
fee selection (prefer native or USDC, gated on availableRaw).
- lib/tx-dispatch.ts: runTx routes to OMS when POLYGON_AGENT_OMS is set.
- wallet login (email OTP) + wallet logout; list/address handle OMS pointers.
Changed:
- storage.ts: export GCM helpers; add OmsConfig/OmsWalletPointer + helpers
and bootstrapOmsConfig.
- All 17 runDappClientTx call sites now import runTx via the dispatch shim.
- utils.ts: getReadRpcUrl with public-RPC fallback (OMS has no nodes access key).
- x402-pay receipt poll uses getReadRpcUrl instead of session.projectAccessKey.
Verified end-to-end on Polygon mainnet: email login -> persisted session ->
call with POLYGON_AGENT_OMS=1 -> on-chain USDC transfer
(tx 0xb5e35f2f74fcdb75ccd453e23af4e0d3a88f60e383f00fb2e0e43cbf41613ba1).
… only path Completes the migration from the dapp-client delegated-session model (browser approval + relay + on-chain Sapient permission scoping) to the Sequence V3 OMSClient embedded-wallet model. OMS is now the only path. Removed: - packages/connector-ui (browser approval UI) + its deploy workflow - packages/shared (x25519/xchacha20 relay session crypto) - src/lib/dapp-client.ts, src/lib/relay-client.ts - wallet create/import (+ WalletCreateUI), AUTO_WHITELISTED_CONTRACTS, spending-limit / --contract scoping flags, relay storage helpers, bootstrapAccessKey, SequenceIndexer usage - 12 legacy @0xsequence/* + tweetnacl deps (pnpm: +95 -894 packages) Changed: - balances + balances Ink UI now read via oms.indexer (publishableKey auth); no more projectAccessKey - withdraw/x402 receipt polling uses getReadRpcUrl (public-RPC fallback) - all tx commands resolve wallets via loadOmsWalletPointer; chain defaults to polygon (OMS wallets are chain-agnostic) - tx-dispatch.runTx now wraps runOmsTx unconditionally - CLAUDE.md updated for the OMS-only structure Verified live on Polygon mainnet with no env flag: wallet login, balances via oms.indexer, and a USDC transfer via `call` (tx 0x1c7ff1df746bacab7930dc24ada694fa9061976164871ad3fb6bf3940eec2bdc).
Remove all references to the removed wallet create / browser approval / --contract scoping / connector-ui flow across SKILL.md files and README. Document wallet login (email OTP), setup --oms-* credentials, the call command, and the no-permission-scoping V3 model.
Drop the dead "re-create with wallet create --contract" notes and the
Sapient-era error handling ("No signer supported", session-permission
rejection) from deposit and withdraw — these referred to the removed
dapp-client permission-scoping model and can't occur on the OMS path.
Deposit/withdraw now submit through runOmsTx directly; OMS session
errors are handled in the primitive. Also fix the setup TTY hint to
point at `wallet login` instead of the removed `wallet create`.
| return Uint8Array.from(Buffer.from(decrypt(cipher), 'hex')); | ||
| } | ||
| const keyHex = Buffer.from(randomBytes(32)).toString('hex'); | ||
| fs.writeFileSync(file, JSON.stringify(encrypt(keyHex)), { mode: 0o600 }); |
Add a `wallet login-browser` subcommand that signs in with Google through the SDK's OIDC + PKCE redirect flow, using a short-lived localhost callback server. The resulting session persists identically to email login, so balances, tx and address resume with no re-login. The funding step is chained after a successful login (skip with --no-fund). - oidc-callback-server.ts: loopback server that captures the single callback URL - oms-client.ts: pass the mandatory redirectAuthStorage; SEQUENCE_OIDC_RELAY_URI override - oms-storage.ts: FileStorageManager subdir arg, isolating transient OIDC state - storage.ts: widen loginMethod to email|oidc|google; email now optional - operations.ts: extract showFunding so `fund` and post-login reuse one path This is the same-machine flow (browser and CLI co-located). Remote login over a relay is a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A small Cloudflare Worker + Durable Object that lets the CLI complete browser login from any machine, including a remote server where a localhost callback can't be reached. The browser is redirected to the relay with the OAuth code+state; the CLI polls for them and finishes the exchange itself. The PKCE verifier never leaves the CLI, so the relay alone cannot complete a login. Sessions are keyed by the OIDC state, single-use, with a 10-minute TTL. Not yet wired into the CLI: the --remote poll path lands once Sequence allowlists the relay's /api/oidc/cb as a redirect target. Deploy with `npx wrangler` (kept out of the workspace dep graph to satisfy the repo's trust policy). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gration # Conflicts: # packages/connector-ui/CHANGELOG.md # packages/connector-ui/package.json # packages/connector-ui/src/App.css # packages/connector-ui/src/index.css # packages/shared/CHANGELOG.md # packages/shared/package.json # pnpm-lock.yaml
Code reviewFound 3 issues. Checked for bugs and CLAUDE.md compliance.
See inline comments for details. |
Detailed review findings1. Bug in
See Fix: swap the call order so 2. Team standards violation in Definite assignment assertions ( 3. Team standards violation in
|
Summary
Migrates
polygon-agent-clifrom the Sequence dapp-client wallet model (browser-approval sessions + on-chain permission scoping) to the Sequence V3 OMS embedded-wallet model (@0xsequence/typescript-sdk, email-OTP login). Breaking change — the wallet is a new address space; users re-onboard viawallet login.What changed
New wallet model
wallet login --email <addr>(email OTP) replaceswallet create(browser approval).wallet logoutadded. Start+complete happen in one process (OTP is in-memory only).EthereumPrivateKeyCredentialSigner+ file-backedStorageManager); survives process restarts — verified headless on Polygon mainnet.New libs
lib/oms-client.ts—getOmsClient(walletName)singletonlib/oms-storage.ts— encrypted fileStorageManager+ credential-key persistencelib/oms-tx.ts—runOmsTx, drop-in for the old tx primitive; ported fee selection (prefer native or USDC, gated on affordability); sequential multi-tx fordeposit(non-atomic)lib/tx-dispatch.ts—runTxindirection used by all command call sitesCommands — all 17 tx call sites route through
runTx.balancesmigrated tooms.indexer. Newcallcommand (arbitrary calldata) already on main, retained. x402-pay funding + EIP-3009 unchanged (EOA-based).Removed (one-way) —
lib/dapp-client.ts,lib/relay-client.ts, theconnector-uipackage + its deploy workflow, thesharedx25519/xchacha20 session crypto, the Sapient permission flow, and all--contract/--usdc-limit/spend-limit/--defiflags. Legacy@0xsequence/dapp-client/wallet-*/relay deps pruned.Config / env
setup --oms-publishable-key <key> --oms-project-id <proj_...>persists OMS creds tobuilder.json.bootstrapOmsConfig()loadsSEQUENCE_PUBLISHABLE_KEY+SEQUENCE_OMS_PROJECT_ID, and alsoSEQUENCE_PROJECT_ACCESS_KEY(Trails/indexer key) from disk.TRAILS_API_KEY → SEQUENCE_PROJECT_ACCESS_KEY → builder.json.accessKey.Docs —
skills/*+ README + CLAUDE.md rewritten for the email-login flow; all old-model references removed.depositis non-atomic — approve + supply submit as two sequential txs.@0xsequence/typescript-sdk@0.1.0-alpha.2, pinned exactly.Verification (Polygon mainnet)
send-token,send-native,call(real tx hashes) ✅balancessingle + multi-chain viaoms.indexer✅depositbuilds correct 2-tx bundle;swapPOL→USDC builds a valid Trails intent ✅Commits
feat(cli): add OMS path behind flagrefactor(cli)!: remove dapp-client/connector-ui legacy, OMS is the only pathdocs(cli): update skills + READMErefactor(cli): bootstrap Trails key + unify resolution; drop stale legacy notes