Skip to content

Conversation

@jiexi
Copy link
Contributor

@jiexi jiexi commented Feb 2, 2026

Explanation

Improves reliability of wallet_sendCalls.

Changes getAccounts hook to getPermittedAccountsForOrigin hook which takes no params and returns the permitted accounts for the origin of the request

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Moderate risk because it changes RPC middleware authorization/account-selection behavior and the hook contract (from getAccounts(req) to getPermittedAccountsForOrigin()), which could surface new unauthorized errors if consumers don’t implement the new hook correctly.

Overview
Makes wallet_sendCalls more reliable by switching account authorization and default from resolution to an origin-scoped getPermittedAccountsForOrigin() hook, rather than relying on a generic getAccounts(req)/selected-account lookup.

processSendCalls now defaults from to the first permitted account when from is omitted and explicitly throws providerErrors.unauthorized() when no permitted account is available; wallet_sendCalls, wallet_getCapabilities, and validateAndNormalizeKeyholder were updated accordingly, with tests and the changelog updated to match.

Written by Cursor Bugbot for commit 8f310db. This will update automatically on new commits. Configure here.

@jiexi jiexi requested a review from a team as a code owner February 2, 2026 22:14
@jiexi jiexi changed the title jl/make wallet sendCalls better feat: make wallet_sendCalls more reliable Feb 2, 2026
@jiexi jiexi requested a review from a team as a code owner February 2, 2026 22:20
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

address: Hex,
req: JsonRpcRequest,
{ getAccounts }: { getAccounts: (req: JsonRpcRequest) => Promise<string[]> },
{ getPermittedAccountsForOrigin }: { getPermittedAccountsForOrigin: () => Promise<string[]> },
Copy link
Member

@matthewwalsh0 matthewwalsh0 Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we avoid breaking changes for all clients if we kept the current name, but just ensured the hooks check the origin?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah Jiexi and I went back and forth on this a bit, but I think for this case the name change is worth it. The bug this PR fixes happened precisely because getAccounts is ambiguous - it doesn't convey that these must be permitted accounts for the requesting origin. A future developer could reasonably implement getAccounts by returning all accounts or the selected account, not realizing this breaks the security model.
Since this is already a breaking change (the signature changed from (req) => Promise<string[]> to () => Promise<string[]>), we'd prefer to make the API self-documenting and reduce the risk of similar bugs.

// Ensure that an "unauthorized" error is thrown if the requester
// does not have the `eth_accounts` permission.
const accounts = await getAccounts(req);
const accounts = await getPermittedAccountsForOrigin();
Copy link
Member

@matthewwalsh0 matthewwalsh0 Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does the client access the origin if we don't provide anything to the hook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook gets the origin off the request object directly. The 7702 middleware follows the same pattern that I'm hoping to use here

matthewwalsh0
matthewwalsh0 previously approved these changes Feb 3, 2026
adonesky1
adonesky1 previously approved these changes Feb 3, 2026
Copy link
Contributor

@adonesky1 adonesky1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jiexi jiexi dismissed stale reviews from adonesky1 and matthewwalsh0 via 8f310db February 3, 2026 21:56
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.

4 participants