From 508ee40c3f3175d97ae4c8095462dc918b105364 Mon Sep 17 00:00:00 2001 From: Bartek Date: Thu, 3 Oct 2024 17:22:53 +0200 Subject: [PATCH] feat: sort chain IDs with core chains on top (#1962) --- .../src/util/__tests__/networks.test.ts | 45 +++++++++++++++++++ .../arb-token-bridge-ui/src/util/networks.ts | 30 +++++++++++-- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts b/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts index ff1f88a4d9..554663bf91 100644 --- a/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts +++ b/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts @@ -3,6 +3,7 @@ import { registerCustomArbitrumNetwork } from '@arbitrum/sdk' import { ChainId, getBaseChainIdByChainId, + getDestinationChainIds, getSupportedChainIds } from '../networks' import { orbitTestnets } from '../orbitChainsList' @@ -210,3 +211,47 @@ describe('getSupportedChainIds', () => { }) }) }) + +describe('getDestinationChainIds', () => { + function isAscending(arr: number[]) { + return arr.every( + (value, index) => index === 0 || value >= Number(arr[index - 1]) + ) + } + + it('should return a sorted list for Ethereum Mainnet', () => { + const destinationChainIds = getDestinationChainIds(ChainId.Ethereum) + const defaultChainId = destinationChainIds[0] + const nonDefaultChainIds = destinationChainIds.slice(1) + + expect(defaultChainId).toBe(ChainId.ArbitrumOne) + expect(isAscending(nonDefaultChainIds)).toBe(true) + }) + + it('should return a sorted list for Arbitrum One', () => { + const destinationChainIds = getDestinationChainIds(ChainId.ArbitrumOne) + const defaultChainId = destinationChainIds[0] + const nonDefaultChainIds = destinationChainIds.slice(1) + + expect(defaultChainId).toBe(ChainId.Ethereum) + expect(isAscending(nonDefaultChainIds)).toBe(true) + }) + + it('should return a sorted list for Sepolia', () => { + const destinationChainIds = getDestinationChainIds(ChainId.Sepolia) + const defaultChainId = destinationChainIds[0] + const nonDefaultChainIds = destinationChainIds.slice(1) + + expect(defaultChainId).toBe(ChainId.ArbitrumSepolia) + expect(isAscending(nonDefaultChainIds)).toBe(true) + }) + + it('should return a sorted list for Arbitrum Sepolia', () => { + const destinationChainIds = getDestinationChainIds(ChainId.ArbitrumSepolia) + const defaultChainId = destinationChainIds[0] + const nonDefaultChainIds = destinationChainIds.slice(1) + + expect(defaultChainId).toBe(ChainId.Sepolia) + expect(isAscending(nonDefaultChainIds)).toBe(true) + }) +}) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index 06252531de..e6b22e9a83 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -487,6 +487,31 @@ export function getChildChainIds(chain: ArbitrumNetwork | L1Network) { return Array.from(new Set(childChainIds)) } +/** + * Sorts an array of chain IDs in ascending order (default) but keep core chains on top. + * This is helpful e.g. when we grab the default chain which is the first chain on top. + */ +export function sortChainIds(chainIds: number[]) { + return chainIds.sort((a, b) => { + const { isCoreChain: isCoreChainA } = isNetwork(a) + const { isCoreChain: isCoreChainB } = isNetwork(b) + + if (isCoreChainA && isCoreChainB) { + // Both are core chains, sort in ascending order + return a - b + } else if (isCoreChainA) { + // Only A is core chain, it should come first + return -1 + } else if (isCoreChainB) { + // Only B is core chain, it should come first + return 1 + } else { + // Neither are core chains, sort in ascending order + return a - b + } + }) +} + export function getDestinationChainIds(chainId: ChainId): ChainId[] { const chain = getChainByChainId(chainId) @@ -499,9 +524,8 @@ export function getDestinationChainIds(chainId: ChainId): ChainId[] { const validDestinationChainIds = getChildChainIds(chain) if (parentChainId) { - // always make parent chain the first element - return [parentChainId, ...validDestinationChainIds] + return sortChainIds([parentChainId, ...validDestinationChainIds]) } - return validDestinationChainIds + return sortChainIds(validDestinationChainIds) }