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

@jpuri jpuri 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. signAuthorizationList skips 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 signed authorizationList 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 owners August 3, 2026 15:36
@jpuri
jpuri temporarily deployed to default-branch August 3, 2026 15:36 — with GitHub Actions Inactive

@cursor cursor Bot 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 thread packages/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 thread packages/transaction-controller/src/utils/batch.ts
Comment thread packages/transaction-controller/src/utils/batch.ts
Keep foreign authorizations out of the batch payer's nonce history and restore the addTransactionBatchWith7702 JSDoc placement.
@jpuri
jpuri requested a review from pedronfigueiredo August 4, 2026 10:44
jpuri added 2 commits August 4, 2026 16:17
Use ^2.1.2 so yarn constraints stay consistent with accounts-controller and phishing-controller.
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 requested a review from pedronfigueiredo August 4, 2026 12:45
@jpuri
jpuri added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit f9cb59c Aug 4, 2026
136 checks passed
@jpuri
jpuri deleted the fix/batch-authorization-list-money-account branch August 4, 2026 12:59
@cursor cursor Bot mentioned this pull request Aug 4, 2026
4 tasks
runway-github Bot 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-github Bot 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-github Bot 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 -->
pull Bot 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 free to 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