Skip to content

Headless identity: restore, profile, custody changes, create, storage, transfer - #5

Merged
baairon merged 9 commits into
masterfrom
claude/wonderful-wright-obszfp
Oct 6, 2026
Merged

baairon merged 9 commits into
masterfrom
claude/wonderful-wright-obszfp

Conversation

@baairon

@baairon baairon commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Summary

Every action in the interactive manager now has a headless command. An agent can be restored, edited, re-custodied, created and handed over without a TTY.

Each command follows the same conventions as custody and ens:

  • It previews by default and acts only with --yes.
  • It runs all of its wallet prompts in one browser tab.
  • It returns the stable {"schema":1} JSON envelope and the existing exit codes.

The commands reuse the manager's existing runners, so the headless and interactive paths share their logic. One commit per step:

  1. Shared groundwork
    • Gas fix: browser wallet sessions now pass the prepared gas and fees to the wallet page. One-shot requests already did; sessions dropped them, which also affected ens.
    • Session option: the Vault runners and the operator sync take an optional wallet session.
    • Restore and refetch signer: they take an optional signer, either a wallet session or the operator key, which decrypts locally through its slot in the snapshot.
    • Revoke before withdrawing: switching to Simple now revokes the Vault's operator approvals before the withdrawal, in the manager too. Some Vault builds keep approvals across a withdrawal.
  2. restore
    • restore <token-id>|<name> rebuilds an agent on this machine.
    • restore --owner <address> lists the agents a wallet holds.
    • restore with no target pulls the newest onchain snapshot into the vault.
    • --operator decrypts with the operator key and opens no browser. The vault is checkpointed first, and config is saved only after the files land.
  3. profile
    • Changes the name, description and image (--image none removes it) in one save.
    • --operator works in Advanced custody with a linked ENS name; otherwise it says what is missing.
  4. Custody changes
    • custody --advanced deploys or reuses a Vault, deposits the token and saves.
    • custody --simple revokes the Vault's operators, withdraws the token and saves.
    • --add-operator, --remove-operator and --activate-operator manage operators.
    • Each change is planned from chain state, so a run that stops part way resumes when run again.
    • --add-operator --operator has the injected key sign its own proof.
    • The operator proof logic moved out of the manager screen into a shared helper, which the screen now uses.
  5. create
    • Mints a new agent. --advanced continues into the Vault in the same tab, --import folds in notes from local tools, and --replace is required when an agent already exists.
  6. storage
    • Shows whether IPFS storage is ready.
    • --set reads a Pinata JWT from stdin only; --forget removes it after a preview.
  7. transfer <address|name>
    • Both wallets sign in one tab and the owner publishes the re-encrypted snapshot.
    • Refuses a token that is still in the Vault, and states that ethagent never moves the token itself.
  8. Docs
    • README: common tasks, command rows, a "Setting up and moving an agent" section, exit code 4 for partly-done runs, and a mention of create in the quick start.
    • --help lists the new commands.
    • Agent guidance: previews and read-only forms are the agent's to run, --yes is the user's, and restore --operator --yes may run when the user asks.

Testing

  • npm run typecheck is clean.
  • npm test passes all 763 tests in a clean CI-like environment.
  • New test files:
    • restoreCommand, including an end-to-end decrypt with a local key against a real envelope that writes the vault;
    • profileCommand;
    • custodyWrite, covering step order, the single wallet tab, resuming, partial cancellation, revoking, and the operator-key proof;
    • setupCommands (create, storage, transfer);
    • a session gas passthrough test.

Live checks after merge (non-destructive first)

  1. keychain exec ethagent -- ethagent restore 45744 --network base --operator (preview), then with --yes into a temporary HOME.
  2. ethagent profile and a profile --name <text> preview.
  3. ethagent custody --add-operator --operator preview, then custody --simple preview, to check the revoke step lists the current operators.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw


Generated by Claude Code

claude added 9 commits October 6, 2026 21:54
…ab or with the operator key

- Browser wallet sessions pass the prepared gas and fees to the page, as one-shot requests already did.
- The Vault deploy, deposit, unwrap, and withdraw runners and the operator sync take an optional wallet session, so a command can run every prompt in one tab.
- Restore and refetch take an optional signer: a wallet session, or the operator key, which decrypts locally through the snapshot's slot. Without a known requester, restore asks whichever wallet connects for its own slot.
- Revoke the Vault's operator approvals before withdrawing on the switch to Simple; some Vault builds keep them across a withdraw.
- Shared helpers for the headless commands: one lazy wallet tab, operator key and storage checks, network registries, and saving a completed identity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- restore <token-id> | <name>: rebuild an agent on this machine; restore --owner <address|name> lists what a wallet holds; restore with an identity pulls the newest onchain snapshot into the vault.
- Previews until --yes: agent, snapshot, who decrypts it, and warnings for local changes, a pending publish, or switching agents.
- The browser wallet signs in one tab, or --operator decrypts with the operator key and opens nothing. Config is saved only after the files land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- profile shows the public name, description, image, and agent card; --name, --description, and --image <path|url|none> change them and publish in one save, previewing until --yes.
- Validates the name and image before anything is pinned, and sends nothing when nothing changes.
- The owner wallet signs in one tab; --operator signs with the operator key when advanced custody with a linked ENS name allows it, and otherwise refuses with what is missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- custody --advanced deploys a Vault (or reuses one), deposits the token, and saves; --simple revokes the Vault's operator approvals, withdraws, and saves; --add-operator, --remove-operator, and --activate-operator manage operators.
- Each change is planned from chain state, previews until --yes, and runs every wallet prompt in one tab. A run that stops part way says what landed and resumes when run again.
- --add-operator --operator lets the injected operator key sign its own restore-access proof, so authorizing it needs only the owner's approval.
- Move the operator proof out of the manager screen into a shared helper the screen now uses, and label the wallet page's custody-switch steps as they run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- create --name <text> --network mainnet|base mints a new agent with its first encrypted snapshot, previewing until --yes; --description, --import (fold this machine's notes into MEMORY.md), and --replace (when an agent already exists; its vault stays on disk).
- --advanced continues into deploy, deposit, and the custody save in the same browser tab; if the mint lands but custody does not, it says so and points at custody --advanced.
- The mint runner takes an optional wallet session; the manager is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- storage shows where snapshots are pinned and whether a credential is set; --set reads a Pinata JWT from stdin only, checks it with Pinata, and saves it; --forget removes it after a preview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- transfer <address|name> prepares the agent for a new owner: both wallets sign in one browser tab and the owner publishes the re-encrypted snapshot, previewing until --yes.
- Refuses the owner itself and a token still in a Vault, and ends by naming the step ethagent never takes: sending the token from your wallet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
- README: common tasks, command rows, and a Setting up and moving an agent section covering previews, the one wallet tab, resuming, restoring and approving with the operator key, revoking on the switch to Simple, transfers, and storage. Quick start mentions create.
- --help lists the new commands; agent guidance says previews and read-only forms are the agent's to run, --yes is the user's, and restore --operator --yes may run when the user asks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
Resolve src/identity/manager/custody/helpers.ts: keep master's removal of
buildSeedConfigFromStep and keep localOperatorAddresses, which the custody
changes use. Restore envelopeChallengeFor in localKeyDecrypt.ts, removed on
master as unreferenced and now used by restore previews.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HG2miyE22qTuug1Quxj7iw
@baairon
baairon merged commit 89269b6 into master Oct 6, 2026
3 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