Skip to content

refactor(wallet-cli): Parameterise RpcHandler with struct-validated dispatch#8846

Draft
sirtimid wants to merge 1 commit into
rekm/wallet-clifrom
sirtimid/wallet-cli-rpc-handler-structs
Draft

refactor(wallet-cli): Parameterise RpcHandler with struct-validated dispatch#8846
sirtimid wants to merge 1 commit into
rekm/wallet-clifrom
sirtimid/wallet-cli-rpc-handler-structs

Conversation

@sirtimid
Copy link
Copy Markdown

Summary

Resolves #8777.

  • Adds RpcHandler<TParams, TResult>, RpcHandlerDefinition<TParams, TResult> ({ paramsStruct, run }), and a defineHandler(paramsStruct, run) helper in daemon/types.ts. RpcHandlerMap now maps method names to definitions.
  • rpc-socket-server.ts validates params against the handler's struct via superstruct.validate before dispatch and returns -32602 invalidParams on shape mismatch. Each handler body can now trust the shape of its argument.
  • daemon-entry.ts:
    • getStatus uses literal(null).
    • call uses a defined struct that enforces a non-empty [string, ...Json[]] tuple, dropping the ad-hoc Array.isArray / typeof checks from the handler body.
    • Replaces the wallet.messenger.call as any cast with a single typed RpcDispatcher = messenger.call.bind(messenger) escape hatch.
  • Adds @metamask/superstruct ^3.1.0 to wallet-cli (already used across the monorepo at this version).

Branched off rekm/wallet-cli; merge target intentionally kept on the feature branch rather than main. No changelog entry (folds into the package's existing 0.0.0 initial-release bullet).

Test plan

  • yarn workspace @metamask/wallet-cli run test — 248 tests pass, 100% line/branch/function/statement coverage on the touched files.
  • yarn lint:eslint packages/wallet-cli/src — clean.
  • yarn constraints — clean.
  • yarn workspace @metamask/wallet-cli run changelog:validate — clean.
  • New server test covers the -32602 invalidParams path and verifies run is not invoked when the struct rejects.
  • New struct tests on the call handler cover both the rejection cases (null, empty, non-string head, non-array) and the accepting case.

🤖 Generated with Claude Code

…ispatch

Adds a `defineHandler(paramsStruct, run)` helper plus a generic
`RpcHandler<TParams, TResult>` / `RpcHandlerDefinition` type so each daemon
RPC method owns its params struct. `rpc-socket-server` now validates params
via `superstruct.validate` once per request and returns
`-32602 invalidParams` on shape mismatch, so handler bodies can trust their
input. Rewrites `getStatus` and `call` against the new shape and replaces
the `wallet.messenger.call as any` cast with a single labelled
`RpcDispatcher` bind. Tests updated; coverage stays at 100%.

Closes #8777.

Co-Authored-By: Claude Opus 4.7 (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