From 33e220767e3a2be6cff84c0fcecd2bc8fd799ca6 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Sun, 17 Nov 2024 00:03:03 +0000 Subject: [PATCH] Use preview build Include network client ID in addTransaction calls. Include network client ID in updateIncomingTransactions calls. Include network client Id in getNetworkNonce calls. Update calls to wipeTransactions. Create global network utils. Move getGlobalEthQuery to global network utils. Add network client ID to test data. --- app/components/Nav/Main/RootRPCMethodsUI.js | 8 +- app/components/Nav/Main/index.js | 13 ++- .../Views/SendTransaction/SendTransaction.tsx | 6 + .../Stake/hooks/usePoolStakedClaim/index.ts | 7 ++ .../Stake/hooks/usePoolStakedDeposit/index.ts | 5 +- .../Stake/hooks/usePoolStakedUnstake/index.ts | 4 + app/components/UI/Swaps/QuotesView.js | 3 +- .../TransactionDetails/index.js | 3 +- app/components/UI/Transactions/index.js | 16 ++- app/components/Views/Asset/index.js | 10 +- .../Views/NetworkSelector/NetworkSelector.tsx | 2 +- .../Views/Settings/AdvancedSettings/index.js | 2 +- .../NetworksSettings/NetworkSettings/index.js | 2 +- .../Views/Settings/NetworksSettings/index.js | 2 +- .../TransactionManager/approveTransaction.ts | 4 + app/core/Engine.ts | 104 ++++++------------ app/core/NotificationManager.js | 4 +- .../RPCMethods/eth_sendTransaction.test.ts | 28 ++++- app/core/RPCMethods/eth_sendTransaction.ts | 6 +- .../WalletConnect/WalletConnect2Session.ts | 1 + app/util/blockaid/index.test.ts | 2 + app/util/dappTransactions/index.ts | 5 +- app/util/importAdditionalAccounts.js | 3 +- app/util/networks/global-network.ts | 50 +++++++++ app/util/networks/index.js | 4 +- app/util/networks/index.test.ts | 13 ++- app/util/smart-transactions/index.test.ts | 7 ++ .../smart-publish-hook.test.ts | 1 + app/util/transaction-controller/index.test.ts | 5 +- app/util/transaction-controller/index.ts | 7 +- app/util/transactions/index.js | 11 +- app/util/transactions/index.test.ts | 40 +++++-- package.json | 2 +- yarn.lock | 26 ++++- 34 files changed, 275 insertions(+), 131 deletions(-) create mode 100644 app/util/networks/global-network.ts diff --git a/app/components/Nav/Main/RootRPCMethodsUI.js b/app/components/Nav/Main/RootRPCMethodsUI.js index 086d3c3a61f..1e39e48d371 100644 --- a/app/components/Nav/Main/RootRPCMethodsUI.js +++ b/app/components/Nav/Main/RootRPCMethodsUI.js @@ -73,6 +73,7 @@ import { updateSwapsTransaction } from '../../../util/swaps/swaps-transactions'; ///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps) import InstallSnapApproval from '../../Approvals/InstallSnapApproval'; +import { getGlobalEthQuery } from '../../../util/networks/global-network'; ///: END:ONLY_INCLUDE_IF const hstInterface = new ethers.utils.Interface(abi); @@ -157,7 +158,7 @@ const RootRPCMethodsUI = (props) => { ({ id }) => id === approvalTransactionMetaId, ); - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); const ethBalance = await query(ethQuery, 'getBalance', [ props.selectedAddress, @@ -304,7 +305,7 @@ const RootRPCMethodsUI = (props) => { transactionId: transactionMeta.id, deviceId, // eslint-disable-next-line no-empty-function - onConfirmationComplete: () => {}, + onConfirmationComplete: () => { }, type: 'signTransaction', }), ); @@ -356,6 +357,7 @@ const RootRPCMethodsUI = (props) => { autoSign(transactionMeta); } else { const { + networkClientId, txParams: { value, gas, gasPrice, data }, } = transactionMeta; const { AssetsContractController } = Engine.context; @@ -367,7 +369,7 @@ const RootRPCMethodsUI = (props) => { data && data !== '0x' && to && - (await getMethodData(data)).name === TOKEN_METHOD_TRANSFER + (await getMethodData(data, networkClientId)).name === TOKEN_METHOD_TRANSFER ) { let asset = props.tokens.find(({ address }) => toLowerCaseEquals(address, to), diff --git a/app/components/Nav/Main/index.js b/app/components/Nav/Main/index.js index 8d463aae71b..645c74e0d07 100644 --- a/app/components/Nav/Main/index.js +++ b/app/components/Nav/Main/index.js @@ -58,6 +58,7 @@ import { useMinimumVersions } from '../../hooks/MinimumVersions'; import navigateTermsOfUse from '../../../util/termsOfUse/termsOfUse'; import { selectChainId, + selectNetworkClientId, selectNetworkConfigurations, selectProviderConfig, selectProviderType, @@ -82,6 +83,7 @@ import { } from '../../../util/transaction-controller'; import isNetworkUiRedesignEnabled from '../../../util/networks/isNetworkUiRedesignEnabled'; import { useConnectionHandler } from '../../../util/navigation/useConnectionHandler'; +import { getGlobalEthQuery } from '../../../util/networks/global-network'; const Stack = createStackNavigator(); @@ -137,7 +139,7 @@ const Main = (props) => { const checkInfuraAvailability = useCallback(async () => { if (props.providerType !== 'rpc') { try { - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); await query(ethQuery, 'blockNumber', []); props.setInfuraAvailabilityNotBlocked(); } catch (e) { @@ -175,11 +177,11 @@ const Main = (props) => { removeNotVisibleNotifications(); BackgroundTimer.runBackgroundTimer(async () => { - await updateIncomingTransactions(); + await updateIncomingTransactions([props.networkClientId]); }, AppConstants.TX_CHECK_BACKGROUND_FREQUENCY); } }, - [backgroundMode, removeNotVisibleNotifications], + [backgroundMode, removeNotVisibleNotifications, props.networkClientId], ); const initForceReload = () => { @@ -447,6 +449,10 @@ Main.propTypes = { * backup seed phrase modal visible */ backUpSeedphraseVisible: PropTypes.bool, + /** + * ID of the global network client + */ + networkClientId: PropTypes.string, }; const mapStateToProps = (state) => ({ @@ -454,6 +460,7 @@ const mapStateToProps = (state) => ({ selectShowIncomingTransactionNetworks(state), providerType: selectProviderType(state), chainId: selectChainId(state), + networkClientId: selectNetworkClientId(state), backUpSeedphraseVisible: state.user.backUpSeedphraseVisible, }); diff --git a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx index ac4927aa503..273e6aff583 100644 --- a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx +++ b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx @@ -58,6 +58,7 @@ import { generateTransferData } from '../../../../../util/transactions'; import useAnalytics from '../../hooks/useAnalytics'; import { toHex } from '@metamask/controller-utils'; import { RAMPS_SEND } from '../../constants'; +import { selectNetworkClientId } from '../../../../../selectors/networkController'; interface SendTransactionParams { orderId?: string; @@ -70,6 +71,7 @@ function SendTransaction() { const order = useSelector((state: RootState) => getOrderById(state, params.orderId), ); + const networkClientId = useSelector(selectNetworkClientId); const trackEvent = useAnalytics(); const [isConfirming, setIsConfirming] = useState(false); @@ -165,10 +167,13 @@ function SendTransaction() { // but RampTransaction type / interface expecting it to be a number transactionAnalyticsPayload, ); + const response = await addTransaction(transactionParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin: RAMPS_SEND, }); + const hash = await response.result; if (order?.id) { @@ -200,6 +205,7 @@ function SendTransaction() { orderData, trackEvent, transactionAnalyticsPayload, + networkClientId, ]); if (!order) { diff --git a/app/components/UI/Stake/hooks/usePoolStakedClaim/index.ts b/app/components/UI/Stake/hooks/usePoolStakedClaim/index.ts index 6a5a3533c40..5f1c5f6e14b 100644 --- a/app/components/UI/Stake/hooks/usePoolStakedClaim/index.ts +++ b/app/components/UI/Stake/hooks/usePoolStakedClaim/index.ts @@ -12,6 +12,7 @@ import { isRequestClaimable, transformAggregatedClaimableExitRequestToMulticallArgs, } from './utils'; +import { getGlobalNetworkClientId } from '../../../../../util/networks/global-network'; const attemptMultiCallClaimTransaction = async ( pooledStakesData: PooledStake, @@ -42,8 +43,11 @@ const attemptMultiCallClaimTransaction = async ( gasLimit.toString(), ); + const networkClientId = getGlobalNetworkClientId(); + return addTransaction(txParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin: ORIGIN_METAMASK, type: TransactionType.stakingClaim, }); @@ -85,8 +89,11 @@ const attemptSingleClaimTransaction = async ( gasLimit.toString(), ); + const networkClientId = getGlobalNetworkClientId(); + return addTransaction(txParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin: ORIGIN_METAMASK, type: TransactionType.stakingClaim, }); diff --git a/app/components/UI/Stake/hooks/usePoolStakedDeposit/index.ts b/app/components/UI/Stake/hooks/usePoolStakedDeposit/index.ts index 5ecdf93cb59..1072768aecb 100644 --- a/app/components/UI/Stake/hooks/usePoolStakedDeposit/index.ts +++ b/app/components/UI/Stake/hooks/usePoolStakedDeposit/index.ts @@ -9,6 +9,7 @@ import { addTransaction } from '../../../../../util/transaction-controller'; import { formatEther } from 'ethers/lib/utils'; import { useStakeContext } from '../useStakeContext'; import trackErrorAsAnalytics from '../../../../../util/metrics/TrackError/trackErrorAsAnalytics'; +import { getGlobalNetworkClientId } from '../../../../../util/networks/global-network'; const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; @@ -60,9 +61,11 @@ const attemptDepositTransaction = chainId, ); - // TODO: Add Stake/Unstake/Claim TransactionType to display contract method in confirmation screen. + const networkClientId = getGlobalNetworkClientId(); + return await addTransaction(txParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin: ORIGIN_METAMASK, type: TransactionType.stakingDeposit, }); diff --git a/app/components/UI/Stake/hooks/usePoolStakedUnstake/index.ts b/app/components/UI/Stake/hooks/usePoolStakedUnstake/index.ts index 641a2fd9c49..bf39c3817ce 100644 --- a/app/components/UI/Stake/hooks/usePoolStakedUnstake/index.ts +++ b/app/components/UI/Stake/hooks/usePoolStakedUnstake/index.ts @@ -10,6 +10,7 @@ import { addTransaction } from '../../../../../util/transaction-controller'; import { ORIGIN_METAMASK } from '@metamask/controller-utils'; import trackErrorAsAnalytics from '../../../../../util/metrics/TrackError/trackErrorAsAnalytics'; import useBalance from '../useBalance'; +import { getGlobalNetworkClientId } from '../../../../../util/networks/global-network'; const generateUnstakeTxParams = ( activeAccountAddress: string, @@ -72,8 +73,11 @@ const attemptUnstakeTransaction = chainId, ); + const networkClientId = getGlobalNetworkClientId(); + return await addTransaction(txParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin: ORIGIN_METAMASK, type: TransactionType.stakingUnstake, }); diff --git a/app/components/UI/Swaps/QuotesView.js b/app/components/UI/Swaps/QuotesView.js index b0e37a6e718..609f9d6f92b 100644 --- a/app/components/UI/Swaps/QuotesView.js +++ b/app/components/UI/Swaps/QuotesView.js @@ -114,6 +114,7 @@ import { selectGasFeeEstimates } from '../../../selectors/confirmTransaction'; import { selectShouldUseSmartTransaction } from '../../../selectors/smartTransactionsController'; import { selectGasFeeControllerEstimateType } from '../../../selectors/gasFeeController'; import { addSwapsTransaction } from '../../../util/swaps/swaps-transactions'; +import { getGlobalEthQuery } from '../../../util/networks/global-network'; const LOG_PREFIX = 'Swaps'; const POLLING_INTERVAL = 30000; @@ -794,7 +795,7 @@ function SwapsQuotesView({ const updateSwapsTransactions = useCallback( async (transactionMeta, approvalTransactionMetaId) => { - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); const blockNumber = await query(ethQuery, 'blockNumber', []); const currentBlock = await query(ethQuery, 'getBlockByNumber', [ blockNumber, diff --git a/app/components/UI/TransactionElement/TransactionDetails/index.js b/app/components/UI/TransactionElement/TransactionDetails/index.js index 830b86d7856..e5201a6a234 100644 --- a/app/components/UI/TransactionElement/TransactionDetails/index.js +++ b/app/components/UI/TransactionElement/TransactionDetails/index.js @@ -47,6 +47,7 @@ import { selectTransactions, } from '../../../../selectors/transactionController'; import { swapsControllerTokens } from '../../../../reducers/swaps'; +import { getGlobalEthQuery } from '../../../../util/networks/global-network'; const createStyles = (colors) => StyleSheet.create({ @@ -144,7 +145,7 @@ class TransactionDetails extends PureComponent { }; fetchTxReceipt = async (transactionHash) => { - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); return await query(ethQuery, 'getTransactionReceipt', [transactionHash]); }; diff --git a/app/components/UI/Transactions/index.js b/app/components/UI/Transactions/index.js index 2a503836e2c..1c7797eeaba 100644 --- a/app/components/UI/Transactions/index.js +++ b/app/components/UI/Transactions/index.js @@ -25,6 +25,7 @@ import NotificationManager from '../../../core/NotificationManager'; import { collectibleContractsSelector } from '../../../reducers/collectibles'; import { selectChainId, + selectNetworkClientId, selectNetworkConfigurations, selectProviderConfig, selectProviderType, @@ -206,6 +207,10 @@ class Transactions extends PureComponent { */ onScrollThroughContent: PropTypes.func, gasFeeEstimates: PropTypes.object, + /** + * ID of the global network client + */ + networkClientId: PropTypes.string, }; static defaultProps = { @@ -341,9 +346,11 @@ class Transactions extends PureComponent { }; onRefresh = async () => { + const { networkClientId } = this.props; + this.setState({ refreshing: true }); - await updateIncomingTransactions(); + await updateIncomingTransactions([networkClientId]); this.setState({ refreshing: false }); }; @@ -565,7 +572,7 @@ class Transactions extends PureComponent { const onConfirmation = (isComplete) => { if (isComplete) { transaction.speedUpParams && - transaction.speedUpParams?.type === 'SpeedUp' + transaction.speedUpParams?.type === 'SpeedUp' ? this.onSpeedUpCompleted() : this.onCancelCompleted(); } @@ -751,8 +758,8 @@ class Transactions extends PureComponent { const transactions = submittedTransactions && submittedTransactions.length ? submittedTransactions - .sort((a, b) => b.time - a.time) - .concat(confirmedTransactions) + .sort((a, b) => b.time - a.time) + .concat(confirmedTransactions) : this.props.transactions; const renderRetryGas = (rate) => { @@ -900,6 +907,7 @@ class Transactions extends PureComponent { const mapStateToProps = (state) => ({ accounts: selectAccounts(state), chainId: selectChainId(state), + networkClientId: selectNetworkClientId(state), collectibleContracts: collectibleContractsSelector(state), contractExchangeRates: selectContractExchangeRates(state), conversionRate: selectConversionRate(state), diff --git a/app/components/Views/Asset/index.js b/app/components/Views/Asset/index.js index 7327ebe78a3..bbe4fba74ce 100644 --- a/app/components/Views/Asset/index.js +++ b/app/components/Views/Asset/index.js @@ -23,6 +23,7 @@ import { } from '../../../reducers/swaps'; import { selectChainId, + selectNetworkClientId, selectNetworkConfigurations, selectRpcUrl, } from '../../../selectors/networkController'; @@ -157,6 +158,10 @@ class Asset extends PureComponent { * Boolean that indicates if native token is supported to buy */ isNetworkBuyNativeTokenSupported: PropTypes.bool, + /** + * ID of the global network client + */ + networkClientId: PropTypes.string, }; state = { @@ -428,9 +433,11 @@ class Asset extends PureComponent { }; onRefresh = async () => { + const { networkClientId } = this.props; + this.setState({ refreshing: true }); - await updateIncomingTransactions(); + await updateIncomingTransactions([networkClientId]); this.setState({ refreshing: false }); }; @@ -521,6 +528,7 @@ const mapStateToProps = (state) => ({ selectChainId(state), getRampNetworks(state), ), + networkClientId: selectNetworkClientId(state), }); export default connect(mapStateToProps)(withMetricsAwareness(Asset)); diff --git a/app/components/Views/NetworkSelector/NetworkSelector.tsx b/app/components/Views/NetworkSelector/NetworkSelector.tsx index 21bf02d1b71..364a9923fb7 100644 --- a/app/components/Views/NetworkSelector/NetworkSelector.tsx +++ b/app/components/Views/NetworkSelector/NetworkSelector.tsx @@ -384,7 +384,7 @@ const NetworkSelector = () => { AccountTrackerController.refresh(); setTimeout(async () => { - await updateIncomingTransactions(); + await updateIncomingTransactions([clientId]); }, 1000); } diff --git a/app/components/Views/Settings/AdvancedSettings/index.js b/app/components/Views/Settings/AdvancedSettings/index.js index 6f7da7c6191..c54160f32fd 100644 --- a/app/components/Views/Settings/AdvancedSettings/index.js +++ b/app/components/Views/Settings/AdvancedSettings/index.js @@ -237,7 +237,7 @@ class AdvancedSettings extends PureComponent { resetAccount = () => { const { navigation } = this.props; - wipeTransactions(true); + wipeTransactions(); navigation.navigate('WalletView'); }; diff --git a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js index 2833c06f795..21c7659023a 100644 --- a/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js +++ b/app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js @@ -1540,7 +1540,7 @@ export class NetworkSettings extends PureComponent { NetworkController.setActiveNetwork(networkClientId); setTimeout(async () => { - await updateIncomingTransactions(); + await updateIncomingTransactions([networkClientId]); }, 1000); }; diff --git a/app/components/Views/Settings/NetworksSettings/index.js b/app/components/Views/Settings/NetworksSettings/index.js index 56a1b062165..94f55a5e114 100644 --- a/app/components/Views/Settings/NetworksSettings/index.js +++ b/app/components/Views/Settings/NetworksSettings/index.js @@ -191,7 +191,7 @@ class NetworksSettings extends PureComponent { NetworkController.setProviderType(MAINNET); setTimeout(async () => { - await updateIncomingTransactions(); + await updateIncomingTransactions([MAINNET]); }, 1000); }; diff --git a/app/core/DeeplinkManager/TransactionManager/approveTransaction.ts b/app/core/DeeplinkManager/TransactionManager/approveTransaction.ts index 72b5307fd8d..bf7ed7d8f76 100644 --- a/app/core/DeeplinkManager/TransactionManager/approveTransaction.ts +++ b/app/core/DeeplinkManager/TransactionManager/approveTransaction.ts @@ -9,6 +9,7 @@ import Engine from '../../Engine'; import NotificationManager from '../../NotificationManager'; import { WalletDevice } from '@metamask/transaction-controller'; import { toChecksumHexAddress } from '@metamask/controller-utils'; +import { getGlobalNetworkClientId } from '../../../util/networks/global-network'; async function approveTransaction({ deeplinkManager, @@ -60,8 +61,11 @@ async function approveTransaction({ data: generateApprovalData({ spender: spenderAddress, value }), }; + const networkClientId = getGlobalNetworkClientId(); + addTransaction(txParams, { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId, origin, }); } diff --git a/app/core/Engine.ts b/app/core/Engine.ts index 55d6fdbf2e3..e45d966dcdc 100644 --- a/app/core/Engine.ts +++ b/app/core/Engine.ts @@ -247,7 +247,6 @@ import { submitSmartTransactionHook } from '../util/smart-transactions/smart-pub import { zeroAddress } from 'ethereumjs-util'; import { ApprovalType, toChecksumHexAddress } from '@metamask/controller-utils'; import { ExtendedControllerMessenger } from './ExtendedControllerMessenger'; -import EthQuery from '@metamask/eth-query'; import DomainProxyMap from '../lib/DomainProxyMap/DomainProxyMap'; import { MetaMetricsEventCategory, @@ -269,6 +268,10 @@ import { trace } from '../util/trace'; import { MetricsEventBuilder } from './Analytics/MetricsEventBuilder'; import { JsonMap } from './Analytics/MetaMetrics.types'; import { isPooledStakingFeatureEnabled } from '../components/UI/Stake/constants'; +import { + getGlobalChainId, + getGlobalNetworkClientId, +} from '../util/networks/global-network'; const NON_EMPTY = 'NON_EMPTY'; @@ -592,9 +595,7 @@ export class Engine { 'NetworkController:networkDidChange', ], }), - chainId: networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(networkController), }); const accountsControllerMessenger: AccountsControllerMessenger = this.controllerMessenger.getRestricted({ @@ -624,9 +625,7 @@ export class Engine { }); const nftController = new NftController({ - chainId: networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(networkController), useIpfsSubdomains: false, messenger: this.controllerMessenger.getRestricted({ name: 'NftController', @@ -663,9 +662,7 @@ export class Engine { state: initialState.LoggingController, }); const tokensController = new TokensController({ - chainId: networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(networkController), // @ts-expect-error at this point in time the provider will be defined by the `networkController.initializeProvider` provider: networkController.getProviderAndBlockTracker().provider, state: initialState.TokensController, @@ -686,9 +683,7 @@ export class Engine { }), }); const tokenListController = new TokenListController({ - chainId: networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(networkController), onNetworkStateChange: (listener) => this.controllerMessenger.subscribe( AppConstants.NETWORK_STATE_CHANGE_EVENT, @@ -726,9 +721,7 @@ export class Engine { getCurrentNetworkEIP1559Compatibility: async () => (await networkController.getEIP1559Compatibility()) ?? false, getCurrentNetworkLegacyGasAPICompatibility: () => { - const chainId = networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId; + const chainId = getGlobalChainId(networkController); return ( isMainnetByChainId(chainId) || chainId === addHexPrefix(swapsUtils.BSC_CHAIN_ID) || @@ -1350,8 +1343,6 @@ export class Engine { ///: END:ONLY_INCLUDE_IF this.transactionController = new TransactionController({ - // @ts-expect-error at this point in time the provider will be defined by the `networkController.initializeProvider` - blockTracker: networkController.getProviderAndBlockTracker().blockTracker, disableHistory: true, disableSendFlowHistory: true, disableSwaps: true, @@ -1391,9 +1382,7 @@ export class Engine { }, incomingTransactions: { isEnabled: () => { - const currentHexChainId = networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId; + const currentHexChainId = getGlobalChainId(networkController); const showIncomingTransactions = preferencesController?.state?.showIncomingTransactions; @@ -1417,16 +1406,9 @@ export class Engine { ], allowedEvents: [`NetworkController:stateChange`], }), - onNetworkStateChange: (listener) => - this.controllerMessenger.subscribe( - AppConstants.NETWORK_STATE_CHANGE_EVENT, - listener, - ), pendingTransactions: { isResubmitEnabled: () => false, }, - // @ts-expect-error at this point in time the provider will be defined by the `networkController.initializeProvider` - provider: networkController.getProviderAndBlockTracker().provider, sign: this.keyringController.signTransaction.bind( this.keyringController, ) as unknown as TransactionControllerOptions['sign'], @@ -1466,6 +1448,7 @@ export class Engine { getNonceLock: this.transactionController.getNonceLock.bind( this.transactionController, ), + // @ts-expect-error TODO: resolve types confirmExternalTransaction: this.transactionController.confirmExternalTransaction.bind( this.transactionController, @@ -1531,11 +1514,7 @@ export class Engine { { token_standard: 'ERC20', asset_type: 'token', - chain_id: getDecimalChainId( - networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, - ), + chain_id: getDecimalChainId(getGlobalChainId(networkController)), }, ), getBalancesInSingleCall: @@ -1663,9 +1642,7 @@ export class Engine { ///: END:ONLY_INCLUDE_IF accountsController, new PPOMController({ - chainId: networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(networkController), blockaidPublicKey: process.env.BLOCKAID_PUBLIC_KEY as string, cdnBaseUrl: process.env.BLOCKAID_FILE_CDN as string, messenger: this.controllerMessenger.getRestricted({ @@ -1750,16 +1727,12 @@ export class Engine { if ( state.networksMetadata[state.selectedNetworkClientId].status === NetworkStatus.Available && - networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId !== currentChainId + getGlobalChainId(networkController) !== currentChainId ) { // We should add a state or event emitter saying the provider changed setTimeout(() => { this.configureControllersOnNetworkChange(); - currentChainId = networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId; + currentChainId = getGlobalChainId(networkController); }, 500); } }, @@ -1774,11 +1747,7 @@ export class Engine { } catch (error) { console.error( error, - `Network ID not changed, current chainId: ${ - networkController.getNetworkClientById( - networkController?.state.selectedNetworkClientId, - ).configuration.chainId - }`, + `Network ID not changed, current chainId: ${getGlobalChainId(networkController)}`, ); } }, @@ -1931,9 +1900,7 @@ export class Engine { SwapsController.configure({ provider, - chainId: NetworkController.getNetworkClientById( - NetworkController?.state.selectedNetworkClientId, - ).configuration.chainId, + chainId: getGlobalChainId(NetworkController), pollCountLimit: AppConstants.SWAPS.POLL_COUNT_LIMIT, }); AccountTrackerController.refresh(); @@ -1964,7 +1931,7 @@ export class Engine { toChecksumHexAddress(selectedInternalAccount.address); const { currentCurrency } = CurrencyRateController.state; const { chainId, ticker } = NetworkController.getNetworkClientById( - NetworkController?.state.selectedNetworkClientId, + getGlobalNetworkClientId(NetworkController), ).configuration; const { settings: { showFiatOnTestnets } = {} } = store.getState(); @@ -1991,13 +1958,19 @@ export class Engine { selectSelectedInternalAccountChecksummedAddress ] ) { - const balanceBN = hexToBN(accountsByChainId[toHexadecimal(chainId)][ - selectSelectedInternalAccountChecksummedAddress - ].balance); - const stakedBalanceBN = hexToBN(accountsByChainId[toHexadecimal(chainId)][ - selectSelectedInternalAccountChecksummedAddress - ].stakedBalance || '0x00'); - const totalAccountBalance = balanceBN.add(stakedBalanceBN).toString('hex'); + const balanceBN = hexToBN( + accountsByChainId[toHexadecimal(chainId)][ + selectSelectedInternalAccountChecksummedAddress + ].balance, + ); + const stakedBalanceBN = hexToBN( + accountsByChainId[toHexadecimal(chainId)][ + selectSelectedInternalAccountChecksummedAddress + ].stakedBalance || '0x00', + ); + const totalAccountBalance = balanceBN + .add(stakedBalanceBN) + .toString('hex'); ethFiat = weiToFiatNumber( totalAccountBalance, conversionRate, @@ -2267,17 +2240,6 @@ export class Engine { AccountsController.setAccountName(accountToBeNamed.id, label); PreferencesController.setAccountLabel(address, label); } - - getGlobalEthQuery(): EthQuery { - const { NetworkController } = this.context; - const { provider } = NetworkController.getSelectedNetworkClient() ?? {}; - - if (!provider) { - throw new Error('No selected network client'); - } - - return new EthQuery(provider); - } } /** @@ -2447,10 +2409,6 @@ export default { instance.setAccountLabel(address, label); }, - getGlobalEthQuery: (): EthQuery => { - assertEngineExists(instance); - return instance.getGlobalEthQuery(); - }, ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) getSnapKeyring: () => { assertEngineExists(instance); diff --git a/app/core/NotificationManager.js b/app/core/NotificationManager.js index 22af910e519..9c6c362a5e1 100644 --- a/app/core/NotificationManager.js +++ b/app/core/NotificationManager.js @@ -409,9 +409,7 @@ class NotificationManager { const ticker = useSelector(selectTicker); /// Find the incoming TX - const transactions = TransactionController.getTransactions({ - filterToCurrentNetwork: false, - }); + const transactions = TransactionController.getTransactions(); // If a TX has been confirmed more than 10 min ago, it's considered old const oldestTimeAllowed = Date.now() - 1000 * 60 * 10; diff --git a/app/core/RPCMethods/eth_sendTransaction.test.ts b/app/core/RPCMethods/eth_sendTransaction.test.ts index 89e3c154b1f..1490d436e42 100644 --- a/app/core/RPCMethods/eth_sendTransaction.test.ts +++ b/app/core/RPCMethods/eth_sendTransaction.test.ts @@ -41,6 +41,8 @@ jest.mock('../../util/transaction-controller', () => ({ updateTransaction: jest.fn(), })); +const NETWORK_CLIENT_ID_MOCK = 'testNetworkClientId'; + /** * Construct a `eth_sendTransaction` JSON-RPC request. * @@ -49,11 +51,15 @@ jest.mock('../../util/transaction-controller', () => ({ */ function constructSendTransactionRequest( params: unknown, -): JsonRpcRequest & { method: 'eth_sendTransaction' } { +): JsonRpcRequest & { + method: 'eth_sendTransaction'; + networkClientId: string; +} { return { jsonrpc: '2.0', id: 1, method: 'eth_sendTransaction', + networkClientId: 'testNetworkClientId', params, }; } @@ -154,7 +160,10 @@ describe('eth_sendTransaction', () => { res: pendingResult, sendTransaction: getMockAddTransaction({ expectedTransaction: mockTransactionParameters, - expectedOrigin: { origin: 'example.metamask.io' }, + expectedOrigin: { + origin: 'example.metamask.io', + networkClientId: NETWORK_CLIENT_ID_MOCK, + }, returnValue: expectedResult, }), validateAccountAndChainId: jest.fn(), @@ -239,7 +248,10 @@ describe('eth_sendTransaction', () => { res: constructPendingJsonRpcResponse(), sendTransaction: getMockAddTransaction({ expectedTransaction: mockTransactionParameters, - expectedOrigin: { origin: 'example.metamask.io' }, + expectedOrigin: { + origin: 'example.metamask.io', + networkClientId: NETWORK_CLIENT_ID_MOCK, + }, addTransactionError: new Error('Failed to add transaction'), }), validateAccountAndChainId: jest.fn(), @@ -259,7 +271,10 @@ describe('eth_sendTransaction', () => { res: constructPendingJsonRpcResponse(), sendTransaction: getMockAddTransaction({ expectedTransaction: mockTransactionParameters, - expectedOrigin: { origin: 'example.metamask.io' }, + expectedOrigin: { + origin: 'example.metamask.io', + networkClientId: NETWORK_CLIENT_ID_MOCK, + }, processTransactionError: new Error('User rejected the transaction'), }), validateAccountAndChainId: jest.fn(), @@ -280,7 +295,10 @@ describe('eth_sendTransaction', () => { res: pendingResult, sendTransaction: getMockAddTransaction({ expectedTransaction: mockTransactionParameters, - expectedOrigin: { origin: 'example.metamask.io' }, + expectedOrigin: { + origin: 'example.metamask.io', + networkClientId: NETWORK_CLIENT_ID_MOCK, + }, returnValue: expectedResult, }), validateAccountAndChainId: jest.fn(), diff --git a/app/core/RPCMethods/eth_sendTransaction.ts b/app/core/RPCMethods/eth_sendTransaction.ts index 465cc87b51d..defb22b9280 100644 --- a/app/core/RPCMethods/eth_sendTransaction.ts +++ b/app/core/RPCMethods/eth_sendTransaction.ts @@ -66,7 +66,10 @@ async function eth_sendTransaction({ validateAccountAndChainId, }: { hostname: string; - req: JsonRpcRequest & { method: 'eth_sendTransaction' }; + req: JsonRpcRequest & { + method: 'eth_sendTransaction'; + networkClientId: string; + }; res: PendingJsonRpcResponse; sendTransaction: TransactionController['addTransaction']; validateAccountAndChainId: (args: { @@ -95,6 +98,7 @@ async function eth_sendTransaction({ const { result, transactionMeta } = await sendTransaction(req.params[0], { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId: req.networkClientId, origin: hostname, }); diff --git a/app/core/WalletConnect/WalletConnect2Session.ts b/app/core/WalletConnect/WalletConnect2Session.ts index ff3613e63ff..7e0914e3498 100644 --- a/app/core/WalletConnect/WalletConnect2Session.ts +++ b/app/core/WalletConnect/WalletConnect2Session.ts @@ -512,6 +512,7 @@ class WalletConnect2Session { origin, deviceConfirmedOn: WalletDevice.MM_MOBILE, securityAlertResponse: undefined, + networkClientId: 'testNetworkClientId', }); const id = trx.transactionMeta.id; diff --git a/app/util/blockaid/index.test.ts b/app/util/blockaid/index.test.ts index 4c8b403849f..612982fd4bb 100644 --- a/app/util/blockaid/index.test.ts +++ b/app/util/blockaid/index.test.ts @@ -54,6 +54,7 @@ describe('Blockaid util', () => { error: new Error('Simulated transaction error'), id: '1', chainId: '0x1', + networkClientId: 'testNetworkClientId', time: Date.now(), txParams: { from: '0x1', @@ -82,6 +83,7 @@ describe('Blockaid util', () => { error: new Error('Simulated transaction error'), id: '1', chainId: '0x1', + networkClientId: 'testNetworkClientId', time: Date.now(), txParams: { from: '0x1', diff --git a/app/util/dappTransactions/index.ts b/app/util/dappTransactions/index.ts index d2d93d8fd74..ee3fa87e170 100644 --- a/app/util/dappTransactions/index.ts +++ b/app/util/dappTransactions/index.ts @@ -28,6 +28,7 @@ interface Transaction { gas: BN; gasPrice: BN; id: string; + networkClientId: string; nonce: string | undefined; origin: string; paymentRequest: boolean | undefined; @@ -67,7 +68,7 @@ export const estimateGas = async ( opts: opts, transaction: Transaction, ): Promise => { - const { from, selectedAsset } = transaction; + const { from, networkClientId, selectedAsset } = transaction; const { amount = transaction.value, data = transaction.data, @@ -81,7 +82,7 @@ export const estimateGas = async ( from, data, to: selectedAsset?.address ? selectedAsset.address : to, - }); + }, networkClientId); } catch (e) { estimation = { gas: TransactionTypes.CUSTOM_GAS.DEFAULT_GAS_LIMIT, diff --git a/app/util/importAdditionalAccounts.js b/app/util/importAdditionalAccounts.js index 9b015ce661b..b1a2bcf089b 100644 --- a/app/util/importAdditionalAccounts.js +++ b/app/util/importAdditionalAccounts.js @@ -2,6 +2,7 @@ import Engine from '../core/Engine'; import { BNToHex } from '../util/number'; import Logger from '../util/Logger'; import ExtendedKeyringTypes from '../../app/constants/keyringTypes'; +import { getGlobalEthQuery } from './networks/global-network'; const HD_KEY_TREE_ERROR = 'MetamaskController - No HD Key Tree found'; const ZERO_BALANCE = '0x0'; @@ -31,7 +32,7 @@ const getBalance = async (address, ethQuery) => export default async () => { const { KeyringController } = Engine.context; - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); let accounts = await KeyringController.getAccounts(); let lastBalance = await getBalance(accounts[accounts.length - 1], ethQuery); diff --git a/app/util/networks/global-network.ts b/app/util/networks/global-network.ts new file mode 100644 index 00000000000..9ae2671c1ea --- /dev/null +++ b/app/util/networks/global-network.ts @@ -0,0 +1,50 @@ +import EthQuery from '@metamask/eth-query'; +import { + NetworkClientId, + NetworkController, +} from '@metamask/network-controller'; +import { Hex } from '@metamask/utils'; +import Engine from '../../core/Engine'; + +/** + * @deprecated Avoid new references to the global network. + * Will be removed once multi-chain support is fully implemented. + * @returns An instance of EthQuery for the currently selected network. + */ +export function getGlobalEthQuery( + networkController?: NetworkController, +): EthQuery { + const finalController = networkController ?? Engine.context.NetworkController; + const { provider } = finalController.getSelectedNetworkClient() ?? {}; + + if (!provider) { + throw new Error('No selected network client'); + } + + return new EthQuery(provider); +} + +/** + * @deprecated Avoid new references to the global network. + * Will be removed once multi-chain support is fully implemented. + * @returns The chain ID of the currently selected network. + */ +export function getGlobalChainId(networkController?: NetworkController): Hex { + const finalController = networkController ?? Engine.context.NetworkController; + + return finalController.getNetworkClientById( + getGlobalNetworkClientId(finalController), + ).configuration.chainId; +} + +/** + * @deprecated Avoid new references to the global network. + * Will be removed once multi-chain support is fully implemented. + * @returns The ID of the currently selected network client. + */ +export function getGlobalNetworkClientId( + networkController?: NetworkController, +): NetworkClientId { + const finalController = networkController ?? Engine.context.NetworkController; + return finalController.state.selectedNetworkClientId; +} diff --git a/app/util/networks/index.js b/app/util/networks/index.js index 62491502031..f398abaa5a7 100644 --- a/app/util/networks/index.js +++ b/app/util/networks/index.js @@ -369,8 +369,8 @@ export function isPrefixedFormattedHexString(value) { return regex.prefixedFormattedHexString.test(value); } -export const getNetworkNonce = async ({ from }) => { - const { nextNonce, releaseLock } = await getNonceLock(from); +export const getNetworkNonce = async ({ from, networkClientId }) => { + const { nextNonce, releaseLock } = await getNonceLock(from, networkClientId); releaseLock(); diff --git a/app/util/networks/index.test.ts b/app/util/networks/index.test.ts index bd31f18b947..1aaa75c061d 100644 --- a/app/util/networks/index.test.ts +++ b/app/util/networks/index.test.ts @@ -369,6 +369,7 @@ describe('network-utils', () => { describe('getNetworkNonce', () => { const nonceMock = 123; const fromMock = '0x123'; + const networkClientIdMock = 'testNetworkClientId'; it('returns value from TransactionController', async () => { (getNonceLock as jest.Mock).mockReturnValueOnce({ @@ -376,7 +377,12 @@ describe('network-utils', () => { releaseLock: jest.fn(), }); - expect(await getNetworkNonce({ from: fromMock })).toBe(nonceMock); + expect( + await getNetworkNonce({ + from: fromMock, + networkClientId: networkClientIdMock, + }), + ).toBe(nonceMock); expect(getNonceLock).toHaveBeenCalledWith(fromMock); }); @@ -388,7 +394,10 @@ describe('network-utils', () => { releaseLock: releaseLockMock, }); - await getNetworkNonce({ from: fromMock }); + await getNetworkNonce({ + from: fromMock, + networkClientId: networkClientIdMock, + }); expect(releaseLockMock).toHaveBeenCalledTimes(1); }); diff --git a/app/util/smart-transactions/index.test.ts b/app/util/smart-transactions/index.test.ts index 0cbb132a88d..88ca79bac21 100644 --- a/app/util/smart-transactions/index.test.ts +++ b/app/util/smart-transactions/index.test.ts @@ -16,6 +16,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: '52fd9ae0-098f-11ef-949b-c3c3278f64e5', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'MetaMask Mobile', rawTransaction: @@ -53,6 +54,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: '07178fe0-0990-11ef-96e6-c3c3278f64e5', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'MetaMask Mobile', rawTransaction: @@ -91,6 +93,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: 'a3551450-098f-11ef-95ae-c3c3278f64e5', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'app.uniswap.org', rawTransaction: @@ -128,6 +131,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: 'a3551450-098f-11ef-95ae-c3c3278f64e5', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'app.uniswap.org', rawTransaction: @@ -165,6 +169,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: 'b3095a90-0990-11ef-9909-c3c3278f64e5', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'EXAMPLE_FOX_CODE', rawTransaction: @@ -203,6 +208,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: '15879650-0991-11ef-9ce4-2f3037ea41a6', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'EXAMPLE_FOX_CODE', rawTransaction: @@ -241,6 +247,7 @@ describe('Smart Transactions utils', () => { deviceConfirmedOn: 'metamask_mobile', gasFeeEstimatesLoaded: true, id: '1587e470-0991-11ef-9ce4-2f3037ea41a6', + networkClientId: 'testNetworkClientId', networkID: undefined, origin: 'EXAMPLE_FOX_CODE', rawTransaction: diff --git a/app/util/smart-transactions/smart-publish-hook.test.ts b/app/util/smart-transactions/smart-publish-hook.test.ts index 0a902572214..89f52a576d8 100644 --- a/app/util/smart-transactions/smart-publish-hook.test.ts +++ b/app/util/smart-transactions/smart-publish-hook.test.ts @@ -100,6 +100,7 @@ const defaultTransactionMeta: TransactionMeta = { }, type: TransactionType.simpleSend, chainId: ChainId.mainnet, + networkClientId: 'testNetworkClientId', time: 1624408066355, // defaultGasEstimates: { // gas: '0x7b0d', diff --git a/app/util/transaction-controller/index.test.ts b/app/util/transaction-controller/index.test.ts index dd4636e5161..da2d9bea9ce 100644 --- a/app/util/transaction-controller/index.test.ts +++ b/app/util/transaction-controller/index.test.ts @@ -7,8 +7,11 @@ const { addTransaction, estimateGas, ...proxyMethods } = TransactionControllerUtils; const TRANSACTION_MOCK = { from: '0x0', to: '0x1', value: '0x0' }; +const NETWORK_CLIENT_ID_MOCK = 'testNetworkClientId'; + const TRANSACTION_OPTIONS_MOCK = { deviceConfirmedOn: WalletDevice.MM_MOBILE, + networkClientId: NETWORK_CLIENT_ID_MOCK, origin: 'origin', }; @@ -49,7 +52,7 @@ describe('Transaction Controller Util', () => { describe('estimateGas', () => { it('should call estimateGas with correct parameters', async () => { - await estimateGas(TRANSACTION_MOCK); + await estimateGas(TRANSACTION_MOCK, NETWORK_CLIENT_ID_MOCK); expect( Engine.context.TransactionController.estimateGas, diff --git a/app/util/transaction-controller/index.ts b/app/util/transaction-controller/index.ts index 34d52c60776..67f83c0c483 100644 --- a/app/util/transaction-controller/index.ts +++ b/app/util/transaction-controller/index.ts @@ -4,6 +4,7 @@ import { } from '@metamask/transaction-controller'; import Engine from '../../core/Engine'; +import { NetworkClientId } from '@metamask/network-controller'; // Keeping this export as function to put more logic in the future export async function addTransaction( @@ -15,11 +16,9 @@ export async function addTransaction( return await TransactionController.addTransaction(transaction, opts); } -// Keeping this export as function to put more logic in the future -export async function estimateGas(transaction: TransactionParams) { +export async function estimateGas(transaction: TransactionParams, networkClientId: NetworkClientId) { const { TransactionController } = Engine.context; - - return await TransactionController.estimateGas(transaction); + return await TransactionController.estimateGas(transaction, networkClientId); } // Proxy methods diff --git a/app/util/transactions/index.js b/app/util/transactions/index.js index a04aa9f7ebf..4d711b187de 100644 --- a/app/util/transactions/index.js +++ b/app/util/transactions/index.js @@ -50,6 +50,7 @@ import { import Logger from '../../util/Logger'; import { handleMethodData } from '../../util/transaction-controller'; +import { getGlobalEthQuery } from '../networks/global-network'; const { SAI_ADDRESS } = AppConstants; @@ -314,7 +315,7 @@ export function decodeTransferData(type, data) { * @param {string} data - Transaction data * @returns {MethodData} - Method data object containing the name if is valid */ -export async function getMethodData(data) { +export async function getMethodData(data, networkClientId) { if (data.length < 10) return {}; const fourByteSignature = getFourByteSignature(data); if (fourByteSignature === TRANSFER_FUNCTION_SIGNATURE) { @@ -332,7 +333,7 @@ export async function getMethodData(data) { } // If it's a new method, use on-chain method registry try { - const registryObject = await handleMethodData(fourByteSignature); + const registryObject = await handleMethodData(fourByteSignature, networkClientId); if (registryObject) { return registryObject.parsedRegistryMethod; } @@ -360,7 +361,7 @@ export async function isSmartContractAddress(address, chainId) { return Promise.resolve(true); } - const ethQuery = Engine.getGlobalEthQuery(); + const ethQuery = getGlobalEthQuery(); const code = address ? await query(ethQuery, 'getCode', [address]) @@ -401,7 +402,7 @@ export async function isCollectibleAddress(address, tokenId) { * @returns {string} - Corresponding transaction action key */ export async function getTransactionActionKey(transaction, chainId) { - const { type } = transaction ?? {}; + const { networkClientId, type } = transaction ?? {}; const txParams = transaction.txParams ?? transaction.transaction ?? {}; const { data, to } = txParams; @@ -419,7 +420,7 @@ export async function getTransactionActionKey(transaction, chainId) { // if data in transaction try to get method data if (data && data !== '0x') { - const { name } = await getMethodData(data); + const { name } = await getMethodData(data, networkClientId); if (name) return name; } diff --git a/app/util/transactions/index.test.ts b/app/util/transactions/index.test.ts index 76bef96a7bc..c16dd7654e4 100644 --- a/app/util/transactions/index.test.ts +++ b/app/util/transactions/index.test.ts @@ -63,6 +63,7 @@ const UNI_TICKER = 'UNI'; const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'; const MOCK_CHAIN_ID = '1'; +const MOCK_NETWORK_CLIENT_ID = 'testNetworkClientId'; const spyOnQueryMethod = (returnValue: string | undefined) => jest.spyOn(controllerUtilsModule, 'query').mockImplementation( @@ -304,17 +305,37 @@ describe('Transactions utils :: getMethodData', () => { const increaseAllowanceDataMock = `${INCREASE_ALLOWANCE_SIGNATURE}0000000000000000000000000000`; const setApprovalForAllDataMock = `${SET_APPROVAL_FOR_ALL_SIGNATURE}0000000000000000000000000000`; const approveDataMock = `${APPROVE_FUNCTION_SIGNATURE}000000000000000000000000`; - const invalidMethodData = await getMethodData(invalidData); - const transferMethodData = await getMethodData(transferData); - const deployMethodData = await getMethodData(deployData); - const transferFromMethodData = await getMethodData(transferFromData); - const randomMethodData = await getMethodData(randomData); - const approvalMethodData = await getMethodData(approveDataMock); + const invalidMethodData = await getMethodData( + invalidData, + MOCK_NETWORK_CLIENT_ID, + ); + const transferMethodData = await getMethodData( + transferData, + MOCK_NETWORK_CLIENT_ID, + ); + const deployMethodData = await getMethodData( + deployData, + MOCK_NETWORK_CLIENT_ID, + ); + const transferFromMethodData = await getMethodData( + transferFromData, + MOCK_NETWORK_CLIENT_ID, + ); + const randomMethodData = await getMethodData( + randomData, + MOCK_NETWORK_CLIENT_ID, + ); + const approvalMethodData = await getMethodData( + approveDataMock, + MOCK_NETWORK_CLIENT_ID, + ); const increaseAllowanceMethodData = await getMethodData( increaseAllowanceDataMock, + MOCK_NETWORK_CLIENT_ID, ); const setApprovalForAllMethodData = await getMethodData( setApprovalForAllDataMock, + MOCK_NETWORK_CLIENT_ID, ); expect(invalidMethodData).toEqual({}); expect(transferMethodData.name).toEqual(TOKEN_METHOD_TRANSFER); @@ -336,8 +357,11 @@ describe('Transactions utils :: getMethodData', () => { }); const transferData = '0xa9059cbb00000000000000000000000056ced0d816c668d7c0bcc3fbf0ab2c6896f589a'; - await getMethodData(transferData); - expect(handleMethodData).toHaveBeenCalledWith('0x98765432'); + await getMethodData(transferData, MOCK_NETWORK_CLIENT_ID); + expect(handleMethodData).toHaveBeenCalledWith( + '0x98765432', + MOCK_NETWORK_CLIENT_ID, + ); }); }); diff --git a/package.json b/package.json index 28ff2385193..af727a5ff49 100644 --- a/package.json +++ b/package.json @@ -190,7 +190,7 @@ "@metamask/stake-sdk": "^0.2.13", "@metamask/swappable-obj-proxy": "^2.1.0", "@metamask/swaps-controller": "^9.0.12", - "@metamask/transaction-controller": "^38.3.0", + "@metamask/transaction-controller": "npm:@metamask-previews/transaction-controller@39.0.0-preview-913113cf", "@metamask/utils": "^9.2.1", "@ngraveio/bc-ur": "^1.1.6", "@notifee/react-native": "^9.0.0", diff --git a/yarn.lock b/yarn.lock index a714ab0e966..c63a0a3de7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4523,6 +4523,22 @@ eth-ens-namehash "^2.0.8" fast-deep-equal "^3.1.3" +"@metamask/controller-utils@^11.4.3": + version "11.4.3" + resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-11.4.3.tgz#5763f0bbee2f3770c1ba42dd4869786afef849bd" + integrity sha512-shrVCHFwIbt8qVcKbxe/mp5tOxjz6905/7ZIAnwUJKHYv7iEqfjyO1ibPoOknrZCF2vbXtP21b435g3v9DBNTQ== + dependencies: + "@ethereumjs/util" "^8.1.0" + "@metamask/eth-query" "^4.0.0" + "@metamask/ethjs-unit" "^0.3.0" + "@metamask/utils" "^10.0.0" + "@spruceid/siwe-parser" "2.1.0" + "@types/bn.js" "^5.1.5" + bignumber.js "^9.1.2" + bn.js "^5.2.1" + eth-ens-namehash "^2.0.8" + fast-deep-equal "^3.1.3" + "@metamask/controller-utils@^8.0.1", "@metamask/controller-utils@^8.0.2", "@metamask/controller-utils@^8.0.4": version "8.0.4" resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-8.0.4.tgz#78a952301ff4b2a501b31865ab0de434c6ea3cd2" @@ -5690,10 +5706,10 @@ lodash "^4.17.21" uuid "^8.3.2" -"@metamask/transaction-controller@^38.3.0": - version "38.3.0" - resolved "https://registry.yarnpkg.com/@metamask/transaction-controller/-/transaction-controller-38.3.0.tgz#51d4c5739da004b0e498b40273f838ee6f17be04" - integrity sha512-Ogj534hgT6ng6iTL0Wf3aHf17kZcY0F1xHFdGX9fXLLkPeTEIPisiYbZrZhzT4N00QJzBt+RMVLoeg42H3cozw== +"@metamask/transaction-controller@npm:@metamask-previews/transaction-controller@39.0.0-preview-913113cf": + version "39.0.0-preview-913113cf" + resolved "https://registry.yarnpkg.com/@metamask-previews/transaction-controller/-/transaction-controller-39.0.0-preview-913113cf.tgz#c65ffb7dc8e9fb6579cc7f81ea763a45d6617975" + integrity sha512-66IchL3WnLuVbtqFEVrGpce5U5BLtRQWNTbFQfXLBZD3nBxIRM7yXIUQjRfcCQ2BonZhiSc45RkY2XIp8kJ2bw== dependencies: "@ethereumjs/common" "^3.2.0" "@ethereumjs/tx" "^4.2.0" @@ -5702,7 +5718,7 @@ "@ethersproject/contracts" "^5.7.0" "@ethersproject/providers" "^5.7.0" "@metamask/base-controller" "^7.0.2" - "@metamask/controller-utils" "^11.4.2" + "@metamask/controller-utils" "^11.4.3" "@metamask/eth-query" "^4.0.0" "@metamask/metamask-eth-abis" "^3.1.1" "@metamask/nonce-tracker" "^6.0.0"