Skip to content

fix(spend-permission): return the wallet-substituted account in requestSpendPermission#365

Open
Nexory wants to merge 1 commit into
base:masterfrom
Nexory:fix/request-spend-permission-substituted-account
Open

fix(spend-permission): return the wallet-substituted account in requestSpendPermission#365
Nexory wants to merge 1 commit into
base:masterfrom
Nexory:fix/request-spend-permission-substituted-account

Conversation

@Nexory

@Nexory Nexory commented Jul 18, 2026

Copy link
Copy Markdown

Summary

requestSpendPermission sends mutableData: { fields: ['message.account'] } when capabilities are provided, so the wallet may substitute account with a smart-wallet address. permissionHash is already derived from the wallet-returned (post-substitution) message, but the returned permission object used the original pre-substitution typedData.message. As a result result.permission.account and result.permissionHash described different permissions, and any consumer reading result.permission.account (display, storage, prepareSpendCallData, fetchPermissions) saw the wrong account.

This hoists the returned message into a permissionMessage variable, set from signResult.signedData.message in the wallet_sign branch and from typedData.message in the eth_signTypedData_v4 branch, so permission and permissionHash stay consistent. The eth_signTypedData_v4 path is unchanged in behavior.

Fixes #324.

How did you test your changes?

Added a unit test in requestSpendPermission.test.ts where the wallet returns signedData.message.account set to a different address than the request; it asserts result.permission matches the post-substitution message. The test fails on the current code (returns the original account) and passes with this change.

  • requestSpendPermission.test.ts: 17 passed (the new test fails without the fix)
  • full spend-permission suite: 9 files, 137 tests passing
  • tsc --noEmit: no new type errors from this change

…stSpendPermission

When capabilities are provided, requestSpendPermission sends
mutableData: { fields: ['message.account'] }, allowing the wallet to
substitute account with a smart-wallet address. permissionHash is already
derived from the wallet-returned (post-substitution) message, but the
returned permission object used the original pre-substitution
typedData.message, so result.permission.account and result.permissionHash
described different permissions.

Hoist the returned message into permissionMessage, set from
signResult.signedData.message in the wallet_sign branch and from
typedData.message in the eth_signTypedData_v4 branch, so permission and
permissionHash stay consistent. Adds a test where the wallet substitutes
account with a different address; it fails before this change and passes
after.
@cb-heimdall

Copy link
Copy Markdown
Collaborator

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

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.

spend-permission: requestSpendPermission returns inconsistent SpendPermission when wallet substitutes account via mutableData

2 participants