Skip to content

fix: preserve Money Account EIP-7702 auths on same-chain pay batches - #9765

Merged
jpuri merged 11 commits into
mainfrom
fix/batch-authorization-list-money-account
Aug 4, 2026
Merged

fix: preserve Money Account EIP-7702 auths on same-chain pay batches#9765
jpuri merged 11 commits into
mainfrom
fix/batch-authorization-list-money-account

Conversation

@jpuri

@jpurijpuri commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add optional authorizationList to TransactionBatchRequest and merge it with the batch payer (from) upgrade authorization when building the type-4 batch transaction.
  • Retain pre-signed EIP-7702 authorizations in signAuthorizationList instead of re-signing them with txParams.from.
  • In Relay same-chain batch submit with account override, forward the quote's full signed authorizationList through addTransactionBatch so Money Account vault upgrades are not dropped (CONF-1741 / Monad mUSD deposits).

Related to task: https://consensyssoftware.atlassian.net/browse/CONF-1757

Test plan

  • Unit: @metamask/transaction-controllerbatch.test.ts / eip7702.test.ts (merge provided auths; retain pre-signed)
  • Unit: @metamask/transaction-pay-controllerrelay-submit.test.ts (batch gets signed auth list only when same-chain + account override; single-tx path unchanged)
  • Manual (with mobile Gas Station merge): new user Money Account deposit, pay with Monad mUSD, same-chain batch path — Sentinel request includes 2 authorizations (EOA + Money Account) and vault leg succeeds
  • Regression: single-tx same-chain route and cross-chain routes unchanged

Note

Medium Risk
Touches EIP-7702 signing, batch assembly, and nonce attribution on the transaction publish path; incorrect authority recovery could skew nonces, but changes are scoped with unit tests and limited relay batch conditions.

Overview
Fixes same-chain MetaMask Pay relay batches when an EOA pays for a Money Account deposit: Money Account vault EIP-7702 authorizations are kept on the type-4 batch instead of being dropped or re-signed as the payer.

Transaction controller:TransactionBatchRequest gains optional authorizationList. Batch building merges caller-provided auths with the batch payer’s upgrade auth when needed; security delegationMock only uses the payer’s upgrade entry, not foreign auths. signAuthorizationListskips re-signing entries that already have a full signature. Nonce tracking recovers each authorization’s authority (new recoverAuthorizationAuthority / getAuthorizationAuthority) so another account’s auth nonces do not count against the payer.

Transaction pay controller: On same-chain multi-tx relay submit with account override, the quote’s fully signedauthorizationList is forwarded into addTransactionBatch; single-tx and non-override paths stay as before.

Reviewed by Cursor Bugbot for commit 10ffd51. Bugbot is set up for automated code reviews on this repo. Configure here.

Pass pre-signed authorizationList through addTransactionBatch when an
account override is active, retain those signatures on publish, and merge
them with the batch payer upgrade so Monad mUSD vault deposits succeed.
@jpuri
jpuri requested review from a team as code ownersAugust 3, 2026 15:36

@cursorcursorBot left a comment

Copy link
Copy Markdown

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.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c9dcd37. Configure here.

Comment threadpackages/transaction-controller/src/utils/batch.ts
delegationMock is for the batch payer. When from is already upgraded and
only foreign authorizations are provided, do not mock authorizationList[0]
onto the sender.
Comment threadpackages/transaction-controller/src/utils/batch.ts
Comment threadpackages/transaction-controller/src/utils/batch.ts
Keep foreign authorizations out of the batch payer's nonce history and restore the addTransactionBatchWith7702 JSDoc placement.
jpuri added 2 commits August 4, 2026 16:17
Use ^2.1.2 so yarn constraints stay consistent with accounts-controller and phishing-controller.
pedronfigueiredo
pedronfigueiredo previously approved these changes Aug 4, 2026
jpuri added 2 commits August 4, 2026 18:07
After merging main, the #9765 Fixed entry landed under 26.2.1; move it back to Unreleased.
@jpuri
jpuri added this pull request to the merge queueAug 4, 2026
Merged via the queue into main with commit f9cb59cAug 4, 2026
136 checks passed
@jpuri
jpuri deleted the fix/batch-authorization-list-money-account branch August 4, 2026 12:59
@cursorcursorBot mentioned this pull request Aug 4, 2026
4 tasks
runway-githubBot added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 5, 2026
…-8.6.0 (#34210)
## Summary
- In the Gas Station 7702 publish hook, retain pre-signed EIP-7702
authorizations whose recovered signer is not `txParams.from` (e.g. Money
Account upgrades) instead of replacing the entire authorization list
with only the EOA payer auth.
- When `from` is not upgraded, append a newly signed EOA authorization
alongside those foreign entries so Sentinel receives both.
- Depends on core: MetaMask/core#9765
(`addTransactionBatch` `authorizationList` + Relay batch pass-through).
Without that bump, Money Account auths never reach `txParams` and this
change alone cannot fix CONF-1741.
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1757
## Test plan
- [ ] Unit: `yarn jest
app/util/transactions/hooks/delegation-7702-publish.test.ts`
- [ ] After core packages are bumped: new-user Money Account deposit
paying with Monad mUSD (same-chain batch) — Sentinel submission includes
2 authorizations (EOA + Money Account) and vault leg succeeds
- [ ] Regression: Gas Station path when `from` is already upgraded / no
foreign auths; revokeDelegation skip unchanged
- [ ] Keep draft until core #9765 is published and versions are bumped
in this PR
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes EIP-7702 authorization assembly for Sentinel relay batches
(Money Account + EOA), so incorrect filtering could break upgrades or
relay submission; scope is localized to the publish hook with new tests.
> > **Overview**
> Fixes Gas Station / Sentinel relay submissions dropping **pre-signed
EIP-7702 authorizations** that belong to accounts other than the batch
payer (`txParams.from`), e.g. Money Account upgrades bundled with an
EOA-paid batch.
> > The **7702 publish hook** no longer replaces
`txParams.authorizationList` with only a freshly signed payer upgrade.
It **resolves** the list via `recoverAuthorizationAddress` (viem): keeps
fully signed entries whose recovered signer is not `from`, and when the
payer is not yet upgraded **appends** the new EOA authorization after
those foreign entries. If the payer is already upgraded, it forwards
foreign auths only when present.
> > Adds unit coverage for merged Money Account + EOA auth and for
upgraded `from` with a foreign auth. Bumps
**`@metamask/transaction-controller`** to **69.5.0** and
**`@metamask/transaction-pay-controller`** to **26.2.2** (with lockfile
transitives) so batch `authorizationList` can reach the hook end-to-end.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28a37f8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-githubBot added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 5, 2026
…-8.6.0 (#34210)
## Summary
- In the Gas Station 7702 publish hook, retain pre-signed EIP-7702
authorizations whose recovered signer is not `txParams.from` (e.g. Money
Account upgrades) instead of replacing the entire authorization list
with only the EOA payer auth.
- When `from` is not upgraded, append a newly signed EOA authorization
alongside those foreign entries so Sentinel receives both.
- Depends on core: MetaMask/core#9765
(`addTransactionBatch` `authorizationList` + Relay batch pass-through).
Without that bump, Money Account auths never reach `txParams` and this
change alone cannot fix CONF-1741.
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1757
## Test plan
- [ ] Unit: `yarn jest
app/util/transactions/hooks/delegation-7702-publish.test.ts`
- [ ] After core packages are bumped: new-user Money Account deposit
paying with Monad mUSD (same-chain batch) — Sentinel submission includes
2 authorizations (EOA + Money Account) and vault leg succeeds
- [ ] Regression: Gas Station path when `from` is already upgraded / no
foreign auths; revokeDelegation skip unchanged
- [ ] Keep draft until core #9765 is published and versions are bumped
in this PR
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes EIP-7702 authorization assembly for Sentinel relay batches
(Money Account + EOA), so incorrect filtering could break upgrades or
relay submission; scope is localized to the publish hook with new tests.
> > **Overview**
> Fixes Gas Station / Sentinel relay submissions dropping **pre-signed
EIP-7702 authorizations** that belong to accounts other than the batch
payer (`txParams.from`), e.g. Money Account upgrades bundled with an
EOA-paid batch.
> > The **7702 publish hook** no longer replaces
`txParams.authorizationList` with only a freshly signed payer upgrade.
It **resolves** the list via `recoverAuthorizationAddress` (viem): keeps
fully signed entries whose recovered signer is not `from`, and when the
payer is not yet upgraded **appends** the new EOA authorization after
those foreign entries. If the payer is already upgraded, it forwards
foreign auths only when present.
> > Adds unit coverage for merged Money Account + EOA auth and for
upgraded `from` with a foreign auth. Bumps
**`@metamask/transaction-controller`** to **69.5.0** and
**`@metamask/transaction-pay-controller`** to **26.2.2** (with lockfile
transitives) so batch `authorizationList` can reach the hook end-to-end.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28a37f8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-githubBot added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 5, 2026
…-8.6.0 (#34210)
## Summary
- In the Gas Station 7702 publish hook, retain pre-signed EIP-7702
authorizations whose recovered signer is not `txParams.from` (e.g. Money
Account upgrades) instead of replacing the entire authorization list
with only the EOA payer auth.
- When `from` is not upgraded, append a newly signed EOA authorization
alongside those foreign entries so Sentinel receives both.
- Depends on core: MetaMask/core#9765
(`addTransactionBatch` `authorizationList` + Relay batch pass-through).
Without that bump, Money Account auths never reach `txParams` and this
change alone cannot fix CONF-1741.
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1757
## Test plan
- [ ] Unit: `yarn jest
app/util/transactions/hooks/delegation-7702-publish.test.ts`
- [ ] After core packages are bumped: new-user Money Account deposit
paying with Monad mUSD (same-chain batch) — Sentinel submission includes
2 authorizations (EOA + Money Account) and vault leg succeeds
- [ ] Regression: Gas Station path when `from` is already upgraded / no
foreign auths; revokeDelegation skip unchanged
- [ ] Keep draft until core #9765 is published and versions are bumped
in this PR
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes EIP-7702 authorization assembly for Sentinel relay batches
(Money Account + EOA), so incorrect filtering could break upgrades or
relay submission; scope is localized to the publish hook with new tests.
> > **Overview**
> Fixes Gas Station / Sentinel relay submissions dropping **pre-signed
EIP-7702 authorizations** that belong to accounts other than the batch
payer (`txParams.from`), e.g. Money Account upgrades bundled with an
EOA-paid batch.
> > The **7702 publish hook** no longer replaces
`txParams.authorizationList` with only a freshly signed payer upgrade.
It **resolves** the list via `recoverAuthorizationAddress` (viem): keeps
fully signed entries whose recovered signer is not `from`, and when the
payer is not yet upgraded **appends** the new EOA authorization after
those foreign entries. If the payer is already upgraded, it forwards
foreign auths only when present.
> > Adds unit coverage for merged Money Account + EOA auth and for
upgraded `from` with a foreign auth. Bumps
**`@metamask/transaction-controller`** to **69.5.0** and
**`@metamask/transaction-pay-controller`** to **26.2.2** (with lockfile
transitives) so batch `authorizationList` can reach the hook end-to-end.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28a37f8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
pullBot pushed a commit to Reality2byte/metamask-mobile that referenced this pull request Aug 5, 2026
MetaMask#34210)
## Summary
- In the Gas Station 7702 publish hook, retain pre-signed EIP-7702
authorizations whose recovered signer is not `txParams.from` (e.g. Money
Account upgrades) instead of replacing the entire authorization list
with only the EOA payer auth.
- When `from` is not upgraded, append a newly signed EOA authorization
alongside those foreign entries so Sentinel receives both.
- Depends on core: MetaMask/core#9765
(`addTransactionBatch` `authorizationList` + Relay batch pass-through).
Without that bump, Money Account auths never reach `txParams` and this
change alone cannot fix CONF-1741.
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1757
## Test plan
- [ ] Unit: `yarn jest
app/util/transactions/hooks/delegation-7702-publish.test.ts`
- [ ] After core packages are bumped: new-user Money Account deposit
paying with Monad mUSD (same-chain batch) — Sentinel submission includes
2 authorizations (EOA + Money Account) and vault leg succeeds
- [ ] Regression: Gas Station path when `from` is already upgraded / no
foreign auths; revokeDelegation skip unchanged
- [ ] Keep draft until core MetaMask#9765 is published and versions are bumped
in this PR
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes EIP-7702 authorization assembly for Sentinel relay batches
(Money Account + EOA), so incorrect filtering could break upgrades or
relay submission; scope is localized to the publish hook with new tests.
> > **Overview**
> Fixes Gas Station / Sentinel relay submissions dropping **pre-signed
EIP-7702 authorizations** that belong to accounts other than the batch
payer (`txParams.from`), e.g. Money Account upgrades bundled with an
EOA-paid batch.
> > The **7702 publish hook** no longer replaces
`txParams.authorizationList` with only a freshly signed payer upgrade.
It **resolves** the list via `recoverAuthorizationAddress` (viem): keeps
fully signed entries whose recovered signer is not `from`, and when the
payer is not yet upgraded **appends** the new EOA authorization after
those foreign entries. If the payer is already upgraded, it forwards
foreign auths only when present.
> > Adds unit coverage for merged Money Account + EOA auth and for
upgraded `from` with a foreign auth. Bumps
**`@metamask/transaction-controller`** to **69.5.0** and
**`@metamask/transaction-pay-controller`** to **26.2.2** (with lockfile
transitives) so batch `authorizationList` can reach the hook end-to-end.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28a37f8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
sleepytanya added a commit to MetaMask/metamask-mobile that referenced this pull request Aug 6, 2026
…tation publish hook (#34348)
- fix: merge foreign EIP-7702 auths in Gas Station publish hook cp-8.6.0
(#34210)
## Summary
- In the Gas Station 7702 publish hook, retain pre-signed EIP-7702
authorizations whose recovered signer is not `txParams.from` (e.g. Money
Account upgrades) instead of replacing the entire authorization list
with only the EOA payer auth.
- When `from` is not upgraded, append a newly signed EOA authorization
alongside those foreign entries so Sentinel receives both.
- Depends on core: MetaMask/core#9765
(`addTransactionBatch` `authorizationList` + Relay batch pass-through).
Without that bump, Money Account auths never reach `txParams` and this
change alone cannot fix CONF-1741.
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1757
## Test plan
- [ ] Unit: `yarn jest
app/util/transactions/hooks/delegation-7702-publish.test.ts`
- [ ] After core packages are bumped: new-user Money Account deposit
paying with Monad mUSD (same-chain batch) — Sentinel submission includes
2 authorizations (EOA + Money Account) and vault leg succeeds
- [ ] Regression: Gas Station path when `from` is already upgraded / no
foreign auths; revokeDelegation skip unchanged
- [ ] Keep draft until core #9765 is published and versions are bumped
in this PR
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes EIP-7702 authorization assembly for Sentinel relay batches
(Money Account + EOA), so incorrect filtering could break upgrades or
relay submission; scope is localized to the publish hook with new tests.
> > **Overview**
> Fixes Gas Station / Sentinel relay submissions dropping **pre-signed
EIP-7702 authorizations** that belong to accounts other than the batch
payer (`txParams.from`), e.g. Money Account upgrades bundled with an
EOA-paid batch.
> > The **7702 publish hook** no longer replaces
`txParams.authorizationList` with only a freshly signed payer upgrade.
It **resolves** the list via `recoverAuthorizationAddress` (viem): keeps
fully signed entries whose recovered signer is not `from`, and when the
payer is not yet upgraded **appends** the new EOA authorization after
those foreign entries. If the payer is already upgraded, it forwards
foreign auths only when present.
> > Adds unit coverage for merged Money Account + EOA auth and for
upgraded `from` with a foreign auth. Bumps
**`@metamask/transaction-controller`** to **69.5.0** and
**`@metamask/transaction-pay-controller`** to **26.2.2** (with lockfile
transitives) so batch `authorizationList` can reach the hook end-to-end.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28a37f8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[29ede59](29ede59)
Co-authored-by: Jyoti Puri <jyotipuri@gmail.com>
Co-authored-by: sleepytanya <104780023+sleepytanya@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jpuri@pedronfigueiredo