Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[old] chore: remove EVM-specific code and update bridge types #30078

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
98c85aa
chore: add default native token for Solana
micaelae Feb 3, 2025
898cd68
chore: read solana FF from api
micaelae Feb 3, 2025
e2832d0
chore: include solana in src/dest network list
micaelae Feb 4, 2025
c7930c8
fix: display image of SOL token
micaelae Feb 4, 2025
62bdfa0
chore: multichain utils
micaelae Feb 4, 2025
06f47c4
chore: wrap chainId conversions in bridge components
micaelae Feb 4, 2025
a330018
chore: wrap chainId conversions in transaction-details
micaelae Feb 4, 2025
f684630
chore: wrap chainId conversions in tx submission
micaelae Feb 4, 2025
c725c2f
chore: wrap chainId conversions in bridge hooks
micaelae Feb 4, 2025
73fa9b4
chore: wrap chainId conversions in bridge ducks
micaelae Feb 4, 2025
cec73c6
chore: shared bridge utils
micaelae Feb 4, 2025
d358d6f
chore: bridge-status utils
micaelae Feb 4, 2025
15052cb
chore: bridge controller
micaelae Feb 4, 2025
1f54214
header
micaelae Feb 4, 2025
d30e456
fix: bridge quote request params
micaelae Feb 5, 2025
a54fc0e
fix: non-flask build
micaelae Feb 5, 2025
fb15727
refactor: rename chainId formatter utils
micaelae Feb 5, 2025
e514e1c
chore: remove usages of MultichainProviderConfig
micaelae Feb 5, 2025
6154fd3
fix: unit tests
micaelae Feb 5, 2025
7c47ab5
fix: set bridge src token from url param
micaelae Feb 5, 2025
901b5c1
fix: lint issue
micaelae Feb 5, 2025
4a85d31
fix: snapshot tests
micaelae Feb 5, 2025
c23801a
chore: deprecate BridgeLinkClicked event
micaelae Feb 6, 2025
4ecc81c
chore: rm unnecessary walletAddress condition
micaelae Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { StateMetadata } from '@metamask/base-controller';
import { StaticIntervalPollingController } from '@metamask/polling-controller';
import { Hex } from '@metamask/utils';
// eslint-disable-next-line import/no-restricted-paths
import { type CaipChainId, type Hex } from '@metamask/utils';
import {
StatusTypes,
BridgeStatusControllerState,
StartPollingForBridgeTxStatusArgsSerialized,
BridgeStatusState,
} from '../../../../shared/types/bridge-status';
import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils';
import { formatChainIdFromDecimal } from '../../../../shared/modules/bridge-utils/multichain';
import {
BRIDGE_STATUS_CONTROLLER_NAME,
DEFAULT_BRIDGE_STATUS_STATE,
Expand Down Expand Up @@ -336,14 +335,17 @@ export default class BridgeStatusController extends StaticIntervalPollingControl

// Wipes the bridge status for the given address and chainId
// Will match only source chainId to the selectedChainId
#wipeBridgeStatusByChainId = (address: string, selectedChainId: Hex) => {
#wipeBridgeStatusByChainId = (
address: string,
selectedChainId: Hex | CaipChainId,
) => {
const sourceTxMetaIdsToDelete = Object.keys(
this.state.bridgeStatusState.txHistory,
).filter((txMetaId) => {
const bridgeHistoryItem =
this.state.bridgeStatusState.txHistory[txMetaId];

const hexSourceChainId = decimalToPrefixedHex(
const hexSourceChainId = formatChainIdFromDecimal(
bridgeHistoryItem.quote.srcChainId,
);

Expand Down
39 changes: 24 additions & 15 deletions app/scripts/controllers/bridge/bridge-controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { add0x, Hex } from '@metamask/utils';
import { type Hex, isCaipChainId } from '@metamask/utils';
import { StaticIntervalPollingController } from '@metamask/polling-controller';
import { NetworkClientId } from '@metamask/network-controller';
import { StateMetadata } from '@metamask/base-controller';
Expand All @@ -12,10 +12,7 @@ import {
fetchBridgeFeatureFlags,
fetchBridgeQuotes,
} from '../../../../shared/modules/bridge-utils/bridge.util';
import {
decimalToHex,
sumHexes,
} from '../../../../shared/modules/conversion.utils';
import { sumHexes } from '../../../../shared/modules/conversion.utils';
import {
type L1GasFees,
type QuoteRequest,
Expand All @@ -28,7 +25,11 @@ import {
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 {
type AllowedBridgeChainIds,
REFRESH_INTERVAL_MS,
} from '../../../../shared/constants/bridge';
import { formatChainIdFromDecimal } from '../../../../shared/modules/bridge-utils/multichain';
import {
BRIDGE_CONTROLLER_NAME,
DEFAULT_BRIDGE_STATE,
Expand Down Expand Up @@ -139,9 +140,10 @@ export default class BridgeController extends StaticIntervalPollingController<Br

if (isValidQuoteRequest(updatedQuoteRequest)) {
this.#quotesFirstFetched = Date.now();
const walletAddress = this.#getSelectedAccount().address;
const srcChainIdInHex = add0x(
decimalToHex(updatedQuoteRequest.srcChainId),
const walletAddress =
paramsToUpdate.walletAddress ?? this.#getSelectedAccount().address;
const srcChainIdInHex = formatChainIdFromDecimal(
updatedQuoteRequest.srcChainId,
);

const insufficientBal =
Expand All @@ -162,7 +164,9 @@ export default class BridgeController extends StaticIntervalPollingController<Br

#hasSufficientBalance = async (quoteRequest: QuoteRequest) => {
const walletAddress = this.#getSelectedAccount().address;
const srcChainIdInHex = add0x(decimalToHex(quoteRequest.srcChainId));
const srcChainIdInHexOrCaip = formatChainIdFromDecimal(
quoteRequest.srcChainId,
);
const provider = this.#getSelectedNetworkClient()?.provider;

return (
Expand All @@ -172,7 +176,7 @@ export default class BridgeController extends StaticIntervalPollingController<Br
walletAddress,
quoteRequest.srcTokenAddress,
quoteRequest.srcTokenAmount,
srcChainIdInHex,
srcChainIdInHexOrCaip,
))
);
};
Expand Down Expand Up @@ -287,8 +291,9 @@ export default class BridgeController extends StaticIntervalPollingController<Br
return await Promise.all(
quotes.map(async (quoteResponse) => {
const { quote, trade, approval } = quoteResponse;
const chainId = add0x(decimalToHex(quote.srcChainId)) as ChainId;
const chainId = formatChainIdFromDecimal(quote.srcChainId);
if (
!isCaipChainId(chainId) &&
[CHAIN_IDS.OPTIMISM.toString(), CHAIN_IDS.BASE.toString()].includes(
chainId,
)
Expand All @@ -303,12 +308,12 @@ export default class BridgeController extends StaticIntervalPollingController<Br
const approvalL1GasFees = approval
? await this.#getLayer1GasFee({
transactionParams: getTxParams(approval),
chainId,
chainId: chainId as ChainId,
})
: '0';
const tradeL1GasFees = await this.#getLayer1GasFee({
transactionParams: getTxParams(trade),
chainId,
chainId: chainId as ChainId,
});
return {
...quoteResponse,
Expand All @@ -330,7 +335,11 @@ export default class BridgeController extends StaticIntervalPollingController<Br
);
}

#getSelectedNetworkClientId(chainId: Hex) {
#getSelectedNetworkClientId(chainId: AllowedBridgeChainIds) {
if (isCaipChainId(chainId)) {
// TODO get solana network client id
return chainId;
}
return this.messagingSystem.call(
'NetworkController:findNetworkClientIdByChainId',
chainId,
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/lib/bridge-status/metrics-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Hex } from '@metamask/utils';
import { calcHexGasTotal } from '../../../../shared/lib/transaction-breakdown-utils';
import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils';
import {
Expand All @@ -15,6 +14,7 @@ import {
getUSDConversionRateByChainId,
// eslint-disable-next-line import/no-restricted-paths
} from '../../../../ui/selectors';
import { type AllowedBridgeChainIds } from '../../../../shared/constants/bridge';

export const getHexGasTotalUsd = ({
bridgeHistoryItem,
Expand Down Expand Up @@ -43,7 +43,7 @@ export const getTokenUsdValue = async ({
tokenAddress,
state,
}: {
chainId: Hex;
chainId: AllowedBridgeChainIds;
tokenAmount: number;
tokenAddress: string;
state: { metamask: MetricsBackgroundState };
Expand Down
8 changes: 4 additions & 4 deletions app/scripts/lib/bridge-status/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
BridgeStatusControllerBridgeTransactionCompleteEvent,
BridgeStatusControllerBridgeTransactionFailedEvent,
} from '../../controllers/bridge-status/types';
import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils';
import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils';
// eslint-disable-next-line import/no-restricted-paths
import {
Expand All @@ -24,6 +23,7 @@ import {
} from '../../../../shared/types/bridge-status';
import { isEthUsdt } from '../../../../shared/modules/bridge-utils/bridge.util';
import { getCommonProperties } from '../../../../shared/lib/bridge-status/metrics';
import { formatChainIdFromDecimal } from '../../../../shared/modules/bridge-utils/multichain';
import { getTokenUsdValue } from './metrics-utils';

type TrackEvent = (
Expand Down Expand Up @@ -81,7 +81,7 @@ export const handleBridgeTransactionComplete = async (
const destination_transaction = StatusTypes.COMPLETE;

const isEthUsdtTx = isEthUsdt(
decimalToPrefixedHex(quote.srcChainId),
formatChainIdFromDecimal(quote.srcChainId),
quote.srcAsset.address,
);

Expand Down Expand Up @@ -149,7 +149,7 @@ export const handleBridgeTransactionFailed = async (
: StatusTypes.FAILED;

const isEthUsdtTx = isEthUsdt(
decimalToPrefixedHex(quote.srcChainId),
formatChainIdFromDecimal(quote.srcChainId),
quote.srcAsset.address,
);

Expand Down Expand Up @@ -213,7 +213,7 @@ export const handleTransactionFailedTypeBridge = async (
const source_transaction = StatusTypes.FAILED;

const isEthUsdtTx = isEthUsdt(
decimalToPrefixedHex(quote.srcChainId),
formatChainIdFromDecimal(quote.srcChainId),
quote.srcAsset.address,
);
const allowanceResetTransaction =
Expand Down
5 changes: 2 additions & 3 deletions shared/constants/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { MultichainNetworks } from './multichain/networks';
///: END:ONLY_INCLUDE_IF
import { CHAIN_IDS, NETWORK_TO_NAME_MAP } from './network';

// TODO read from feature flags
export const ALLOWED_BRIDGE_CHAIN_IDS = [
CHAIN_IDS.MAINNET,
CHAIN_IDS.BSC,
Expand All @@ -17,7 +16,7 @@ export const ALLOWED_BRIDGE_CHAIN_IDS = [
///: BEGIN:ONLY_INCLUDE_IF(solana-swaps)
MultichainNetworks.SOLANA,
///: END:ONLY_INCLUDE_IF
];
] as const;

export type AllowedBridgeChainIds = (typeof ALLOWED_BRIDGE_CHAIN_IDS)[number];

Expand All @@ -39,7 +38,7 @@ export const BRIDGE_PREFERRED_GAS_ESTIMATE = 'high';
export const BRIDGE_DEFAULT_SLIPPAGE = 0.5;

export const NETWORK_TO_SHORT_NETWORK_NAME_MAP: Record<
AllowedBridgeChainIds,
AllowedBridgeChainIds | MultichainNetworks,
string
> = {
[CHAIN_IDS.MAINNET]: 'Ethereum',
Expand Down
16 changes: 13 additions & 3 deletions shared/constants/swaps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
///: BEGIN:ONLY_INCLUDE_IF(solana-swaps)
import { MultichainNetworks } from './multichain/networks';
///: END:ONLY_INCLUDE_IF
import {
MULTICHAIN_TOKEN_IMAGE_MAP,
MultichainNetworks,
} from './multichain/networks';
import {
ETH_TOKEN_IMAGE_URL,
TEST_ETH_TOKEN_IMAGE_URL,
Expand Down Expand Up @@ -129,6 +130,14 @@ export const BASE_SWAPS_TOKEN_OBJECT: SwapsTokenObject = {
...ETH_SWAPS_TOKEN_OBJECT,
} as const;

const SOLANA_SWAPS_TOKEN_OBJECT: SwapsTokenObject = {
symbol: 'SOL',
name: 'Solana',
address: DEFAULT_TOKEN_ADDRESS,
decimals: 9,
iconUrl: MULTICHAIN_TOKEN_IMAGE_MAP[MultichainNetworks.SOLANA],
};

// A gas value for ERC20 approve calls that should be sufficient for all ERC20 approve implementations
export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0';

Expand Down Expand Up @@ -288,6 +297,7 @@ export const SWAPS_CHAINID_DEFAULT_TOKEN_MAP = {
[CHAIN_IDS.ZKSYNC_ERA]: ZKSYNC_ERA_SWAPS_TOKEN_OBJECT,
[CHAIN_IDS.LINEA_MAINNET]: LINEA_SWAPS_TOKEN_OBJECT,
[CHAIN_IDS.BASE]: BASE_SWAPS_TOKEN_OBJECT,
[MultichainNetworks.SOLANA]: SOLANA_SWAPS_TOKEN_OBJECT,
} as const;

export const ETHEREUM = 'ethereum';
Expand Down
6 changes: 3 additions & 3 deletions shared/lib/bridge-status/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { ActionType } from '../../../ui/hooks/bridge/events/types';
import { formatProviderLabel } from '../../../ui/pages/bridge/utils/quote';
import { getCurrentKeyring } from '../../../ui/selectors';
import { BRIDGE_DEFAULT_SLIPPAGE } from '../../constants/bridge';
import { decimalToPrefixedHex } from '../../modules/conversion.utils';
import { getIsSmartTransaction } from '../../modules/selectors';
import { formatChainIdFromDecimal } from '../../modules/bridge-utils/multichain';

export const getCommonProperties = (
bridgeHistoryItem: BridgeHistoryItem,
Expand All @@ -20,10 +20,10 @@ export const getCommonProperties = (
// @ts-expect-error keyring type is possibly wrong
const is_hardware_wallet = isHardwareKeyring(keyring.type) ?? false;

const chain_id_source = decimalToPrefixedHex(
const chain_id_source = formatChainIdFromDecimal(
bridgeHistoryItem.quote.srcChainId,
);
const chain_id_destination = decimalToPrefixedHex(
const chain_id_destination = formatChainIdFromDecimal(
bridgeHistoryItem.quote.destChainId,
);

Expand Down
9 changes: 7 additions & 2 deletions shared/modules/bridge-utils/balance.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Web3Provider } from '@ethersproject/providers';
import type { Provider } from '@metamask/network-controller';
import { Hex } from '@metamask/utils';
import { type Hex, isCaipChainId } from '@metamask/utils';
import { zeroAddress } from 'ethereumjs-util';
import { getAddress } from 'ethers/lib/utils';
import { fetchTokenBalance } from '../../lib/token-util';
import { Numeric } from '../Numeric';
import { type AllowedBridgeChainIds } from '../../constants/bridge';

export const calcLatestSrcBalance = async (
provider: Provider,
Expand Down Expand Up @@ -37,8 +38,12 @@ export const hasSufficientBalance = async (
selectedAddress: string,
tokenAddress: string,
fromTokenAmount: string,
chainId: Hex,
chainId: AllowedBridgeChainIds,
) => {
if (isCaipChainId(chainId)) {
// TODO check solana balance
return true;
}
const srcTokenBalance = await calcLatestSrcBalance(
provider,
selectedAddress,
Expand Down
14 changes: 11 additions & 3 deletions shared/modules/bridge-utils/bridge.util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ describe('Bridge utils', () => {
isActiveSrc: false,
isActiveDest: true,
},
'1151111081099710': {
isActiveSrc: true,
isActiveDest: true,
},
},
},
};
Expand Down Expand Up @@ -96,6 +100,10 @@ describe('Bridge utils', () => {
isActiveSrc: false,
isActiveDest: true,
},
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
isActiveDest: true,
isActiveSrc: true,
},
},
},
});
Expand Down Expand Up @@ -248,7 +256,7 @@ describe('Bridge utils', () => {
);

expect(fetchWithCache).toHaveBeenCalledWith({
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&destWalletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
fetchOptions: {
method: 'GET',
headers: { 'X-Client-Id': 'extension' },
Expand Down Expand Up @@ -283,7 +291,7 @@ describe('Bridge utils', () => {
);

expect(fetchWithCache).toHaveBeenCalledWith({
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&destWalletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
fetchOptions: {
method: 'GET',
headers: { 'X-Client-Id': 'extension' },
Expand Down Expand Up @@ -337,7 +345,7 @@ describe('Bridge utils', () => {
);

expect(fetchWithCache).toHaveBeenCalledWith({
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
url: 'https://bridge.api.cx.metamask.io/getQuote?walletAddress=0x123&destWalletAddress=0x123&srcChainId=1&destChainId=10&srcTokenAddress=0x0000000000000000000000000000000000000000&destTokenAddress=0x0000000000000000000000000000000000000000&srcTokenAmount=20000&slippage=0.5&insufficientBal=false&resetApproval=false',
fetchOptions: {
method: 'GET',
headers: { 'X-Client-Id': 'extension' },
Expand Down
Loading
Loading