Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/transaction-pay-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Live token balance queries now prefer the chain's Infura endpoint, falling back to the default endpoint if no Infura endpoint is configured ([#8839](https://github.com/MetaMask/core/pull/8839))

## [22.8.0]

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
import { accountSupports7702 } from '../../utils/7702';
import { getPayStrategiesConfig } from '../../utils/feature-flags';
import { getGasBuffer } from '../../utils/feature-flags';
import { getNetworkClientId } from '../../utils/provider';
import {
collectTransactionIds,
getTransaction,
Expand Down Expand Up @@ -141,10 +142,7 @@ async function submitTransactions(
const transactionCount =
orderedTransactions.length + (shouldPrependOriginalTransaction ? 1 : 0);

const networkClientId = messenger.call(
'NetworkController:findNetworkClientIdByChainId',
chainId,
);
const networkClientId = getNetworkClientId(messenger, chainId);

const is7702Batch = is7702 && transactionCount > 1;
const canUseQuotedBatchGasLimit =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Web3Provider } from '@ethersproject/providers';
import type { RampsOrder } from '@metamask/ramps-controller';
import type { TransactionMeta } from '@metamask/transaction-controller';
import { TransactionType } from '@metamask/transaction-controller';
Expand All @@ -15,11 +14,6 @@ import {
resolveSourceAmountRaw,
} from './utils';

jest.mock('@ethersproject/providers', () => ({
...jest.requireActual('@ethersproject/providers'),
Web3Provider: jest.fn(),
}));

const TX_HASH_MOCK = '0xabc123';
const WALLET_ADDRESS_MOCK = '0x1111111111111111111111111111111111111111' as Hex;
const ERC20_ADDRESS_MOCK = '0x2222222222222222222222222222222222222222' as Hex;
Expand Down Expand Up @@ -210,23 +204,17 @@ describe('Fiat Utils', () => {
messenger: resolveMessenger,
findNetworkClientIdByChainIdMock,
getNetworkClientByIdMock,
getNetworkConfigurationByChainIdMock,
getTokensControllerStateMock,
getRemoteFeatureFlagControllerStateMock:
resolveRemoteFeatureFlagControllerStateMock,
} = getMessengerMock();

let mockGetTransactionReceipt: jest.Mock;
let mockSend: jest.Mock;
let mockGetTransaction: jest.Mock;

beforeEach(() => {
jest.resetAllMocks();

mockGetTransactionReceipt = jest.fn();
mockSend = jest.fn();
mockGetTransaction = jest.fn();

findNetworkClientIdByChainIdMock.mockReturnValue(NETWORK_CLIENT_ID_MOCK);
getNetworkConfigurationByChainIdMock.mockReturnValue(undefined);
getNetworkClientByIdMock.mockReturnValue({
provider: PROVIDER_MOCK,
} as never);
Expand Down Expand Up @@ -255,16 +243,10 @@ describe('Fiat Utils', () => {
allIgnoredTokens: {},
allDetectedTokens: {},
} as never);

(Web3Provider as unknown as jest.Mock).mockImplementation(() => ({
getTransactionReceipt: mockGetTransactionReceipt,
send: mockSend,
getTransaction: mockGetTransaction,
}));
});

it('returns on-chain ERC-20 amount from receipt logs', async () => {
mockGetTransactionReceipt.mockResolvedValue({
PROVIDER_MOCK.request.mockResolvedValue({
logs: [
{
address: ERC20_ADDRESS_MOCK,
Expand Down Expand Up @@ -297,11 +279,11 @@ describe('Fiat Utils', () => {
});

expect(result).toBe('1500000');
expect(mockGetTransactionReceipt).not.toHaveBeenCalled();
expect(PROVIDER_MOCK.request).not.toHaveBeenCalled();
});

it('falls back to cryptoAmount when receipt is null', async () => {
mockGetTransactionReceipt.mockResolvedValue(null);
PROVIDER_MOCK.request.mockResolvedValue(null);

const result = await resolveSourceAmountRaw({
messenger: resolveMessenger,
Expand All @@ -314,7 +296,7 @@ describe('Fiat Utils', () => {
});

it('falls back to cryptoAmount when on-chain read throws', async () => {
mockGetTransactionReceipt.mockRejectedValue(new Error('Network error'));
PROVIDER_MOCK.request.mockRejectedValue(new Error('Network error'));

const result = await resolveSourceAmountRaw({
messenger: resolveMessenger,
Expand All @@ -327,7 +309,7 @@ describe('Fiat Utils', () => {
});

it('returns native amount from debug_traceTransaction', async () => {
mockSend.mockResolvedValue({
PROVIDER_MOCK.request.mockResolvedValue({
to: WALLET_ADDRESS_MOCK.toLowerCase(),
value: '0x1bc16d674ec80000',
calls: [],
Expand All @@ -344,11 +326,17 @@ describe('Fiat Utils', () => {
});

it('falls back to tx.value for native when trace is unsupported', async () => {
mockSend.mockRejectedValue(new Error('Method not found'));
mockGetTransaction.mockResolvedValue({
to: WALLET_ADDRESS_MOCK.toLowerCase(),
value: { toString: () => '2000000000000000000' },
});
PROVIDER_MOCK.request.mockImplementation(
({ method }: { method: string }) => {
if (method === 'debug_traceTransaction') {
return Promise.reject(new Error('Method not found'));
}
return Promise.resolve({
to: WALLET_ADDRESS_MOCK.toLowerCase(),
value: '0x1bc16d674ec80000',
});
},
);

const result = await resolveSourceAmountRaw({
messenger: resolveMessenger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getRelayPollingInterval,
getRelayPollingTimeout,
} from '../../utils/feature-flags';
import { getNetworkClientId } from '../../utils/provider';
import {
getLiveTokenBalance,
normalizeTokenAddress,
Expand Down Expand Up @@ -508,10 +509,7 @@ async function submitViaRelayExecute(
const { from, sourceChainId } = quote.request;
const { requestId } = quote.original.steps[0];

const networkClientId = messenger.call(
'NetworkController:findNetworkClientIdByChainId',
sourceChainId,
);
const networkClientId = getNetworkClientId(messenger, sourceChainId);

const sourceCallTransaction = {
...transaction,
Expand Down Expand Up @@ -600,10 +598,7 @@ async function submitViaTransactionController(
const { from, sourceChainId, sourceTokenAddress } = quote.request;
const { isPostQuote } = quote.request;

const networkClientId = messenger.call(
'NetworkController:findNetworkClientIdByChainId',
sourceChainId,
);
const networkClientId = getNetworkClientId(messenger, sourceChainId);

log('Adding transactions', {
normalizedParams: allParams,
Expand Down
11 changes: 11 additions & 0 deletions packages/transaction-pay-controller/src/tests/messenger-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
import { Messenger, MOCK_ANY_NAMESPACE } from '@metamask/messenger';
import type { NetworkControllerGetNetworkClientByIdAction } from '@metamask/network-controller';
import type { NetworkControllerFindNetworkClientIdByChainIdAction } from '@metamask/network-controller';
import type { NetworkControllerGetNetworkConfigurationByChainIdAction } from '@metamask/network-controller';
import type { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';
import type {
TransactionControllerAddTransactionAction,
Expand Down Expand Up @@ -117,6 +118,10 @@ export function getMessengerMock({
NetworkControllerGetNetworkClientByIdAction['handler']
> = jest.fn();

const getNetworkConfigurationByChainIdMock: jest.MockedFn<
NetworkControllerGetNetworkConfigurationByChainIdAction['handler']
> = jest.fn();

const getDelegationTransactionMock: jest.MockedFn<
TransactionPayControllerGetDelegationTransactionAction['handler']
> = jest.fn();
Expand Down Expand Up @@ -255,6 +260,11 @@ export function getMessengerMock({
getNetworkClientByIdMock,
);

messenger.registerActionHandler(
'NetworkController:getNetworkConfigurationByChainId',
getNetworkConfigurationByChainIdMock,
);

messenger.registerActionHandler(
'TransactionPayController:getDelegationTransaction',
getDelegationTransactionMock,
Expand Down Expand Up @@ -321,6 +331,7 @@ export function getMessengerMock({
getGasFeeTokensMock,
getKeyringControllerStateMock,
getNetworkClientByIdMock,
getNetworkConfigurationByChainIdMock,
getRemoteFeatureFlagControllerStateMock,
getStrategyMock,
getTokenBalanceControllerStateMock,
Expand Down
2 changes: 2 additions & 0 deletions packages/transaction-pay-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type {
import type { Messenger } from '@metamask/messenger';
import type { NetworkControllerFindNetworkClientIdByChainIdAction } from '@metamask/network-controller';
import type { NetworkControllerGetNetworkClientByIdAction } from '@metamask/network-controller';
import type { NetworkControllerGetNetworkConfigurationByChainIdAction } from '@metamask/network-controller';
import type { Quote as RampsQuote } from '@metamask/ramps-controller';
import type {
RampsControllerGetOrderAction,
Expand Down Expand Up @@ -78,6 +79,7 @@ export type AllowedActions =
| KeyringControllerSignTypedMessageAction
| NetworkControllerFindNetworkClientIdByChainIdAction
| NetworkControllerGetNetworkClientByIdAction
| NetworkControllerGetNetworkConfigurationByChainIdAction
| RampsControllerGetOrderAction
| RampsControllerGetQuotesAction
| RampsControllerGetStateAction
Expand Down
6 changes: 2 additions & 4 deletions packages/transaction-pay-controller/src/utils/gas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { TransactionPayControllerMessenger } from '..';
import { createModuleLogger, projectLogger } from '../logger';
import type { Amount } from '../types';
import { getFallbackGas, getGasBuffer } from './feature-flags';
import { getNetworkClientId } from './provider';
import { getNativeToken, getTokenBalance, getTokenFiatRate } from './token';

const log = createModuleLogger(projectLogger, 'gas');
Expand Down Expand Up @@ -227,10 +228,7 @@ export async function estimateGasLimit({
error?: unknown;
}> {
const gasBuffer = getGasBuffer(messenger, chainId);
const networkClientId = messenger.call(
'NetworkController:findNetworkClientIdByChainId',
chainId,
);
const networkClientId = getNetworkClientId(messenger, chainId);

let estimateGasError: unknown;
let simulationError: Error | undefined;
Expand Down
Loading
Loading