From 71e1067957ffd4fe502beb8e2f0877309d1554e7 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Thu, 16 Apr 2026 15:18:22 +0100 Subject: [PATCH] fix(transaction-pay-controller): resolve correct networkClientId for source chain in relay execute The sourceCallTransaction in submitViaRelayExecute inherited networkClientId from the original transaction, which references the target chain. This caused getNonceLock to query the wrong chain, producing an incorrect nonce in the EIP-7702 authorization list during cross-chain pay flows. Resolve the correct networkClientId for the source chain via findNetworkClientIdByChainId before building the source call transaction. --- packages/transaction-pay-controller/CHANGELOG.md | 4 ++++ .../src/strategy/relay/relay-submit.test.ts | 9 +++++++++ .../src/strategy/relay/relay-submit.ts | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/packages/transaction-pay-controller/CHANGELOG.md b/packages/transaction-pay-controller/CHANGELOG.md index 2589b78feaf..d089f19cda1 100644 --- a/packages/transaction-pay-controller/CHANGELOG.md +++ b/packages/transaction-pay-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Resolve correct `networkClientId` for source chain in Relay execute flow ([#8492](https://github.com/MetaMask/core/pull/8492)) + ## [19.2.0] ### Changed diff --git a/packages/transaction-pay-controller/src/strategy/relay/relay-submit.test.ts b/packages/transaction-pay-controller/src/strategy/relay/relay-submit.test.ts index 4fb81b98176..8e640262811 100644 --- a/packages/transaction-pay-controller/src/strategy/relay/relay-submit.test.ts +++ b/packages/transaction-pay-controller/src/strategy/relay/relay-submit.test.ts @@ -1272,6 +1272,7 @@ describe('Relay Submit Utils', () => { expect(getDelegationTransactionMock).toHaveBeenCalledWith({ transaction: expect.objectContaining({ chainId: CHAIN_ID_MOCK, + networkClientId: NETWORK_CLIENT_ID_MOCK, nestedTransactions: [ { data: '0x1234', @@ -1283,6 +1284,14 @@ describe('Relay Submit Utils', () => { }); }); + it('resolves networkClientId for source chain instead of inheriting from original transaction', async () => { + await submitRelayQuotes(request); + + expect(findNetworkClientIdByChainIdMock).toHaveBeenCalledWith( + CHAIN_ID_MOCK, + ); + }); + it('submits to /execute with delegation data', async () => { await submitRelayQuotes(request); diff --git a/packages/transaction-pay-controller/src/strategy/relay/relay-submit.ts b/packages/transaction-pay-controller/src/strategy/relay/relay-submit.ts index 9642842ee1e..8c307a923dc 100644 --- a/packages/transaction-pay-controller/src/strategy/relay/relay-submit.ts +++ b/packages/transaction-pay-controller/src/strategy/relay/relay-submit.ts @@ -400,9 +400,15 @@ async function submitViaRelayExecute( const { from, sourceChainId } = quote.request; const { requestId } = quote.original.steps[0]; + const networkClientId = messenger.call( + 'NetworkController:findNetworkClientIdByChainId', + sourceChainId, + ); + const sourceCallTransaction = { ...transaction, chainId: sourceChainId, + networkClientId, nestedTransactions: allParams.map((params) => ({ data: (params.data ?? '0x') as Hex, to: params.to as Hex,