From 2f42ea32ff22e45f18eec55f85881de080942f53 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 13:32:12 -0800 Subject: [PATCH 1/8] chore: rm swapsSlice from bridge reducer --- ui/ducks/bridge/bridge.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/ducks/bridge/bridge.ts b/ui/ducks/bridge/bridge.ts index 82bbba964868..58ebb52fbe57 100644 --- a/ui/ducks/bridge/bridge.ts +++ b/ui/ducks/bridge/bridge.ts @@ -1,6 +1,5 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { Hex } from '@metamask/utils'; -import { swapsSlice } from '../swaps/swaps'; import { BridgeToken, QuoteMetadata, @@ -57,7 +56,6 @@ const bridgeSlice = createSlice({ name: 'bridge', initialState: { ...initialState }, reducers: { - ...swapsSlice.reducer, setToChainId: (state, action) => { state.toChainId = action.payload; }, From b7a5a761a296ade5e7c47e70375ec1475ff992be Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 13:56:17 -0800 Subject: [PATCH 2/8] refactor: move bridge.util and types to shared directory --- .../controllers/bridge-status/utils.ts | 4 +- .../bridge/bridge-controller.test.ts | 8 +- .../controllers/bridge/bridge-controller.ts | 12 +- app/scripts/controllers/bridge/types.ts | 6 +- .../modules/bridge-utils}/bridge.util.test.ts | 6 +- .../modules/bridge-utils}/bridge.util.ts | 21 +-- shared/modules/bridge-utils/quote.ts | 36 ++++ .../modules/bridge-utils}/validators.ts | 7 +- shared/types/bridge-status.ts | 9 +- shared/types/bridge.ts | 154 +++++++++++++++++ test/e2e/tests/bridge/bridge-test-utils.ts | 2 +- test/e2e/tests/bridge/constants.ts | 2 +- ui/ducks/bridge/actions.ts | 2 +- ui/ducks/bridge/bridge.ts | 2 +- ui/ducks/bridge/selectors.test.ts | 2 +- ui/ducks/bridge/selectors.ts | 2 +- ui/ducks/bridge/utils.ts | 2 +- ui/hooks/bridge/useBridgeTokens.ts | 2 +- .../bridge/useCrossChainSwapsEventTracker.ts | 2 +- ui/hooks/bridge/useLatestBalance.test.ts | 2 +- ui/pages/bridge/hooks/useAddToken.ts | 2 +- ui/pages/bridge/hooks/useHandleApprovalTx.ts | 11 +- ui/pages/bridge/hooks/useHandleBridgeTx.ts | 2 +- ui/pages/bridge/hooks/useHandleTx.ts | 2 +- .../hooks/useSubmitBridgeTransaction.ts | 2 +- .../bridge/prepare/bridge-input-group.tsx | 2 +- .../bridge/prepare/prepare-bridge-page.tsx | 4 +- .../bridge/quotes/bridge-quotes-modal.tsx | 6 +- ui/pages/bridge/types.ts | 159 ------------------ ui/pages/bridge/utils/quote.ts | 41 +---- 30 files changed, 249 insertions(+), 265 deletions(-) rename {ui/pages/bridge => shared/modules/bridge-utils}/bridge.util.test.ts (98%) rename {ui/pages/bridge => shared/modules/bridge-utils}/bridge.util.ts (92%) create mode 100644 shared/modules/bridge-utils/quote.ts rename {ui/pages/bridge/utils => shared/modules/bridge-utils}/validators.ts (96%) delete mode 100644 ui/pages/bridge/types.ts diff --git a/app/scripts/controllers/bridge-status/utils.ts b/app/scripts/controllers/bridge-status/utils.ts index d8dbac9e1590..d68f0dfe8331 100644 --- a/app/scripts/controllers/bridge-status/utils.ts +++ b/app/scripts/controllers/bridge-status/utils.ts @@ -8,9 +8,7 @@ import { StatusRequestWithSrcTxHash, StatusRequestDto, } from '../../../../shared/types/bridge-status'; -// TODO fix this -// eslint-disable-next-line import/no-restricted-paths -import { Quote } from '../../../../ui/pages/bridge/types'; +import { Quote } from '../../../../shared/types/bridge'; import { validateResponse, validators } from './validators'; const CLIENT_ID_HEADER = { 'X-Client-Id': BRIDGE_CLIENT_ID }; diff --git a/app/scripts/controllers/bridge/bridge-controller.test.ts b/app/scripts/controllers/bridge/bridge-controller.test.ts index 3b0d095fa0c3..68a5e3f26179 100644 --- a/app/scripts/controllers/bridge/bridge-controller.test.ts +++ b/app/scripts/controllers/bridge/bridge-controller.test.ts @@ -5,16 +5,12 @@ import { BRIDGE_API_BASE_URL } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { SWAPS_API_V2_BASE_URL } from '../../../../shared/constants/swaps'; import { flushPromises } from '../../../../test/lib/timer-helpers'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import * as bridgeUtil from '../../../../ui/pages/bridge/bridge.util'; +import * as bridgeUtil from '../../../../shared/modules/bridge-utils/bridge.util'; import * as balanceUtils from '../../../../shared/modules/bridge-utils/balance'; import mockBridgeQuotesErc20Native from '../../../../test/data/bridge/mock-quotes-erc20-native.json'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; import mockBridgeQuotesNativeErc20Eth from '../../../../test/data/bridge/mock-quotes-native-erc20-eth.json'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { QuoteResponse } from '../../../../ui/pages/bridge/types'; +import { QuoteResponse } from '../../../../shared/types/bridge'; import { decimalToHex } from '../../../../shared/modules/conversion.utils'; import BridgeController from './bridge-controller'; import { BridgeControllerMessenger } from './types'; diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index 4770c342587c..1e00e9264fdf 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -12,9 +12,7 @@ import { fetchBridgeFeatureFlags, fetchBridgeQuotes, fetchBridgeTokens, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/bridge.util'; +} from '../../../../shared/modules/bridge-utils/bridge.util'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths import { fetchTopAssetsList } from '../../../../ui/pages/swaps/swaps.util'; @@ -27,12 +25,8 @@ import { QuoteRequest, QuoteResponse, TxData, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/types'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { isValidQuoteRequest } from '../../../../ui/pages/bridge/utils/quote'; +} from '../../../../shared/types/bridge'; +import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote'; import { hasSufficientBalance } from '../../../../shared/modules/bridge-utils/balance'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index 7cdfa43cabd0..aeeae7a0317a 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -13,10 +13,8 @@ import { L1GasFees, QuoteRequest, QuoteResponse, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/types'; -import { ChainConfiguration } from '../../../../shared/types/bridge'; + ChainConfiguration, +} from '../../../../shared/types/bridge'; import BridgeController from './bridge-controller'; import { BRIDGE_CONTROLLER_NAME, RequestStatus } from './constants'; diff --git a/ui/pages/bridge/bridge.util.test.ts b/shared/modules/bridge-utils/bridge.util.test.ts similarity index 98% rename from ui/pages/bridge/bridge.util.test.ts rename to shared/modules/bridge-utils/bridge.util.test.ts index f302cd44090c..555de4fc2516 100644 --- a/ui/pages/bridge/bridge.util.test.ts +++ b/shared/modules/bridge-utils/bridge.util.test.ts @@ -1,8 +1,8 @@ -import fetchWithCache from '../../../shared/lib/fetch-with-cache'; -import { CHAIN_IDS } from '../../../shared/constants/network'; +import { zeroAddress } from 'ethereumjs-util'; +import fetchWithCache from '../../lib/fetch-with-cache'; +import { CHAIN_IDS } from '../../constants/network'; import mockBridgeQuotesErc20Erc20 from '../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../test/data/bridge/mock-quotes-native-erc20.json'; -import { zeroAddress } from '../../__mocks__/ethereumjs-util'; import { fetchBridgeFeatureFlags, fetchBridgeQuotes, diff --git a/ui/pages/bridge/bridge.util.ts b/shared/modules/bridge-utils/bridge.util.ts similarity index 92% rename from ui/pages/bridge/bridge.util.ts rename to shared/modules/bridge-utils/bridge.util.ts index 534ea3418219..9543cbcb979d 100644 --- a/ui/pages/bridge/bridge.util.ts +++ b/shared/modules/bridge-utils/bridge.util.ts @@ -12,25 +12,22 @@ import { BRIDGE_CLIENT_ID, ETH_USDT_ADDRESS, METABRIDGE_ETHEREUM_ADDRESS, -} from '../../../shared/constants/bridge'; -import { MINUTE } from '../../../shared/constants/time'; -import fetchWithCache from '../../../shared/lib/fetch-with-cache'; -import { - decimalToHex, - hexToDecimal, -} from '../../../shared/modules/conversion.utils'; +} from '../../constants/bridge'; +import { MINUTE } from '../../constants/time'; +import fetchWithCache from '../../lib/fetch-with-cache'; +import { decimalToHex, hexToDecimal } from '../conversion.utils'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP, SwapsTokenObject, -} from '../../../shared/constants/swaps'; +} from '../../constants/swaps'; import { isSwapsDefaultTokenAddress, isSwapsDefaultTokenSymbol, -} from '../../../shared/modules/swaps.utils'; +} from '../swaps.utils'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths import { REFRESH_INTERVAL_MS } from '../../../app/scripts/controllers/bridge/constants'; -import { CHAIN_IDS } from '../../../shared/constants/network'; +import { CHAIN_IDS } from '../../constants/network'; import { BridgeAsset, BridgeFlag, @@ -41,7 +38,7 @@ import { QuoteRequest, QuoteResponse, TxData, -} from './types'; +} from '../../types/bridge'; import { FEATURE_FLAG_VALIDATORS, QUOTE_VALIDATORS, @@ -50,7 +47,7 @@ import { validateResponse, QUOTE_RESPONSE_VALIDATORS, FEE_DATA_VALIDATORS, -} from './utils/validators'; +} from './validators'; const CLIENT_ID_HEADER = { 'X-Client-Id': BRIDGE_CLIENT_ID }; const CACHE_REFRESH_TEN_MINUTES = 10 * MINUTE; diff --git a/shared/modules/bridge-utils/quote.ts b/shared/modules/bridge-utils/quote.ts new file mode 100644 index 000000000000..90bd312ca631 --- /dev/null +++ b/shared/modules/bridge-utils/quote.ts @@ -0,0 +1,36 @@ +import { QuoteRequest } from '../../types/bridge'; + +export const isValidQuoteRequest = ( + partialRequest: Partial, + requireAmount = true, +): partialRequest is QuoteRequest => { + const STRING_FIELDS = ['srcTokenAddress', 'destTokenAddress']; + if (requireAmount) { + STRING_FIELDS.push('srcTokenAmount'); + } + const NUMBER_FIELDS = ['srcChainId', 'destChainId', 'slippage']; + + return ( + STRING_FIELDS.every( + (field) => + field in partialRequest && + typeof partialRequest[field as keyof typeof partialRequest] === + 'string' && + partialRequest[field as keyof typeof partialRequest] !== undefined && + partialRequest[field as keyof typeof partialRequest] !== '' && + partialRequest[field as keyof typeof partialRequest] !== null, + ) && + NUMBER_FIELDS.every( + (field) => + field in partialRequest && + typeof partialRequest[field as keyof typeof partialRequest] === + 'number' && + partialRequest[field as keyof typeof partialRequest] !== undefined && + !isNaN(Number(partialRequest[field as keyof typeof partialRequest])) && + partialRequest[field as keyof typeof partialRequest] !== null, + ) && + (requireAmount + ? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\d*$/u)) + : true) + ); +}; diff --git a/ui/pages/bridge/utils/validators.ts b/shared/modules/bridge-utils/validators.ts similarity index 96% rename from ui/pages/bridge/utils/validators.ts rename to shared/modules/bridge-utils/validators.ts index 08fc3519ef52..edfbabdafaa3 100644 --- a/ui/pages/bridge/utils/validators.ts +++ b/shared/modules/bridge-utils/validators.ts @@ -1,10 +1,7 @@ import { isStrictHexString } from '@metamask/utils'; import { isValidHexAddress as isValidHexAddress_ } from '@metamask/controller-utils'; -import { - truthyDigitString, - validateData, -} from '../../../../shared/lib/swaps-utils'; -import { BridgeFlag, FeatureFlagResponse } from '../types'; +import { truthyDigitString, validateData } from '../../lib/swaps-utils'; +import { BridgeFlag, FeatureFlagResponse } from '../../types/bridge'; type Validator = { property: keyof ExpectedResponse | string; diff --git a/shared/types/bridge-status.ts b/shared/types/bridge-status.ts index fc9357ef968a..7574147aa4f6 100644 --- a/shared/types/bridge-status.ts +++ b/shared/types/bridge-status.ts @@ -1,12 +1,5 @@ import { TransactionMeta } from '@metamask/transaction-controller'; -// TODO fix this -import { - ChainId, - Quote, - QuoteMetadata, - QuoteResponse, - // eslint-disable-next-line import/no-restricted-paths -} from '../../ui/pages/bridge/types'; +import { ChainId, Quote, QuoteMetadata, QuoteResponse } from './bridge'; // All fields need to be types not interfaces, same with their children fields // o/w you get a type error diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index 6cfab93f47ed..0c2ff4eb4980 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -1,4 +1,158 @@ +import { Hex } from '@metamask/utils'; +import { BigNumber } from 'bignumber.js'; +import type { AssetType } from '../constants/transaction'; + export type ChainConfiguration = { isActiveSrc: boolean; isActiveDest: boolean; }; + +export type L1GasFees = { + l1GasFeesInHexWei?: string; // l1 fees for approval and trade in hex wei, appended by controller +}; +// Values derived from the quote response +// valueInCurrency values are calculated based on the user's selected currency + +export type QuoteMetadata = { + gasFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; + totalNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // estimatedGasFees + relayerFees + totalMaxNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // maxGasFees + relayerFees + toTokenAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; + adjustedReturn: { valueInCurrency: BigNumber | null }; // destTokenAmount - totalNetworkFee + sentAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; // srcTokenAmount + metabridgeFee + swapRate: BigNumber; // destTokenAmount / sentAmount + cost: { valueInCurrency: BigNumber | null }; // sentAmount - adjustedReturn +}; +// Sort order set by the user + +export enum SortOrder { + COST_ASC = 'cost_ascending', + ETA_ASC = 'time_descending', +} + +export type BridgeToken = { + type: AssetType.native | AssetType.token; + address: string; + symbol: string; + image: string; + decimals: number; + chainId: Hex; + balance: string; // raw balance + string: string | undefined; // normalized balance as a stringified number + tokenFiatAmount?: number | null; +} | null; +// Types copied from Metabridge API + +export enum BridgeFlag { + EXTENSION_CONFIG = 'extension-config', +} +type DecimalChainId = string; +export type GasMultiplierByChainId = Record; + +export type FeatureFlagResponse = { + [BridgeFlag.EXTENSION_CONFIG]: { + refreshRate: number; + maxRefreshCount: number; + support: boolean; + chains: Record; + }; +}; + +export type BridgeAsset = { + chainId: ChainId; + address: string; + symbol: string; + name: string; + decimals: number; + icon?: string; +}; + +export type QuoteRequest = { + walletAddress: string; + destWalletAddress?: string; + srcChainId: ChainId; + destChainId: ChainId; + srcTokenAddress: string; + destTokenAddress: string; + srcTokenAmount: string; // This is the amount sent + slippage: number; + aggIds?: string[]; + bridgeIds?: string[]; + insufficientBal?: boolean; + resetApproval?: boolean; + refuel?: boolean; +}; +type Protocol = { + name: string; + displayName?: string; + icon?: string; +}; +enum ActionTypes { + BRIDGE = 'bridge', + SWAP = 'swap', + REFUEL = 'refuel', +} +type Step = { + action: ActionTypes; + srcChainId: ChainId; + destChainId?: ChainId; + srcAsset: BridgeAsset; + destAsset: BridgeAsset; + srcAmount: string; + destAmount: string; + protocol: Protocol; +}; +type RefuelData = Step; + +export type Quote = { + requestId: string; + srcChainId: ChainId; + srcAsset: BridgeAsset; + // Some tokens have a fee of 0, so sometimes it's equal to amount sent + srcTokenAmount: string; // Atomic amount, the amount sent - fees + destChainId: ChainId; + destAsset: BridgeAsset; + destTokenAmount: string; // Atomic amount, the amount received + feeData: Record & + Partial>; + bridgeId: string; + bridges: string[]; + steps: Step[]; + refuel?: RefuelData; +}; + +export type QuoteResponse = { + quote: Quote; + approval: TxData | null; + trade: TxData; + estimatedProcessingTimeInSeconds: number; +}; + +export enum ChainId { + ETH = 1, + OPTIMISM = 10, + BSC = 56, + POLYGON = 137, + ZKSYNC = 324, + BASE = 8453, + ARBITRUM = 42161, + AVALANCHE = 43114, + LINEA = 59144, +} + +export enum FeeType { + METABRIDGE = 'metabridge', + REFUEL = 'refuel', +} +export type FeeData = { + amount: string; + asset: BridgeAsset; +}; +export type TxData = { + chainId: ChainId; + to: string; + from: string; + value: string; + data: string; + gasLimit: number | null; +}; diff --git a/test/e2e/tests/bridge/bridge-test-utils.ts b/test/e2e/tests/bridge/bridge-test-utils.ts index cf57deb59f96..1a814d73d0b4 100644 --- a/test/e2e/tests/bridge/bridge-test-utils.ts +++ b/test/e2e/tests/bridge/bridge-test-utils.ts @@ -12,7 +12,7 @@ import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { Driver } from '../../webdriver/driver'; import { isManifestV3 } from '../../../../shared/modules/mv3.utils'; -import { FeatureFlagResponse } from '../../../../ui/pages/bridge/types'; +import { FeatureFlagResponse } from '../../../../shared/types/bridge'; import { DEFAULT_FEATURE_FLAGS_RESPONSE, ETH_CONVERSION_RATE_USD, diff --git a/test/e2e/tests/bridge/constants.ts b/test/e2e/tests/bridge/constants.ts index d5b6da9afc61..9f54563d2e9c 100644 --- a/test/e2e/tests/bridge/constants.ts +++ b/test/e2e/tests/bridge/constants.ts @@ -1,4 +1,4 @@ -import { FeatureFlagResponse } from '../../../../ui/pages/bridge/types'; +import { FeatureFlagResponse } from '../../../../shared/types/bridge'; export const DEFAULT_FEATURE_FLAGS_RESPONSE: FeatureFlagResponse = { 'extension-config': { diff --git a/ui/ducks/bridge/actions.ts b/ui/ducks/bridge/actions.ts index 5597503206da..80ff661886fc 100644 --- a/ui/ducks/bridge/actions.ts +++ b/ui/ducks/bridge/actions.ts @@ -9,7 +9,7 @@ import { } from '../../../app/scripts/controllers/bridge/types'; import { forceUpdateMetamaskState } from '../../store/actions'; import { submitRequestToBackground } from '../../store/background-connection'; -import { QuoteRequest } from '../../pages/bridge/types'; +import { QuoteRequest } from '../../../shared/types/bridge'; import { MetaMaskReduxDispatch } from '../../store/store'; import { bridgeSlice, diff --git a/ui/ducks/bridge/bridge.ts b/ui/ducks/bridge/bridge.ts index 58ebb52fbe57..93379656bfdc 100644 --- a/ui/ducks/bridge/bridge.ts +++ b/ui/ducks/bridge/bridge.ts @@ -5,7 +5,7 @@ import { QuoteMetadata, QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; +} from '../../../shared/types/bridge'; import { BRIDGE_DEFAULT_SLIPPAGE } from '../../../shared/constants/bridge'; import { getTokenExchangeRate } from './utils'; diff --git a/ui/ducks/bridge/selectors.test.ts b/ui/ducks/bridge/selectors.test.ts index 0e948ee18784..552c3d70350e 100644 --- a/ui/ducks/bridge/selectors.test.ts +++ b/ui/ducks/bridge/selectors.test.ts @@ -14,7 +14,7 @@ import { QuoteMetadata, QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; +} from '../../../shared/types/bridge'; import { getAllBridgeableNetworks, getBridgeQuotes, diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index 9241af57db6d..08bd653d32aa 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -42,7 +42,7 @@ import { QuoteMetadata, QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; +} from '../../../shared/types/bridge'; import { calcAdjustedReturn, calcCost, diff --git a/ui/ducks/bridge/utils.ts b/ui/ducks/bridge/utils.ts index a563b5af2c73..b39f51d14e92 100644 --- a/ui/ducks/bridge/utils.ts +++ b/ui/ducks/bridge/utils.ts @@ -8,7 +8,7 @@ import { } from '@metamask/network-controller'; import { decGWEIToHexWEI } from '../../../shared/modules/conversion.utils'; import { Numeric } from '../../../shared/modules/Numeric'; -import { TxData } from '../../pages/bridge/types'; +import { TxData } from '../../../shared/types/bridge'; import { getTransaction1559GasFeeEstimates } from '../../pages/swaps/swaps.util'; import { fetchTokenExchangeRates as fetchTokenExchangeRatesUtil } from '../../helpers/utils/util'; diff --git a/ui/hooks/bridge/useBridgeTokens.ts b/ui/hooks/bridge/useBridgeTokens.ts index acddb7ec2fb0..354b90bc4a09 100644 --- a/ui/hooks/bridge/useBridgeTokens.ts +++ b/ui/hooks/bridge/useBridgeTokens.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { getAllBridgeableNetworks } from '../../ducks/bridge/selectors'; -import { fetchBridgeTokens } from '../../pages/bridge/bridge.util'; +import { fetchBridgeTokens } from '../../../shared/modules/bridge-utils/bridge.util'; // This hook is used to fetch the bridge tokens for all bridgeable networks export const useBridgeTokens = () => { diff --git a/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts b/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts index ad4b3698fe84..bd3a14b4ce4b 100644 --- a/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts +++ b/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts @@ -5,7 +5,7 @@ import { MetaMetricsEventName, MetaMetricsSwapsEventSource, } from '../../../shared/constants/metametrics'; -import { SortOrder } from '../../pages/bridge/types'; +import { SortOrder } from '../../../shared/types/bridge'; import { RequestParams, RequestMetadata, diff --git a/ui/hooks/bridge/useLatestBalance.test.ts b/ui/hooks/bridge/useLatestBalance.test.ts index 25f0d0936791..f255a3a10b9b 100644 --- a/ui/hooks/bridge/useLatestBalance.test.ts +++ b/ui/hooks/bridge/useLatestBalance.test.ts @@ -1,8 +1,8 @@ import { BigNumber } from 'bignumber.js'; +import { zeroAddress } from 'ethereumjs-util'; import { renderHookWithProvider } from '../../../test/lib/render-helpers'; import { CHAIN_IDS } from '../../../shared/constants/network'; import { createBridgeMockStore } from '../../../test/jest/mock-store'; -import { zeroAddress } from '../../__mocks__/ethereumjs-util'; import { createTestProviderTools } from '../../../test/stub/provider'; import * as tokenutil from '../../../shared/lib/token-util'; import useLatestBalance from './useLatestBalance'; diff --git a/ui/pages/bridge/hooks/useAddToken.ts b/ui/pages/bridge/hooks/useAddToken.ts index 1f2dc117513b..7eeabc2e6701 100644 --- a/ui/pages/bridge/hooks/useAddToken.ts +++ b/ui/pages/bridge/hooks/useAddToken.ts @@ -1,6 +1,6 @@ import { useDispatch, useSelector } from 'react-redux'; import { NetworkConfiguration } from '@metamask/network-controller'; -import { QuoteResponse } from '../types'; +import { QuoteResponse } from '../../../../shared/types/bridge'; import { FEATURED_RPCS } from '../../../../shared/constants/network'; import { addToken, addNetwork } from '../../../store/actions'; import { diff --git a/ui/pages/bridge/hooks/useHandleApprovalTx.ts b/ui/pages/bridge/hooks/useHandleApprovalTx.ts index 23f4b19cf2b8..929c4933cc41 100644 --- a/ui/pages/bridge/hooks/useHandleApprovalTx.ts +++ b/ui/pages/bridge/hooks/useHandleApprovalTx.ts @@ -1,8 +1,15 @@ import { TransactionType } from '@metamask/transaction-controller'; import { Hex } from '@metamask/utils'; import { BigNumber } from 'bignumber.js'; -import { TxData, QuoteResponse, FeeType } from '../types'; -import { isEthUsdt, getEthUsdtResetData } from '../bridge.util'; +import { + TxData, + QuoteResponse, + FeeType, +} from '../../../../shared/types/bridge'; +import { + isEthUsdt, + getEthUsdtResetData, +} from '../../../../shared/modules/bridge-utils/bridge.util'; import { ETH_USDT_ADDRESS } from '../../../../shared/constants/bridge'; import { getBridgeERC20Allowance } from '../../../ducks/bridge/actions'; import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils'; diff --git a/ui/pages/bridge/hooks/useHandleBridgeTx.ts b/ui/pages/bridge/hooks/useHandleBridgeTx.ts index feb7400acc71..6128750058d3 100644 --- a/ui/pages/bridge/hooks/useHandleBridgeTx.ts +++ b/ui/pages/bridge/hooks/useHandleBridgeTx.ts @@ -1,7 +1,7 @@ import { BigNumber } from 'bignumber.js'; import { TransactionType } from '@metamask/transaction-controller'; import { Numeric } from '../../../../shared/modules/Numeric'; -import { FeeType, QuoteResponse } from '../types'; +import { FeeType, QuoteResponse } from '../../../../shared/types/bridge'; import useHandleTx from './useHandleTx'; export default function useHandleBridgeTx() { diff --git a/ui/pages/bridge/hooks/useHandleTx.ts b/ui/pages/bridge/hooks/useHandleTx.ts index c3a3ede01002..36b8355b3ea4 100644 --- a/ui/pages/bridge/hooks/useHandleTx.ts +++ b/ui/pages/bridge/hooks/useHandleTx.ts @@ -15,7 +15,7 @@ import { } from '../../../ducks/bridge/utils'; import { getGasFeeEstimates } from '../../../ducks/metamask/metamask'; import { checkNetworkAndAccountSupports1559 } from '../../../selectors'; -import { ChainId } from '../types'; +import { ChainId } from '../../../../shared/types/bridge'; import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils'; import { getIsSmartTransaction } from '../../../../shared/modules/selectors'; diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts index 6f8ec559a6a5..77fd20b7da26 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts @@ -3,7 +3,7 @@ import { zeroAddress } from 'ethereumjs-util'; import { useHistory } from 'react-router-dom'; import { TransactionMeta } from '@metamask/transaction-controller'; import { createProjectLogger, Hex } from '@metamask/utils'; -import { QuoteMetadata, QuoteResponse } from '../types'; +import { QuoteMetadata, QuoteResponse } from '../../../../shared/types/bridge'; import { AWAITING_SIGNATURES_ROUTE, CROSS_CHAIN_SWAP_ROUTE, diff --git a/ui/pages/bridge/prepare/bridge-input-group.tsx b/ui/pages/bridge/prepare/bridge-input-group.tsx index 1734624b7dcc..ff9e410f6caa 100644 --- a/ui/pages/bridge/prepare/bridge-input-group.tsx +++ b/ui/pages/bridge/prepare/bridge-input-group.tsx @@ -34,7 +34,7 @@ import { getValidationErrors, } from '../../../ducks/bridge/selectors'; import { shortenString } from '../../../helpers/utils/util'; -import { BridgeToken } from '../types'; +import { BridgeToken } from '../../../../shared/types/bridge'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { MINUTE } from '../../../../shared/constants/time'; import { BridgeAssetPickerButton } from './components/bridge-asset-picker-button'; diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index fc076b73629b..3a4f2df93cd9 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -64,14 +64,14 @@ import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../../shared/constants/sw import { useTokensWithFiltering } from '../../../hooks/bridge/useTokensWithFiltering'; import { setActiveNetwork } from '../../../store/actions'; import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; -import { QuoteRequest } from '../types'; +import { QuoteRequest } from '../../../../shared/types/bridge'; import { calcTokenValue } from '../../../../shared/lib/swaps-utils'; import { BridgeQuoteCard } from '../quotes/bridge-quote-card'; import { formatTokenAmount, isQuoteExpired as isQuoteExpiredUtil, - isValidQuoteRequest, } from '../utils/quote'; +import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote'; import { getProviderConfig } from '../../../../shared/modules/selectors/networks'; import { CrossChainSwapsEventProperties, diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx index aaabfe8f5ddb..4c5b6450a86f 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx @@ -26,7 +26,11 @@ import { import { useI18nContext } from '../../../hooks/useI18nContext'; import { getLocale } from '../../../selectors'; import { setSelectedQuote, setSortOrder } from '../../../ducks/bridge/actions'; -import { QuoteMetadata, QuoteResponse, SortOrder } from '../types'; +import { + QuoteMetadata, + QuoteResponse, + SortOrder, +} from '../../../../shared/types/bridge'; import { getBridgeQuotes, getBridgeSortOrder, diff --git a/ui/pages/bridge/types.ts b/ui/pages/bridge/types.ts deleted file mode 100644 index d0eb45fa71a5..000000000000 --- a/ui/pages/bridge/types.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { BigNumber } from 'bignumber.js'; -import { Hex } from '@metamask/utils'; -import { ChainConfiguration } from '../../../shared/types/bridge'; -import type { AssetType } from '../../../shared/constants/transaction'; - -export type L1GasFees = { - l1GasFeesInHexWei?: string; // l1 fees for approval and trade in hex wei, appended by controller -}; - -// Values derived from the quote response -// valueInCurrency values are calculated based on the user's selected currency -export type QuoteMetadata = { - gasFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; - totalNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // estimatedGasFees + relayerFees - totalMaxNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // maxGasFees + relayerFees - toTokenAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; - adjustedReturn: { valueInCurrency: BigNumber | null }; // destTokenAmount - totalNetworkFee - sentAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; // srcTokenAmount + metabridgeFee - swapRate: BigNumber; // destTokenAmount / sentAmount - cost: { valueInCurrency: BigNumber | null }; // sentAmount - adjustedReturn -}; - -// Sort order set by the user -export enum SortOrder { - COST_ASC = 'cost_ascending', - ETA_ASC = 'time_descending', -} - -export type BridgeToken = { - type: AssetType.native | AssetType.token; - address: string; - symbol: string; - image: string; - decimals: number; - chainId: Hex; - balance: string; // raw balance - string: string | undefined; // normalized balance as a stringified number - tokenFiatAmount?: number | null; -} | null; - -// Types copied from Metabridge API -export enum BridgeFlag { - EXTENSION_CONFIG = 'extension-config', -} - -type DecimalChainId = string; -export type GasMultiplierByChainId = Record; - -export type FeatureFlagResponse = { - [BridgeFlag.EXTENSION_CONFIG]: { - refreshRate: number; - maxRefreshCount: number; - support: boolean; - chains: Record; - }; -}; - -export type BridgeAsset = { - chainId: ChainId; - address: string; - symbol: string; - name: string; - decimals: number; - icon?: string; -}; - -export type QuoteRequest = { - walletAddress: string; - destWalletAddress?: string; - srcChainId: ChainId; - destChainId: ChainId; - srcTokenAddress: string; - destTokenAddress: string; - srcTokenAmount: string; // This is the amount sent - slippage: number; - aggIds?: string[]; - bridgeIds?: string[]; - insufficientBal?: boolean; - resetApproval?: boolean; - refuel?: boolean; -}; - -type Protocol = { - name: string; - displayName?: string; - icon?: string; -}; - -enum ActionTypes { - BRIDGE = 'bridge', - SWAP = 'swap', - REFUEL = 'refuel', -} - -type Step = { - action: ActionTypes; - srcChainId: ChainId; - destChainId?: ChainId; - srcAsset: BridgeAsset; - destAsset: BridgeAsset; - srcAmount: string; - destAmount: string; - protocol: Protocol; -}; - -type RefuelData = Step; - -export type Quote = { - requestId: string; - srcChainId: ChainId; - srcAsset: BridgeAsset; - // Some tokens have a fee of 0, so sometimes it's equal to amount sent - srcTokenAmount: string; // Atomic amount, the amount sent - fees - destChainId: ChainId; - destAsset: BridgeAsset; - destTokenAmount: string; // Atomic amount, the amount received - feeData: Record & - Partial>; - bridgeId: string; - bridges: string[]; - steps: Step[]; - refuel?: RefuelData; -}; - -export type QuoteResponse = { - quote: Quote; - approval: TxData | null; - trade: TxData; - estimatedProcessingTimeInSeconds: number; -}; - -export enum ChainId { - ETH = 1, - OPTIMISM = 10, - BSC = 56, - POLYGON = 137, - ZKSYNC = 324, - BASE = 8453, - ARBITRUM = 42161, - AVALANCHE = 43114, - LINEA = 59144, -} - -export enum FeeType { - METABRIDGE = 'metabridge', - REFUEL = 'refuel', -} -export type FeeData = { - amount: string; - asset: BridgeAsset; -}; -export type TxData = { - chainId: ChainId; - to: string; - from: string; - value: string; - data: string; - gasLimit: number | null; -}; diff --git a/ui/pages/bridge/utils/quote.ts b/ui/pages/bridge/utils/quote.ts index 25555a216c7f..a364bab021c3 100644 --- a/ui/pages/bridge/utils/quote.ts +++ b/ui/pages/bridge/utils/quote.ts @@ -1,7 +1,11 @@ import { zeroAddress } from 'ethereumjs-util'; import { BigNumber } from 'bignumber.js'; import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils'; -import { QuoteResponse, QuoteRequest, Quote, L1GasFees } from '../types'; +import { + QuoteResponse, + Quote, + L1GasFees, +} from '../../../../shared/types/bridge'; import { hexToDecimal, sumDecimals, @@ -26,41 +30,6 @@ export const isQuoteExpired = ( export const isNativeAddress = (address?: string | null) => address === zeroAddress() || address === '' || !address; -export const isValidQuoteRequest = ( - partialRequest: Partial, - requireAmount = true, -): partialRequest is QuoteRequest => { - const STRING_FIELDS = ['srcTokenAddress', 'destTokenAddress']; - if (requireAmount) { - STRING_FIELDS.push('srcTokenAmount'); - } - const NUMBER_FIELDS = ['srcChainId', 'destChainId', 'slippage']; - - return ( - STRING_FIELDS.every( - (field) => - field in partialRequest && - typeof partialRequest[field as keyof typeof partialRequest] === - 'string' && - partialRequest[field as keyof typeof partialRequest] !== undefined && - partialRequest[field as keyof typeof partialRequest] !== '' && - partialRequest[field as keyof typeof partialRequest] !== null, - ) && - NUMBER_FIELDS.every( - (field) => - field in partialRequest && - typeof partialRequest[field as keyof typeof partialRequest] === - 'number' && - partialRequest[field as keyof typeof partialRequest] !== undefined && - !isNaN(Number(partialRequest[field as keyof typeof partialRequest])) && - partialRequest[field as keyof typeof partialRequest] !== null, - ) && - (requireAmount - ? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\d*$/u)) - : true) - ); -}; - export const calcToAmount = ( { destTokenAmount, destAsset }: Quote, exchangeRate: number | null, From 959e98e467cd3a5733e90d6ddb707c5570f10d0b Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 14:08:18 -0800 Subject: [PATCH 3/8] refactor: move controller types to shared dir --- .../bridge/bridge-controller.test.ts | 4 ++-- .../controllers/bridge/bridge-controller.ts | 11 ++++------- app/scripts/controllers/bridge/constants.ts | 14 ++++---------- app/scripts/controllers/bridge/types.ts | 19 +++---------------- shared/constants/bridge.ts | 2 ++ shared/modules/bridge-utils/bridge.util.ts | 12 +++--------- shared/types/bridge.ts | 17 +++++++++++++++++ ui/ducks/bridge/selectors.ts | 6 ++---- .../bridge/prepare/bridge-cta-button.test.tsx | 4 +--- .../bridge/quotes/bridge-quote-card.test.tsx | 4 +--- .../quotes/bridge-quotes-modal.test.tsx | 4 +--- ui/selectors/selectors.js | 2 +- 12 files changed, 41 insertions(+), 58 deletions(-) diff --git a/app/scripts/controllers/bridge/bridge-controller.test.ts b/app/scripts/controllers/bridge/bridge-controller.test.ts index 68a5e3f26179..2ee09b252f62 100644 --- a/app/scripts/controllers/bridge/bridge-controller.test.ts +++ b/app/scripts/controllers/bridge/bridge-controller.test.ts @@ -10,11 +10,11 @@ import * as balanceUtils from '../../../../shared/modules/bridge-utils/balance'; import mockBridgeQuotesErc20Native from '../../../../test/data/bridge/mock-quotes-erc20-native.json'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; import mockBridgeQuotesNativeErc20Eth from '../../../../test/data/bridge/mock-quotes-native-erc20-eth.json'; -import { QuoteResponse } from '../../../../shared/types/bridge'; +import { QuoteResponse, RequestStatus } from '../../../../shared/types/bridge'; import { decimalToHex } from '../../../../shared/modules/conversion.utils'; import BridgeController from './bridge-controller'; import { BridgeControllerMessenger } from './types'; -import { DEFAULT_BRIDGE_CONTROLLER_STATE, RequestStatus } from './constants'; +import { DEFAULT_BRIDGE_CONTROLLER_STATE } from './constants'; const EMPTY_INIT_STATE = { bridgeState: DEFAULT_BRIDGE_CONTROLLER_STATE, diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index 1e00e9264fdf..3b4fef9dbbd8 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -25,22 +25,19 @@ import { QuoteRequest, QuoteResponse, TxData, + BridgeFeatureFlagsKey, + RequestStatus, } from '../../../../shared/types/bridge'; import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote'; import { hasSufficientBalance } from '../../../../shared/modules/bridge-utils/balance'; import { CHAIN_IDS } from '../../../../shared/constants/network'; +import { REFRESH_INTERVAL_MS } from '../../../../shared/constants/bridge'; import { BRIDGE_CONTROLLER_NAME, DEFAULT_BRIDGE_CONTROLLER_STATE, - REFRESH_INTERVAL_MS, - RequestStatus, METABRIDGE_CHAIN_TO_ADDRESS_MAP, } from './constants'; -import { - BridgeControllerState, - BridgeControllerMessenger, - BridgeFeatureFlagsKey, -} from './types'; +import { BridgeControllerState, BridgeControllerMessenger } from './types'; const metadata: StateMetadata<{ bridgeState: BridgeControllerState }> = { bridgeState: { diff --git a/app/scripts/controllers/bridge/constants.ts b/app/scripts/controllers/bridge/constants.ts index 4903a9ee2858..718f81de2f9f 100644 --- a/app/scripts/controllers/bridge/constants.ts +++ b/app/scripts/controllers/bridge/constants.ts @@ -2,21 +2,15 @@ import { zeroAddress } from 'ethereumjs-util'; import { Hex } from '@metamask/utils'; import { BRIDGE_DEFAULT_SLIPPAGE, + DEFAULT_MAX_REFRESH_COUNT, METABRIDGE_ETHEREUM_ADDRESS, + REFRESH_INTERVAL_MS, } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; -import { BridgeControllerState, BridgeFeatureFlagsKey } from './types'; +import { BridgeFeatureFlagsKey } from '../../../../shared/types/bridge'; +import { BridgeControllerState } from './types'; export const BRIDGE_CONTROLLER_NAME = 'BridgeController'; -export const REFRESH_INTERVAL_MS = 30 * 1000; -const DEFAULT_MAX_REFRESH_COUNT = 5; - -export enum RequestStatus { - LOADING, - FETCHED, - ERROR, -} - export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = { bridgeFeatureFlags: { [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index aeeae7a0317a..e07b2ab78a94 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -2,7 +2,6 @@ import { ControllerStateChangeEvent, RestrictedControllerMessenger, } from '@metamask/base-controller'; -import { Hex } from '@metamask/utils'; import { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller'; import { NetworkControllerFindNetworkClientIdByChainIdAction, @@ -10,26 +9,14 @@ import { } from '@metamask/network-controller'; import { SwapsTokenObject } from '../../../../shared/constants/swaps'; import { + BridgeFeatureFlags, L1GasFees, QuoteRequest, QuoteResponse, - ChainConfiguration, + RequestStatus, } from '../../../../shared/types/bridge'; import BridgeController from './bridge-controller'; -import { BRIDGE_CONTROLLER_NAME, RequestStatus } from './constants'; - -export enum BridgeFeatureFlagsKey { - EXTENSION_CONFIG = 'extensionConfig', -} - -export type BridgeFeatureFlags = { - [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { - refreshRate: number; - maxRefreshCount: number; - support: boolean; - chains: Record; - }; -}; +import { BRIDGE_CONTROLLER_NAME } from './constants'; export type BridgeControllerState = { bridgeFeatureFlags: BridgeFeatureFlags; diff --git a/shared/constants/bridge.ts b/shared/constants/bridge.ts index ef7cb7f8a785..57ba22da8f89 100644 --- a/shared/constants/bridge.ts +++ b/shared/constants/bridge.ts @@ -47,3 +47,5 @@ export const NETWORK_TO_SHORT_NETWORK_NAME_MAP: Record< [CHAIN_IDS.BASE]: 'Base', }; export const BRIDGE_MM_FEE_RATE = 0.875; +export const REFRESH_INTERVAL_MS = 30 * 1000; +export const DEFAULT_MAX_REFRESH_COUNT = 5; diff --git a/shared/modules/bridge-utils/bridge.util.ts b/shared/modules/bridge-utils/bridge.util.ts index 9543cbcb979d..b7da42ba9cc6 100644 --- a/shared/modules/bridge-utils/bridge.util.ts +++ b/shared/modules/bridge-utils/bridge.util.ts @@ -1,17 +1,12 @@ import { Contract } from '@ethersproject/contracts'; import { Hex, add0x } from '@metamask/utils'; import { abiERC20 } from '@metamask/metamask-eth-abis'; -import { - BridgeFeatureFlagsKey, - BridgeFeatureFlags, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; import { BRIDGE_API_BASE_URL, BRIDGE_CLIENT_ID, ETH_USDT_ADDRESS, METABRIDGE_ETHEREUM_ADDRESS, + REFRESH_INTERVAL_MS, } from '../../constants/bridge'; import { MINUTE } from '../../constants/time'; import fetchWithCache from '../../lib/fetch-with-cache'; @@ -24,9 +19,6 @@ import { isSwapsDefaultTokenAddress, isSwapsDefaultTokenSymbol, } from '../swaps.utils'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { REFRESH_INTERVAL_MS } from '../../../app/scripts/controllers/bridge/constants'; import { CHAIN_IDS } from '../../constants/network'; import { BridgeAsset, @@ -38,6 +30,8 @@ import { QuoteRequest, QuoteResponse, TxData, + BridgeFeatureFlagsKey, + BridgeFeatureFlags, } from '../../types/bridge'; import { FEATURE_FLAG_VALIDATORS, diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index 0c2ff4eb4980..ab1784b13800 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -156,3 +156,20 @@ export type TxData = { data: string; gasLimit: number | null; }; +export enum BridgeFeatureFlagsKey { + EXTENSION_CONFIG = 'extensionConfig', +} + +export type BridgeFeatureFlags = { + [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { + refreshRate: number; + maxRefreshCount: number; + support: boolean; + chains: Record; + }; +}; +export enum RequestStatus { + LOADING, + FETCHED, + ERROR, +} diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index 08bd653d32aa..672a7377ca26 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -22,7 +22,6 @@ import { } from '../../../shared/constants/bridge'; import { BridgeControllerState, - BridgeFeatureFlagsKey, // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths } from '../../../app/scripts/controllers/bridge/types'; @@ -33,15 +32,14 @@ import { getNetworkConfigurationsByChainId, } from '../../../shared/modules/selectors/networks'; import { getConversionRate, getGasFeeEstimates } from '../metamask/metamask'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../app/scripts/controllers/bridge/constants'; import { L1GasFees, BridgeToken, QuoteMetadata, QuoteResponse, SortOrder, + BridgeFeatureFlagsKey, + RequestStatus, } from '../../../shared/types/bridge'; import { calcAdjustedReturn, diff --git a/ui/pages/bridge/prepare/bridge-cta-button.test.tsx b/ui/pages/bridge/prepare/bridge-cta-button.test.tsx index 5dc368043d3a..92d6591a2808 100644 --- a/ui/pages/bridge/prepare/bridge-cta-button.test.tsx +++ b/ui/pages/bridge/prepare/bridge-cta-button.test.tsx @@ -4,9 +4,7 @@ import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; +import { RequestStatus } from '../../../../shared/types/bridge'; import { BridgeCTAButton } from './bridge-cta-button'; describe('BridgeCTAButton', () => { diff --git a/ui/pages/bridge/quotes/bridge-quote-card.test.tsx b/ui/pages/bridge/quotes/bridge-quote-card.test.tsx index 59db6fa4cc63..25d095705324 100644 --- a/ui/pages/bridge/quotes/bridge-quote-card.test.tsx +++ b/ui/pages/bridge/quotes/bridge-quote-card.test.tsx @@ -5,9 +5,7 @@ import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; +import { RequestStatus } from '../../../../shared/types/bridge'; import { BridgeQuoteCard } from './bridge-quote-card'; describe('BridgeQuoteCard', () => { diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx index ac5e384413d8..2d6f3dd992ea 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx @@ -1,7 +1,5 @@ import React from 'react'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; +import { RequestStatus } from '../../../../shared/types/bridge'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 383f9c0dd683..8c5b55662541 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -108,7 +108,7 @@ import { ENVIRONMENT_TYPE_POPUP } from '../../shared/constants/app'; import { MULTICHAIN_NETWORK_TO_ASSET_TYPES } from '../../shared/constants/multichain/assets'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths -import { BridgeFeatureFlagsKey } from '../../app/scripts/controllers/bridge/types'; +import { BridgeFeatureFlagsKey } from '../../shared/types/bridge'; import { hasTransactionData } from '../../shared/modules/transaction.utils'; import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils'; import { createDeepEqualSelector } from '../../shared/modules/selectors/util'; From 0b95b88a8e0fb4de03284591428b2331432b8871 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 14:13:20 -0800 Subject: [PATCH 4/8] refactor: move BackgroundAction types to shared dir --- app/scripts/controllers/bridge/types.ts | 13 ++----------- app/scripts/metamask-controller.js | 8 ++++---- shared/types/bridge.ts | 10 ++++++++++ ui/ducks/bridge/actions.ts | 8 ++------ ui/ducks/bridge/bridge.test.ts | 4 +--- ui/ducks/bridge/selectors.ts | 8 +++----- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index e07b2ab78a94..9502d2601fc2 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -9,7 +9,9 @@ import { } from '@metamask/network-controller'; import { SwapsTokenObject } from '../../../../shared/constants/swaps'; import { + BridgeBackgroundAction, BridgeFeatureFlags, + BridgeUserAction, L1GasFees, QuoteRequest, QuoteResponse, @@ -35,17 +37,6 @@ export type BridgeControllerState = { quotesRefreshCount: number; }; -export enum BridgeUserAction { - SELECT_SRC_NETWORK = 'selectSrcNetwork', - SELECT_DEST_NETWORK = 'selectDestNetwork', - UPDATE_QUOTE_PARAMS = 'updateBridgeQuoteRequestParams', -} -export enum BridgeBackgroundAction { - SET_FEATURE_FLAGS = 'setBridgeFeatureFlags', - RESET_STATE = 'resetState', - GET_BRIDGE_ERC20_ALLOWANCE = 'getBridgeERC20Allowance', -} - type BridgeControllerAction = { type: `${typeof BRIDGE_CONTROLLER_NAME}:${FunctionName}`; handler: BridgeController[FunctionName]; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 8ab78f2c7e92..933522c449f6 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -250,6 +250,10 @@ import { isSnapId } from '../../ui/helpers/utils/snaps'; import { BridgeStatusAction } from '../../shared/types/bridge-status'; import { ENVIRONMENT } from '../../development/build/constants'; import fetchWithCache from '../../shared/lib/fetch-with-cache'; +import { + BridgeUserAction, + BridgeBackgroundAction, +} from '../../shared/types/bridge'; import { BalancesController as MultichainBalancesController } from './lib/accounts/BalancesController'; import { ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) @@ -365,10 +369,6 @@ import { updateSecurityAlertResponse } from './lib/ppom/ppom-util'; import createEvmMethodsToNonEvmAccountReqFilterMiddleware from './lib/createEvmMethodsToNonEvmAccountReqFilterMiddleware'; import { isEthAddress } from './lib/multichain/address'; import { decodeTransactionData } from './lib/transaction/decode/util'; -import { - BridgeUserAction, - BridgeBackgroundAction, -} from './controllers/bridge/types'; import BridgeController from './controllers/bridge/bridge-controller'; import { BRIDGE_CONTROLLER_NAME } from './controllers/bridge/constants'; import { diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index ab1784b13800..acffeba900ac 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -173,3 +173,13 @@ export enum RequestStatus { FETCHED, ERROR, } +export enum BridgeUserAction { + SELECT_SRC_NETWORK = 'selectSrcNetwork', + SELECT_DEST_NETWORK = 'selectDestNetwork', + UPDATE_QUOTE_PARAMS = 'updateBridgeQuoteRequestParams', +} +export enum BridgeBackgroundAction { + SET_FEATURE_FLAGS = 'setBridgeFeatureFlags', + RESET_STATE = 'resetState', + GET_BRIDGE_ERC20_ALLOWANCE = 'getBridgeERC20Allowance', +} diff --git a/ui/ducks/bridge/actions.ts b/ui/ducks/bridge/actions.ts index 80ff661886fc..2258832a01b7 100644 --- a/ui/ducks/bridge/actions.ts +++ b/ui/ducks/bridge/actions.ts @@ -1,15 +1,11 @@ -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths import { Hex } from '@metamask/utils'; import { BridgeBackgroundAction, BridgeUserAction, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; + QuoteRequest, +} from '../../../shared/types/bridge'; import { forceUpdateMetamaskState } from '../../store/actions'; import { submitRequestToBackground } from '../../store/background-connection'; -import { QuoteRequest } from '../../../shared/types/bridge'; import { MetaMaskReduxDispatch } from '../../store/store'; import { bridgeSlice, diff --git a/ui/ducks/bridge/bridge.test.ts b/ui/ducks/bridge/bridge.test.ts index d317d1b53bb8..30e2f0fe880a 100644 --- a/ui/ducks/bridge/bridge.test.ts +++ b/ui/ducks/bridge/bridge.test.ts @@ -7,9 +7,7 @@ import { setBackgroundConnection } from '../../store/background-connection'; import { BridgeBackgroundAction, BridgeUserAction, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; +} from '../../../shared/types/bridge'; import * as util from '../../helpers/utils/util'; import { BRIDGE_DEFAULT_SLIPPAGE } from '../../../shared/constants/bridge'; import bridgeReducer from './bridge'; diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index 672a7377ca26..ce2610aca4c7 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -20,11 +20,9 @@ import { BRIDGE_PREFERRED_GAS_ESTIMATE, BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE, } from '../../../shared/constants/bridge'; -import { - BridgeControllerState, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; +// TODO: Remove restricted import +// eslint-disable-next-line import/no-restricted-paths +import { BridgeControllerState } from '../../../app/scripts/controllers/bridge/types'; import { createDeepEqualSelector } from '../../../shared/modules/selectors/util'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../shared/constants/swaps'; import { From 83a444119dd0aac51cfba81f99c56866cd177872 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 14:28:24 -0800 Subject: [PATCH 5/8] fix: rm duplicate action --- ui/pages/bridge/prepare/prepare-bridge-page.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index 3a4f2df93cd9..305f0ea48b3b 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -340,8 +340,6 @@ const PrepareBridgePage = () => { input: 'token_source', value: token.address, }); - dispatch(setFromToken(token)); - dispatch(setFromTokenInputValue(null)); }} networkProps={{ network: fromChain, From 0225259cd7ee89c34d788468cc38697d40ab328d Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 16:03:26 -0800 Subject: [PATCH 6/8] fix: storybook imports --- ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx | 2 +- ui/pages/bridge/quotes/bridge-quotes-modal.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx index 3e955d3e34ef..4a57e9517c67 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx @@ -3,7 +3,6 @@ import { Provider } from 'react-redux'; import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; import CrossChainSwap from '../index'; import { MemoryRouter } from 'react-router-dom'; import { @@ -11,6 +10,7 @@ import { PREPARE_SWAP_ROUTE, } from '../../../helpers/constants/routes'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; +import { RequestStatus } from '../../../../shared/types/bridge'; const storybook = { title: 'Pages/Bridge/CrossChainSwapPage', diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.stories.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.stories.tsx index bbdf9b47fa47..fe999108bec8 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.stories.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.stories.tsx @@ -4,7 +4,7 @@ import configureStore from '../../../store/store'; import { BridgeQuotesModal } from './bridge-quotes-modal'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; -import { SortOrder } from '../types'; +import { SortOrder } from '../../../../shared/types/bridge'; const storybook = { title: 'Pages/Bridge/BridgeQuotesModal', From 346da7878028a8ef3ba4ff56e18416421f8089c6 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 16 Dec 2024 16:33:59 -0800 Subject: [PATCH 7/8] refactor: type imports --- app/scripts/controllers/bridge-status/utils.ts | 2 +- .../controllers/bridge/bridge-controller.test.ts | 5 ++++- .../controllers/bridge/bridge-controller.ts | 8 ++++---- app/scripts/controllers/bridge/constants.ts | 2 +- app/scripts/controllers/bridge/types.ts | 2 +- shared/modules/bridge-utils/quote.ts | 2 +- shared/types/bridge-status.ts | 2 +- shared/types/bridge.ts | 4 ++-- test/e2e/tests/bridge/bridge-test-utils.ts | 2 +- test/e2e/tests/bridge/constants.ts | 2 +- ui/ducks/bridge/actions.ts | 4 ++-- ui/ducks/bridge/bridge.ts | 6 +++--- ui/ducks/bridge/selectors.test.ts | 4 ++-- ui/ducks/bridge/selectors.ts | 16 ++++++++-------- ui/ducks/bridge/utils.ts | 6 +++--- ui/pages/bridge/hooks/useAddToken.ts | 4 ++-- ui/pages/bridge/hooks/useHandleApprovalTx.ts | 6 +++--- ui/pages/bridge/hooks/useHandleBridgeTx.ts | 2 +- ui/pages/bridge/hooks/useHandleTx.ts | 2 +- .../bridge/hooks/useSubmitBridgeTransaction.ts | 5 ++++- ui/pages/bridge/prepare/bridge-input-group.tsx | 2 +- ui/pages/bridge/prepare/prepare-bridge-page.tsx | 2 +- ui/pages/bridge/quotes/bridge-quotes-modal.tsx | 4 ++-- ui/pages/bridge/utils/quote.ts | 2 +- 24 files changed, 51 insertions(+), 45 deletions(-) diff --git a/app/scripts/controllers/bridge-status/utils.ts b/app/scripts/controllers/bridge-status/utils.ts index d68f0dfe8331..5447b483e34f 100644 --- a/app/scripts/controllers/bridge-status/utils.ts +++ b/app/scripts/controllers/bridge-status/utils.ts @@ -8,7 +8,7 @@ import { StatusRequestWithSrcTxHash, StatusRequestDto, } from '../../../../shared/types/bridge-status'; -import { Quote } from '../../../../shared/types/bridge'; +import type { Quote } from '../../../../shared/types/bridge'; import { validateResponse, validators } from './validators'; const CLIENT_ID_HEADER = { 'X-Client-Id': BRIDGE_CLIENT_ID }; diff --git a/app/scripts/controllers/bridge/bridge-controller.test.ts b/app/scripts/controllers/bridge/bridge-controller.test.ts index 2ee09b252f62..e35d3c41e67c 100644 --- a/app/scripts/controllers/bridge/bridge-controller.test.ts +++ b/app/scripts/controllers/bridge/bridge-controller.test.ts @@ -10,7 +10,10 @@ import * as balanceUtils from '../../../../shared/modules/bridge-utils/balance'; import mockBridgeQuotesErc20Native from '../../../../test/data/bridge/mock-quotes-erc20-native.json'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; import mockBridgeQuotesNativeErc20Eth from '../../../../test/data/bridge/mock-quotes-native-erc20-eth.json'; -import { QuoteResponse, RequestStatus } from '../../../../shared/types/bridge'; +import { + type QuoteResponse, + RequestStatus, +} from '../../../../shared/types/bridge'; import { decimalToHex } from '../../../../shared/modules/conversion.utils'; import BridgeController from './bridge-controller'; import { BridgeControllerMessenger } from './types'; diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index 3b4fef9dbbd8..ba7a3e75905d 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -21,10 +21,10 @@ import { sumHexes, } from '../../../../shared/modules/conversion.utils'; import { - L1GasFees, - QuoteRequest, - QuoteResponse, - TxData, + type L1GasFees, + type QuoteRequest, + type QuoteResponse, + type TxData, BridgeFeatureFlagsKey, RequestStatus, } from '../../../../shared/types/bridge'; diff --git a/app/scripts/controllers/bridge/constants.ts b/app/scripts/controllers/bridge/constants.ts index 718f81de2f9f..daaf3dc056ce 100644 --- a/app/scripts/controllers/bridge/constants.ts +++ b/app/scripts/controllers/bridge/constants.ts @@ -8,7 +8,7 @@ import { } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { BridgeFeatureFlagsKey } from '../../../../shared/types/bridge'; -import { BridgeControllerState } from './types'; +import type { BridgeControllerState } from './types'; export const BRIDGE_CONTROLLER_NAME = 'BridgeController'; export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = { diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index 9502d2601fc2..cbced91248a6 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -8,7 +8,7 @@ import { NetworkControllerGetSelectedNetworkClientAction, } from '@metamask/network-controller'; import { SwapsTokenObject } from '../../../../shared/constants/swaps'; -import { +import type { BridgeBackgroundAction, BridgeFeatureFlags, BridgeUserAction, diff --git a/shared/modules/bridge-utils/quote.ts b/shared/modules/bridge-utils/quote.ts index 90bd312ca631..3fe4406fa333 100644 --- a/shared/modules/bridge-utils/quote.ts +++ b/shared/modules/bridge-utils/quote.ts @@ -1,4 +1,4 @@ -import { QuoteRequest } from '../../types/bridge'; +import type { QuoteRequest } from '../../types/bridge'; export const isValidQuoteRequest = ( partialRequest: Partial, diff --git a/shared/types/bridge-status.ts b/shared/types/bridge-status.ts index 7574147aa4f6..3e81f6e74f1d 100644 --- a/shared/types/bridge-status.ts +++ b/shared/types/bridge-status.ts @@ -1,5 +1,5 @@ import { TransactionMeta } from '@metamask/transaction-controller'; -import { ChainId, Quote, QuoteMetadata, QuoteResponse } from './bridge'; +import type { ChainId, Quote, QuoteMetadata, QuoteResponse } from './bridge'; // All fields need to be types not interfaces, same with their children fields // o/w you get a type error diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index acffeba900ac..fc7110e49825 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -1,5 +1,5 @@ -import { Hex } from '@metamask/utils'; -import { BigNumber } from 'bignumber.js'; +import type { Hex } from '@metamask/utils'; +import type { BigNumber } from 'bignumber.js'; import type { AssetType } from '../constants/transaction'; export type ChainConfiguration = { diff --git a/test/e2e/tests/bridge/bridge-test-utils.ts b/test/e2e/tests/bridge/bridge-test-utils.ts index 1a814d73d0b4..842ff31fff39 100644 --- a/test/e2e/tests/bridge/bridge-test-utils.ts +++ b/test/e2e/tests/bridge/bridge-test-utils.ts @@ -12,7 +12,7 @@ import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { Driver } from '../../webdriver/driver'; import { isManifestV3 } from '../../../../shared/modules/mv3.utils'; -import { FeatureFlagResponse } from '../../../../shared/types/bridge'; +import type { FeatureFlagResponse } from '../../../../shared/types/bridge'; import { DEFAULT_FEATURE_FLAGS_RESPONSE, ETH_CONVERSION_RATE_USD, diff --git a/test/e2e/tests/bridge/constants.ts b/test/e2e/tests/bridge/constants.ts index 9f54563d2e9c..844cec673509 100644 --- a/test/e2e/tests/bridge/constants.ts +++ b/test/e2e/tests/bridge/constants.ts @@ -1,4 +1,4 @@ -import { FeatureFlagResponse } from '../../../../shared/types/bridge'; +import type { FeatureFlagResponse } from '../../../../shared/types/bridge'; export const DEFAULT_FEATURE_FLAGS_RESPONSE: FeatureFlagResponse = { 'extension-config': { diff --git a/ui/ducks/bridge/actions.ts b/ui/ducks/bridge/actions.ts index 2258832a01b7..e2ea02bad39d 100644 --- a/ui/ducks/bridge/actions.ts +++ b/ui/ducks/bridge/actions.ts @@ -1,4 +1,4 @@ -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BridgeBackgroundAction, BridgeUserAction, @@ -6,7 +6,7 @@ import { } from '../../../shared/types/bridge'; import { forceUpdateMetamaskState } from '../../store/actions'; import { submitRequestToBackground } from '../../store/background-connection'; -import { MetaMaskReduxDispatch } from '../../store/store'; +import type { MetaMaskReduxDispatch } from '../../store/store'; import { bridgeSlice, setDestTokenExchangeRates, diff --git a/ui/ducks/bridge/bridge.ts b/ui/ducks/bridge/bridge.ts index 93379656bfdc..14786b51d4dd 100644 --- a/ui/ducks/bridge/bridge.ts +++ b/ui/ducks/bridge/bridge.ts @@ -1,9 +1,9 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { Hex } from '@metamask/utils'; import { - BridgeToken, - QuoteMetadata, - QuoteResponse, + type BridgeToken, + type QuoteMetadata, + type QuoteResponse, SortOrder, } from '../../../shared/types/bridge'; import { BRIDGE_DEFAULT_SLIPPAGE } from '../../../shared/constants/bridge'; diff --git a/ui/ducks/bridge/selectors.test.ts b/ui/ducks/bridge/selectors.test.ts index 552c3d70350e..bf0cefedeb4d 100644 --- a/ui/ducks/bridge/selectors.test.ts +++ b/ui/ducks/bridge/selectors.test.ts @@ -11,8 +11,8 @@ import { mockNetworkState } from '../../../test/stub/networks'; import mockErc20Erc20Quotes from '../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../test/data/bridge/mock-quotes-native-erc20.json'; import { - QuoteMetadata, - QuoteResponse, + type QuoteMetadata, + type QuoteResponse, SortOrder, } from '../../../shared/types/bridge'; import { diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index ce2610aca4c7..dd111196d8fa 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -1,11 +1,11 @@ -import { +import type { AddNetworkFields, NetworkConfiguration, NetworkState, } from '@metamask/network-controller'; import { orderBy, uniqBy } from 'lodash'; import { createSelector } from 'reselect'; -import { GasFeeEstimates } from '@metamask/gas-fee-controller'; +import type { GasFeeEstimates } from '@metamask/gas-fee-controller'; import { BigNumber } from 'bignumber.js'; import { calcTokenAmount } from '@metamask/notification-services-controller/push-services'; import { @@ -22,7 +22,7 @@ import { } from '../../../shared/constants/bridge'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths -import { BridgeControllerState } from '../../../app/scripts/controllers/bridge/types'; +import type { BridgeControllerState } from '../../../app/scripts/controllers/bridge/types'; import { createDeepEqualSelector } from '../../../shared/modules/selectors/util'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../shared/constants/swaps'; import { @@ -31,10 +31,10 @@ import { } from '../../../shared/modules/selectors/networks'; import { getConversionRate, getGasFeeEstimates } from '../metamask/metamask'; import { - L1GasFees, - BridgeToken, - QuoteMetadata, - QuoteResponse, + type L1GasFees, + type BridgeToken, + type QuoteMetadata, + type QuoteResponse, SortOrder, BridgeFeatureFlagsKey, RequestStatus, @@ -60,7 +60,7 @@ import { exchangeRateFromMarketData, tokenPriceInNativeAsset, } from './utils'; -import { BridgeState } from './bridge'; +import type { BridgeState } from './bridge'; type BridgeAppState = { metamask: { bridgeState: BridgeControllerState } & NetworkState & { diff --git a/ui/ducks/bridge/utils.ts b/ui/ducks/bridge/utils.ts index b39f51d14e92..050829d3ca65 100644 --- a/ui/ducks/bridge/utils.ts +++ b/ui/ducks/bridge/utils.ts @@ -1,14 +1,14 @@ -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BigNumber } from 'bignumber.js'; import { getAddress } from 'ethers/lib/utils'; -import { ContractMarketData } from '@metamask/assets-controllers'; +import type { ContractMarketData } from '@metamask/assets-controllers'; import { AddNetworkFields, NetworkConfiguration, } from '@metamask/network-controller'; import { decGWEIToHexWEI } from '../../../shared/modules/conversion.utils'; import { Numeric } from '../../../shared/modules/Numeric'; -import { TxData } from '../../../shared/types/bridge'; +import type { TxData } from '../../../shared/types/bridge'; import { getTransaction1559GasFeeEstimates } from '../../pages/swaps/swaps.util'; import { fetchTokenExchangeRates as fetchTokenExchangeRatesUtil } from '../../helpers/utils/util'; diff --git a/ui/pages/bridge/hooks/useAddToken.ts b/ui/pages/bridge/hooks/useAddToken.ts index 7eeabc2e6701..f1a148ce7732 100644 --- a/ui/pages/bridge/hooks/useAddToken.ts +++ b/ui/pages/bridge/hooks/useAddToken.ts @@ -1,6 +1,6 @@ import { useDispatch, useSelector } from 'react-redux'; -import { NetworkConfiguration } from '@metamask/network-controller'; -import { QuoteResponse } from '../../../../shared/types/bridge'; +import type { NetworkConfiguration } from '@metamask/network-controller'; +import type { QuoteResponse } from '../../../../shared/types/bridge'; import { FEATURED_RPCS } from '../../../../shared/constants/network'; import { addToken, addNetwork } from '../../../store/actions'; import { diff --git a/ui/pages/bridge/hooks/useHandleApprovalTx.ts b/ui/pages/bridge/hooks/useHandleApprovalTx.ts index 929c4933cc41..7e469bc78ead 100644 --- a/ui/pages/bridge/hooks/useHandleApprovalTx.ts +++ b/ui/pages/bridge/hooks/useHandleApprovalTx.ts @@ -1,9 +1,9 @@ import { TransactionType } from '@metamask/transaction-controller'; -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BigNumber } from 'bignumber.js'; import { - TxData, - QuoteResponse, + type TxData, + type QuoteResponse, FeeType, } from '../../../../shared/types/bridge'; import { diff --git a/ui/pages/bridge/hooks/useHandleBridgeTx.ts b/ui/pages/bridge/hooks/useHandleBridgeTx.ts index 6128750058d3..5d7e1a1b527c 100644 --- a/ui/pages/bridge/hooks/useHandleBridgeTx.ts +++ b/ui/pages/bridge/hooks/useHandleBridgeTx.ts @@ -1,7 +1,7 @@ import { BigNumber } from 'bignumber.js'; import { TransactionType } from '@metamask/transaction-controller'; import { Numeric } from '../../../../shared/modules/Numeric'; -import { FeeType, QuoteResponse } from '../../../../shared/types/bridge'; +import { FeeType, type QuoteResponse } from '../../../../shared/types/bridge'; import useHandleTx from './useHandleTx'; export default function useHandleBridgeTx() { diff --git a/ui/pages/bridge/hooks/useHandleTx.ts b/ui/pages/bridge/hooks/useHandleTx.ts index 36b8355b3ea4..59b6c7ee9c89 100644 --- a/ui/pages/bridge/hooks/useHandleTx.ts +++ b/ui/pages/bridge/hooks/useHandleTx.ts @@ -15,7 +15,7 @@ import { } from '../../../ducks/bridge/utils'; import { getGasFeeEstimates } from '../../../ducks/metamask/metamask'; import { checkNetworkAndAccountSupports1559 } from '../../../selectors'; -import { ChainId } from '../../../../shared/types/bridge'; +import type { ChainId } from '../../../../shared/types/bridge'; import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils'; import { getIsSmartTransaction } from '../../../../shared/modules/selectors'; diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts index 77fd20b7da26..e34c4e9400c6 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts @@ -3,7 +3,10 @@ import { zeroAddress } from 'ethereumjs-util'; import { useHistory } from 'react-router-dom'; import { TransactionMeta } from '@metamask/transaction-controller'; import { createProjectLogger, Hex } from '@metamask/utils'; -import { QuoteMetadata, QuoteResponse } from '../../../../shared/types/bridge'; +import type { + QuoteMetadata, + QuoteResponse, +} from '../../../../shared/types/bridge'; import { AWAITING_SIGNATURES_ROUTE, CROSS_CHAIN_SWAP_ROUTE, diff --git a/ui/pages/bridge/prepare/bridge-input-group.tsx b/ui/pages/bridge/prepare/bridge-input-group.tsx index ff9e410f6caa..f2ec234263e7 100644 --- a/ui/pages/bridge/prepare/bridge-input-group.tsx +++ b/ui/pages/bridge/prepare/bridge-input-group.tsx @@ -34,7 +34,7 @@ import { getValidationErrors, } from '../../../ducks/bridge/selectors'; import { shortenString } from '../../../helpers/utils/util'; -import { BridgeToken } from '../../../../shared/types/bridge'; +import type { BridgeToken } from '../../../../shared/types/bridge'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { MINUTE } from '../../../../shared/constants/time'; import { BridgeAssetPickerButton } from './components/bridge-asset-picker-button'; diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index 305f0ea48b3b..e1f220fc69fa 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -64,7 +64,7 @@ import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../../shared/constants/sw import { useTokensWithFiltering } from '../../../hooks/bridge/useTokensWithFiltering'; import { setActiveNetwork } from '../../../store/actions'; import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; -import { QuoteRequest } from '../../../../shared/types/bridge'; +import type { QuoteRequest } from '../../../../shared/types/bridge'; import { calcTokenValue } from '../../../../shared/lib/swaps-utils'; import { BridgeQuoteCard } from '../quotes/bridge-quote-card'; import { diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx index 4c5b6450a86f..bc846f6d081f 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx @@ -27,8 +27,8 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { getLocale } from '../../../selectors'; import { setSelectedQuote, setSortOrder } from '../../../ducks/bridge/actions'; import { - QuoteMetadata, - QuoteResponse, + type QuoteMetadata, + type QuoteResponse, SortOrder, } from '../../../../shared/types/bridge'; import { diff --git a/ui/pages/bridge/utils/quote.ts b/ui/pages/bridge/utils/quote.ts index a364bab021c3..ee78e055698d 100644 --- a/ui/pages/bridge/utils/quote.ts +++ b/ui/pages/bridge/utils/quote.ts @@ -1,7 +1,7 @@ import { zeroAddress } from 'ethereumjs-util'; import { BigNumber } from 'bignumber.js'; import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils'; -import { +import type { QuoteResponse, Quote, L1GasFees, From 0b8d21c1fccba8493a6899dc08449d62036d4144 Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Tue, 17 Dec 2024 11:04:42 -0800 Subject: [PATCH 8/8] chore: remove more TODO comments --- .../controllers/bridge/bridge-controller.ts | 3 ++- app/scripts/controllers/bridge/constants.ts | 2 +- app/scripts/controllers/bridge/types.ts | 24 +------------------ shared/types/bridge.ts | 17 +++++++++++++ ui/ducks/bridge/selectors.ts | 4 +--- ui/selectors/selectors.js | 2 -- 6 files changed, 22 insertions(+), 30 deletions(-) diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index ba7a3e75905d..005e2d334e9f 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -25,6 +25,7 @@ import { type QuoteRequest, type QuoteResponse, type TxData, + type BridgeControllerState, BridgeFeatureFlagsKey, RequestStatus, } from '../../../../shared/types/bridge'; @@ -37,7 +38,7 @@ import { DEFAULT_BRIDGE_CONTROLLER_STATE, METABRIDGE_CHAIN_TO_ADDRESS_MAP, } from './constants'; -import { BridgeControllerState, BridgeControllerMessenger } from './types'; +import type { BridgeControllerMessenger } from './types'; const metadata: StateMetadata<{ bridgeState: BridgeControllerState }> = { bridgeState: { diff --git a/app/scripts/controllers/bridge/constants.ts b/app/scripts/controllers/bridge/constants.ts index daaf3dc056ce..65e2840cfb73 100644 --- a/app/scripts/controllers/bridge/constants.ts +++ b/app/scripts/controllers/bridge/constants.ts @@ -8,7 +8,7 @@ import { } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { BridgeFeatureFlagsKey } from '../../../../shared/types/bridge'; -import type { BridgeControllerState } from './types'; +import type { BridgeControllerState } from '../../../../shared/types/bridge'; export const BRIDGE_CONTROLLER_NAME = 'BridgeController'; export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = { diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index cbced91248a6..811b8dfb119b 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -7,36 +7,14 @@ import { NetworkControllerFindNetworkClientIdByChainIdAction, NetworkControllerGetSelectedNetworkClientAction, } from '@metamask/network-controller'; -import { SwapsTokenObject } from '../../../../shared/constants/swaps'; import type { BridgeBackgroundAction, - BridgeFeatureFlags, + BridgeControllerState, BridgeUserAction, - L1GasFees, - QuoteRequest, - QuoteResponse, - RequestStatus, } from '../../../../shared/types/bridge'; import BridgeController from './bridge-controller'; import { BRIDGE_CONTROLLER_NAME } from './constants'; -export type BridgeControllerState = { - bridgeFeatureFlags: BridgeFeatureFlags; - srcTokens: Record; - srcTopAssets: { address: string }[]; - srcTokensLoadingStatus?: RequestStatus; - destTokensLoadingStatus?: RequestStatus; - destTokens: Record; - destTopAssets: { address: string }[]; - quoteRequest: Partial; - quotes: (QuoteResponse & L1GasFees)[]; - quotesInitialLoadTime?: number; - quotesLastFetched?: number; - quotesLoadingStatus?: RequestStatus; - quoteFetchError?: string; - quotesRefreshCount: number; -}; - type BridgeControllerAction = { type: `${typeof BRIDGE_CONTROLLER_NAME}:${FunctionName}`; handler: BridgeController[FunctionName]; diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index fc7110e49825..763c2670abad 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -1,6 +1,7 @@ import type { Hex } from '@metamask/utils'; import type { BigNumber } from 'bignumber.js'; import type { AssetType } from '../constants/transaction'; +import type { SwapsTokenObject } from '../constants/swaps'; export type ChainConfiguration = { isActiveSrc: boolean; @@ -183,3 +184,19 @@ export enum BridgeBackgroundAction { RESET_STATE = 'resetState', GET_BRIDGE_ERC20_ALLOWANCE = 'getBridgeERC20Allowance', } +export type BridgeControllerState = { + bridgeFeatureFlags: BridgeFeatureFlags; + srcTokens: Record; + srcTopAssets: { address: string }[]; + srcTokensLoadingStatus?: RequestStatus; + destTokensLoadingStatus?: RequestStatus; + destTokens: Record; + destTopAssets: { address: string }[]; + quoteRequest: Partial; + quotes: (QuoteResponse & L1GasFees)[]; + quotesInitialLoadTime?: number; + quotesLastFetched?: number; + quotesLoadingStatus?: RequestStatus; + quoteFetchError?: string; + quotesRefreshCount: number; +}; diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index dd111196d8fa..f86745e69ae3 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -20,9 +20,7 @@ import { BRIDGE_PREFERRED_GAS_ESTIMATE, BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE, } from '../../../shared/constants/bridge'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import type { BridgeControllerState } from '../../../app/scripts/controllers/bridge/types'; +import type { BridgeControllerState } from '../../../shared/types/bridge'; import { createDeepEqualSelector } from '../../../shared/modules/selectors/util'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../shared/constants/swaps'; import { diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 8c5b55662541..61c15000baba 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -106,8 +106,6 @@ import { BackgroundColor } from '../helpers/constants/design-system'; import { NOTIFICATION_DROP_LEDGER_FIREFOX } from '../../shared/notifications'; import { ENVIRONMENT_TYPE_POPUP } from '../../shared/constants/app'; import { MULTICHAIN_NETWORK_TO_ASSET_TYPES } from '../../shared/constants/multichain/assets'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths import { BridgeFeatureFlagsKey } from '../../shared/types/bridge'; import { hasTransactionData } from '../../shared/modules/transaction.utils'; import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';