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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe('BridgeController SSE', function () {
isActiveDest: true,
},
},
chainRanking: [{ chainId: 'eip155:1' as const, name: 'Ethereum' }],
});

bridgeController = new BridgeController({
Expand Down
1 change: 1 addition & 0 deletions packages/bridge-controller/src/bridge-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2700,6 +2700,7 @@ describe('BridgeController', function () {
enabled: true,
minimumVersion: '13.8.0',
},
chainRanking: [{ chainId: 'eip155:1' as const, name: 'Ethereum' }],
};

const quotesByDecreasingProcessingTime = [...mockBridgeQuotesSolErc20];
Expand Down
18 changes: 18 additions & 0 deletions packages/bridge-controller/src/constants/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,30 @@ export const DEFAULT_MAX_REFRESH_COUNT = 5;

export const BRIDGE_CONTROLLER_NAME = 'BridgeController';

export const DEFAULT_CHAIN_RANKING = [
{ chainId: 'eip155:1', name: 'Ethereum' },
{ chainId: 'eip155:56', name: 'BNB' },
{ chainId: 'bip122:000000000019d6689c085ae165831e93', name: 'BTC' },
{ chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', name: 'Solana' },
{ chainId: 'tron:728126428', name: 'Tron' },
{ chainId: 'eip155:8453', name: 'Base' },
{ chainId: 'eip155:42161', name: 'Arbitrum' },
{ chainId: 'eip155:59144', name: 'Linea' },
{ chainId: 'eip155:137', name: 'Polygon' },
{ chainId: 'eip155:43114', name: 'Avalanche' },
{ chainId: 'eip155:10', name: 'Optimism' },
{ chainId: 'eip155:143', name: 'Monad' },
{ chainId: 'eip155:1329', name: 'Sei' },
{ chainId: 'eip155:324', name: 'zkSync' },
] as const;

export const DEFAULT_FEATURE_FLAG_CONFIG: FeatureFlagsPlatformConfig = {
minimumVersion: '0.0.0',
refreshRate: REFRESH_INTERVAL_MS,
maxRefreshCount: DEFAULT_MAX_REFRESH_COUNT,
support: false,
chains: {},
chainRanking: [...DEFAULT_CHAIN_RANKING],
};

export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = {
Expand Down
4 changes: 2 additions & 2 deletions packages/bridge-controller/src/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ describe('Bridge Selectors', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(mockState.remoteFeatureFlags.bridgeConfig as any),
chains: {
'1': {
'eip155:1': {
refreshRate: 41000,
isActiveSrc: true,
isActiveDest: true,
Expand Down Expand Up @@ -288,7 +288,7 @@ describe('Bridge Selectors', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(mockState.remoteFeatureFlags.bridgeConfig as any),
chains: {
'1': {
'eip155:1': {
refreshRate: 41000,
isActiveSrc: true,
isActiveDest: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/bridge-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type {
BitcoinTradeDataSchema,
BridgeAssetSchema,
ChainConfigurationSchema,
ChainRankingSchema,
FeatureId,
FeeDataSchema,
PlatformConfigSchema,
Expand Down Expand Up @@ -66,6 +67,8 @@ export enum AssetType {

export type ChainConfiguration = Infer<typeof ChainConfigurationSchema>;

export type ChainRanking = Infer<typeof ChainRankingSchema>;

export type L1GasFees = {
l1GasFeesInHexWei?: string; // l1 fees for approval and trade in hex wei, appended by BridgeController.#appendL1GasFees
};
Expand Down
8 changes: 8 additions & 0 deletions packages/bridge-controller/src/utils/feature-flags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

const result = formatFeatureFlags(bridgeConfig);
Expand Down Expand Up @@ -95,6 +96,7 @@ describe('feature-flags', () => {
support: true,
minimumVersion: '0.0.0',
chains: {},
chainRanking: [],
};

const result = formatFeatureFlags(bridgeConfig);
Expand Down Expand Up @@ -124,6 +126,7 @@ describe('feature-flags', () => {
isActiveDest: false,
},
},
chainRanking: [],
};

const result = formatFeatureFlags(bridgeConfig);
Expand Down Expand Up @@ -373,6 +376,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

const bridgeConfig = {
Expand All @@ -386,6 +390,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

const remoteFeatureFlagControllerState = {
Expand Down Expand Up @@ -414,6 +419,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

expect(result).toStrictEqual(expectedBridgeConfig);
Expand All @@ -431,6 +437,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

const remoteFeatureFlagControllerState = {
Expand Down Expand Up @@ -458,6 +465,7 @@ describe('feature-flags', () => {
isActiveDest: true,
},
},
chainRanking: [],
};

expect(result).toStrictEqual(expectedBridgeConfig);
Expand Down
6 changes: 6 additions & 0 deletions packages/bridge-controller/src/utils/validators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('validators', () => {
refreshRate: 30000,
support: true,
minimumVersion: '0.0.0',
chainRanking: [{ chainId: 'eip155:1', name: 'Ethereum' }],
},
type: 'all evm chains active',
expected: true,
Expand All @@ -39,6 +40,7 @@ describe('validators', () => {
refreshRate: 3000000,
support: false,
minimumVersion: '0.0.0',
chainRanking: [],
},
type: 'bridge disabled',
expected: true,
Expand Down Expand Up @@ -103,6 +105,7 @@ describe('validators', () => {
refreshRate: 30000,
support: true,
minimumVersion: '0.0.0',
chainRanking: [{ chainId: 'eip155:1', name: 'Ethereum' }],
},
type: 'evm and solana chain config',
expected: true,
Expand Down Expand Up @@ -200,6 +203,7 @@ describe('validators', () => {
refreshRate: 30000,
support: true,
minimumVersion: '0.0.0',
chainRanking: [{ chainId: 'eip155:1', name: 'Ethereum' }],
},
type: 'evm and solana chain config + bip44 default pairs',
expected: true,
Expand Down Expand Up @@ -227,6 +231,7 @@ describe('validators', () => {
enabled: true,
minimumVersion: '13.8.0',
},
chainRanking: [{ chainId: 'eip155:1', name: 'Ethereum' }],
},
type: 'sse config',
expected: true,
Expand Down Expand Up @@ -306,6 +311,7 @@ describe('validators', () => {
support: true,
minimumVersion: '0.0.0',
extraField: 'foo',
chainRanking: [{ chainId: 'eip155:1', name: 'Ethereum' }],
},
type: 'all evm chains active + an extra field not specified in the schema',
expected: true,
Expand Down
23 changes: 22 additions & 1 deletion packages/bridge-controller/src/utils/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import {
pattern,
intersection,
} from '@metamask/superstruct';
import { CaipAssetTypeStruct, isStrictHexString } from '@metamask/utils';
import {
CaipAssetTypeStruct,
CaipChainIdStruct,
isStrictHexString,
} from '@metamask/utils';

export enum FeeType {
METABRIDGE = 'metabridge',
Expand Down Expand Up @@ -101,6 +105,19 @@ const DefaultPairSchema = type({
other: record(string(), string()),
});

export const ChainRankingItemSchema = type({
/**
* The CAIP-2 chain identifier (e.g., "eip155:1" for Ethereum mainnet)
*/
chainId: CaipChainIdStruct,
/**
* The display name of the chain (e.g., "Ethereum Mainnet")
*/
name: string(),
});

export const ChainRankingSchema = array(ChainRankingItemSchema);

export const ChainConfigurationSchema = type({
isActiveSrc: boolean(),
isActiveDest: boolean(),
Expand Down Expand Up @@ -154,6 +171,10 @@ export const PlatformConfigSchema = type({
minimumVersion: VersionStringSchema,
}),
),
/**
* Array of chain objects ordered by preference/ranking
*/
chainRanking: ChainRankingSchema,
});

export const validateFeatureFlagsResponse = (
Expand Down
Loading