feat(wallet-cli): add daemon JSON-RPC socket transport#9108
Draft
sirtimid wants to merge 2 commits into
Draft
Conversation
Add the daemon's IPC transport layer for `@metamask/wallet-cli`. This is purely additive plumbing — no `mm` subcommand consumes it yet (commands land in a later slice), so there is no user-visible behavior change. - socket-line: newline-delimited read/write framing over a `net.Socket`. - daemon-client: `sendCommand` (one request per connection, id-correlated, retries once on transient connection errors) and `pingDaemon` (a `getStatus` health probe that classifies unreachable daemons by failure mode: refused / timeout / permission / protocol / other). - rpc-socket-server: `startRpcSocketServer` listens on a Unix socket and dispatches one JSON-RPC request per connection to a handler map, with a built-in `shutdown` method and idle-connection timeout. - daemon-spawn: `ensureDaemon` spawns a detached daemon and polls until the socket is responsive, refusing to take over a wedged or foreign socket. - stop-daemon: `stopDaemon` escalates from a graceful `shutdown` RPC through SIGTERM to SIGKILL, then cleans up the PID and socket files. - prompts: `confirmPurge` wraps the ESM-only `@inquirer/confirm`. - types: add `RpcHandler`, `RpcHandlerMap`, `DaemonStatusInfo`, and `DaemonSpawnConfig`. Adds `@inquirer/confirm` and `@metamask/rpc-errors` dependencies. All daemon modules are covered to the package's 100% thresholds, plus an end-to-end socket integration test exercising both halves over a real Unix socket. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
@metamask/wallet-cliruns a background daemon that hosts a@metamask/walletinstance; the CLI talks to it over a Unix socket. This PR adds that transport layer. It is purely additive plumbing — nommsubcommand consumes it yet (commands land in a follow-up), so there is no user-visible behavior change.socket-line—writeLine/readLinefor newline-delimited framing over anet.Socket, with an optional read timeout and listener cleanup.daemon-client—sendCommandopens a connection, writes one JSON-RPC request, reads one response, and closes; it correlates the responseidwith the request and retries once on transient connection errors (ECONNREFUSED/ECONNRESET).pingDaemonis a lightweightgetStatushealth probe that distinguishes "no daemon" (absent) from "daemon present but unreachable", classifying the latter by failure mode (refused/timeout/permission/protocol/other).rpc-socket-server—startRpcSocketServerlistens on a Unix socket and dispatches one JSON-RPC request per connection to a handler map. It intercepts a built-inshutdownmethod, enforces one-request-per-connection, times out idle connections, and returns aclose()handle.daemon-spawn—ensureDaemonspawns a detached daemon process and polls until the socket is responsive, refusing to take over a wedged or foreign-owned socket. Resolves the entry point fromdist(prod) orsrcviatsx(dev).stop-daemon—stopDaemonescalates from a gracefulshutdownRPC throughSIGTERMtoSIGKILL, then removes the PID and socket files best-effort.prompts—confirmPurgewraps the ESM-only@inquirer/confirmvia dynamic import.types— addsRpcHandler,RpcHandlerMap,DaemonStatusInfo, andDaemonSpawnConfig.Adds
@inquirer/confirmand@metamask/rpc-errorsdependencies. Every daemon module is covered to the package's 100% coverage thresholds, plus asocket-integration.test.tsthat exercises the client and server together over a real Unix socket (framing, id correlation, the one-request-per-connection invariant, and real shutdown timing).References
mainonce feat(wallet-cli): add SQLite-backed controller-state persistence #9067 merges.Checklist
🤖 Generated with Claude Code