Skip to content

feat(wallet-cli): add daemon commands, dev-mode launchers, and e2e smoke test#9255

Draft
sirtimid wants to merge 4 commits into
sirtimid/wallet-cli-wallet-factoryfrom
sirtimid/wallet-cli-commands
Draft

feat(wallet-cli): add daemon commands, dev-mode launchers, and e2e smoke test#9255
sirtimid wants to merge 4 commits into
sirtimid/wallet-cli-wallet-factoryfrom
sirtimid/wallet-cli-commands

Conversation

@sirtimid

Copy link
Copy Markdown
Member

Explanation

The final landing slice for @metamask/wallet-cli, after the scaffold (#9065), persistence (#9067), transport (#9108), and factory (#9226) slices. It adds the user-facing command surface so the package is actually runnable:

  • src/commands/daemon/{start,stop,status,purge,call}.ts (+ tests) — the mm daemon command suite. Thin oclif command classes over the daemon layers already on main: start spawns the daemon and reports the socket (or that one is already running), status/stop ping and tear it down, purge deletes the whitelisted daemon state files, and call dispatches an arbitrary Controller:method messenger action and prints the result.
  • src/test/run-command.ts — the oclif test harness used by the command tests (excluded from coverage via coveragePathIgnorePatterns).
  • bin/dev.mjs + bin/dev.cmd — the dev-mode launchers deferred from the scaffold slice, run via the tsx loader.

The command files are lifted verbatim from Erik's rekm/wallet-cli; their imported daemon interfaces (ensureDaemon, pingDaemon/sendCommand, stopDaemon, getDaemonPaths, readPidFile, confirmPurge, …) all match the modules already landed on main, so no rewrites were needed.

Additional, beyond Erik's verbatim files:

  • tsx dev dependency added as the dev-mode --import loader, with a knip ignoreDependencies: ['tsx'] entry since it's referenced only as an argument string (in daemon-spawn's source-entry path and bin/dev), never as a traceable import.
  • wallet-factory.e2e.test.ts — a real-construction smoke test that feeds buildInstanceOptions into a real Wallet (no @metamask/wallet mock) against :memory:, asserts the keyring unlocks on first-run SRP import, and dispatches a messenger action. This closes the one gap flagged in feat(wallet-cli): add wallet factory and daemon entry point #9226 review: the mocked unit test never feeds the wired instanceOptions to a real wallet. Constructing a Wallet never triggers the RemoteFeatureFlagController's network fetch, so it stays offline/CI-safe.
  • Docs — a README Usage section (mm --help + the daemon smoke flow) and a per-package ARCHITECTURE.md describing the daemon → factory → persistence → transport layering.

Stacked on #9226; the diff collapses to the true delta once that merges.

Checklist

  • build, test (100% coverage), lint (eslint, oxfmt, constraints, knip, changelog), and changelog:validate pass.
  • Command files preserved verbatim from Erik's branch; only additive config (tsx/knip/jest), the e2e test, and docs are new.

sirtimid and others added 4 commits June 24, 2026 18:31
…oke test

Add the `mm daemon` command suite — `start`, `stop`, `status`, `purge`, and
`call` — completing the CLI's user-facing surface, plus the oclif test harness
(`src/test/run-command.ts`) and the dev-mode launchers (`bin/dev.mjs`,
`bin/dev.cmd`) deferred from the scaffold slice.

The commands are Erik's verbatim; their imported daemon interfaces all match
the modules already on `main` from the persistence/transport/factory slices.

Also add `tsx` as the dev-mode `--import` loader (with a knip
`ignoreDependencies` entry, since it's referenced only as an argument string),
exclude the test harness from coverage, and add a real-construction e2e smoke
test that feeds `buildInstanceOptions` into a real `Wallet` against `:memory:`
— closing the gap that the mocked unit test cannot reach. Documents the
`mm daemon` usage in the README and adds an ARCHITECTURE.md describing the
daemon → factory → persistence → transport layering.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion

README documented MM_DAEMON_DATA_DIR as the data-dir override, but that's only
the internal start->daemon spawn-contract var (overwritten with config.dataDir
and ignored by the other commands). The real user override is MM_DATA_DIR, the
oclif scopedEnvVar('DATA_DIR'). Also assert the e2e's first account is a real
SRP-derived EVM address, so it fails loudly on an empty/placeholder account.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant