fix(signing): match wallet shape by member presence, not signTypedData arity - #95
Merged
Conversation
…a arity isViemJsonRpc/isViemLocal required signTypedData.length to be 1 or 2, but Function.length counts only parameters declared before the first default or rest parameter. A wrapped or adapted wallet (Privy-style embedded-wallet adapter declaring signTypedData(...args) or all-defaulted params) reports length 0, failed BOTH guards, and died with an opaque "unknown wallet type" error the moment signing was first needed. This fork supports only viem-shaped wallets, so the arity probe was a vestigial viem-vs-ethers discriminator. - Drop the arity conditions from both guards; membership checks stay (jsonrpc = callable signTypedData + getAddresses + getChainId, local = callable signTypedData + string address). Length-0 adapters now adapt and sign byte-identically to the account they wrap. - Keep the one protection arity provided: createSigner rejects a callable signTypedData declaring >= 3 parameters up front — the positional ethers-style signTypedData(domain, types, value) shape that would otherwise pass isViemLocal and fail cryptically at sign time — with a message pointing at the required viem-style single-params-object shape. - Make the fall-through diagnostic: the error now enumerates exactly which members are missing (no callable signTypedData at all, or which of getAddresses/getChainId/string address the wallet lacks), so an integrator can fix their adapter from the message alone. - Update the guard/interface JSDoc, the stale arity comments in tests, and the docs/signing.md wallet-compatibility section accordingly. - New suite tests/signing/_abstractWallet.test.ts pins all of the above against the existing signature fixtures. Fixes #92
Merged
joeblau
added a commit
that referenced
this pull request
Aug 4, 2026
Four fixes, each cross-verified to agreement by three independent reviewers (Claude, Kimi K3 Max, Codex gpt-5.6-sol xhigh): - #89 subscription failures notify every subscriber + failureSignal (#93) - #90 WebSocket message pacing on by default, flush charging fixed (#96) - #91 200-OK { type: "error" } envelopes throw HttpRequestError (#94) - #92 wallet shape detection by member presence, not arity (#95) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
isViemJsonRpc/isViemLocalno longer consultFunction.length— membership checks only, so wrapped/adapted wallets (signTypedData(...args), defaulted params, Privy-style adapters) adapt and signsignTypedData(domain, types, value)(≥3 declared params) is rejected up front with an explanatory error instead of failing cryptically at sign timetypeof— one iteration is enough to fix an adapter from the message aloneVerification (3-agent agreement)
bun run check+ 1965 offline tests, 0 failFixes #92
🤖 Generated with Claude Code