From a9a986d12b66e052d8f53412ec60ea0003bd0ce2 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:59:38 +0100 Subject: [PATCH 01/19] feat: support base and base sepolia --- .../arb-token-bridge-ui/src/util/infura.ts | 8 ++++ .../arb-token-bridge-ui/src/util/networks.ts | 22 +++++++++- .../src/util/wagmi/getWagmiChain.ts | 10 ++++- .../src/util/wagmi/wagmiAdditionalNetworks.ts | 41 +++++++++++++++++++ packages/scripts/src/addOrbitChain/schemas.ts | 14 +++++++ 5 files changed, 93 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/infura.ts b/packages/arb-token-bridge-ui/src/util/infura.ts index 02124bb907..20fa95514d 100644 --- a/packages/arb-token-bridge-ui/src/util/infura.ts +++ b/packages/arb-token-bridge-ui/src/util/infura.ts @@ -61,10 +61,14 @@ export function chainIdToInfuraKey(chainId: ChainId) { return process.env.NEXT_PUBLIC_INFURA_KEY_SEPOLIA || defaultInfuraKey case ChainId.ArbitrumOne: return process.env.NEXT_PUBLIC_INFURA_KEY_ARBITRUM_ONE || defaultInfuraKey + case ChainId.Base: + return process.env.NEXT_PUBLIC_INFURA_KEY_BASE || defaultInfuraKey case ChainId.ArbitrumSepolia: return ( process.env.NEXT_PUBLIC_INFURA_KEY_ARBITRUM_SEPOLIA || defaultInfuraKey ) + case ChainId.BaseSepolia: + return process.env.NEXT_PUBLIC_INFURA_KEY_BASE_SEPOLIA || defaultInfuraKey default: return defaultInfuraKey @@ -81,8 +85,12 @@ export function chainIdToInfuraUrl(chainId: ChainId) { return `https://sepolia.infura.io/v3/${infuraKey}` case ChainId.ArbitrumOne: return `https://arbitrum-mainnet.infura.io/v3/${infuraKey}` + case ChainId.Base: + return `https://base-mainnet.infura.io/v3/${infuraKey}` case ChainId.ArbitrumSepolia: return `https://arbitrum-sepolia.infura.io/v3/${infuraKey}` + case ChainId.BaseSepolia: + return `https://base-sepolia.infura.io/v3/${infuraKey}` default: return undefined } diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index e6b22e9a83..c8094f4e8c 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -20,9 +20,11 @@ export enum ChainId { // L2 ArbitrumOne = 42161, ArbitrumNova = 42170, + Base = 8453, // L2 Testnets ArbitrumSepolia = 421614, ArbitrumLocal = 412346, + BaseSepolia = 84532, // L3 Testnets L3Local = 333333 } @@ -208,10 +210,18 @@ export const rpcURLs: { [chainId: number]: string } = { fallback: 'https://arb1.arbitrum.io/rpc' }), [ChainId.ArbitrumNova]: 'https://nova.arbitrum.io/rpc', + [ChainId.Base]: loadEnvironmentVariableWithFallback({ + env: chainIdToInfuraUrl(ChainId.Base), + fallback: 'https://mainnet.base.org' + }), // L2 Testnets [ChainId.ArbitrumSepolia]: loadEnvironmentVariableWithFallback({ env: chainIdToInfuraUrl(ChainId.ArbitrumSepolia), fallback: 'https://sepolia-rollup.arbitrum.io/rpc' + }), + [ChainId.BaseSepolia]: loadEnvironmentVariableWithFallback({ + env: chainIdToInfuraUrl(ChainId.BaseSepolia), + fallback: 'https://sepolia.base.org' }) } @@ -224,8 +234,10 @@ export const explorerUrls: { [chainId: number]: string } = { // L2 [ChainId.ArbitrumNova]: 'https://nova.arbiscan.io', [ChainId.ArbitrumOne]: 'https://arbiscan.io', + [ChainId.Base]: 'https://basescan.org', // L2 Testnets - [ChainId.ArbitrumSepolia]: 'https://sepolia.arbiscan.io' + [ChainId.ArbitrumSepolia]: 'https://sepolia.arbiscan.io', + [ChainId.BaseSepolia]: 'https://sepolia.basescan.org' } export const getExplorerUrl = (chainId: ChainId) => { @@ -397,12 +409,17 @@ export function isNetwork(chainId: ChainId) { const isArbitrumSepolia = chainId === ChainId.ArbitrumSepolia const isArbitrumLocal = chainId === ChainId.ArbitrumLocal + const isBaseMainnet = chainId === ChainId.Base + const isBaseSepolia = chainId === ChainId.BaseSepolia + const isEthereumMainnetOrTestnet = isEthereumMainnet || isSepolia || isHolesky || isLocal const isArbitrum = isArbitrumOne || isArbitrumNova || isArbitrumLocal || isArbitrumSepolia + const isBase = isBaseMainnet || isBaseSepolia + const isCoreChain = isEthereumMainnetOrTestnet || isArbitrum const isOrbitChain = !isCoreChain @@ -416,8 +433,11 @@ export function isNetwork(chainId: ChainId) { isArbitrum, isArbitrumOne, isArbitrumNova, + isBase, + isBaseMainnet, // L2 Testnets isArbitrumSepolia, + isBaseSepolia, // Orbit chains isOrbitChain, // General diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts index bd6774c656..66de1b1b0f 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts @@ -9,7 +9,9 @@ import { arbitrumSepolia, localL1Network, localL2Network, - localL3Network + localL3Network, + baseSepolia, + base } from './wagmiAdditionalNetworks' import { ChainId } from '../networks' import { getCustomChainFromLocalStorageById } from '../networks' @@ -37,6 +39,9 @@ export function getWagmiChain(chainId: number): Chain { case ChainId.ArbitrumNova: return arbitrumNova + case ChainId.Base: + return base + // Testnets case ChainId.Sepolia: return sepolia @@ -47,6 +52,9 @@ export function getWagmiChain(chainId: number): Chain { case ChainId.ArbitrumSepolia: return arbitrumSepolia + case ChainId.BaseSepolia: + return baseSepolia + // Local networks case ChainId.Local: return localL1Network diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts b/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts index 4ab0f3b6a9..857f4f8bee 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts @@ -85,6 +85,28 @@ export const arbitrumSepolia: Chain = { } } +export const baseSepolia: Chain = { + id: ChainId.BaseSepolia, + name: 'Base Sepolia', + network: 'base-sepolia', + nativeCurrency: ether, + rpcUrls: { + default: { + http: [rpcURLs[ChainId.BaseSepolia]!] + }, + public: { + http: [rpcURLs[ChainId.BaseSepolia]!] + } + }, + blockExplorers: { + etherscan: { + name: 'Basescan', + url: explorerUrls[ChainId.BaseSepolia]! + }, + default: { name: 'Basescan', url: explorerUrls[ChainId.BaseSepolia]! } + } +} + export const arbitrumNova: Chain = { id: ChainId.ArbitrumNova, name: 'Arbitrum Nova', @@ -104,6 +126,25 @@ export const arbitrumNova: Chain = { } } +export const base: Chain = { + id: ChainId.Base, + name: 'Base', + network: 'base', + nativeCurrency: ether, + rpcUrls: { + default: { + http: [rpcURLs[ChainId.Base]!] + }, + public: { + http: [rpcURLs[ChainId.Base]!] + } + }, + blockExplorers: { + etherscan: { name: 'Basescan', url: explorerUrls[ChainId.Base]! }, + default: { name: 'Basescan', url: explorerUrls[ChainId.Base]! } + } +} + /** * For e2e testing */ diff --git a/packages/scripts/src/addOrbitChain/schemas.ts b/packages/scripts/src/addOrbitChain/schemas.ts index 87ff3072de..fb4441652b 100644 --- a/packages/scripts/src/addOrbitChain/schemas.ts +++ b/packages/scripts/src/addOrbitChain/schemas.ts @@ -128,6 +128,20 @@ export const chainSchema = z chainId: 17000, name: "Holesky", }; + case 8453: // Base + return { + rpcUrl: "https://mainnet.base.org", + blockExplorer: "https://basescan.io", + chainId: 8453, + name: "Base", + }; + case 8453: // Base + return { + rpcUrl: "https://sepolia.base.org", + blockExplorer: "https://sepolia.basescan.io", + chainId: 84532, + name: "Base Sepolia", + }; default: throw new Error(`Unsupported parent chain ID: ${parentChainId}`); } From c6eeae8777cdf1659024f59c553cd8d2d48f7206 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:21:32 +0100 Subject: [PATCH 02/19] make tx panel work --- .../arb-token-bridge-ui/.env.local.sample | 2 + .../public/images/BaseWhite.svg | 3 + .../public/images/PolterTestnetLogo.png | Bin 0 -> 15086 bytes .../public/images/ghst.png | Bin 0 -> 1548 bytes .../src/components/App/App.tsx | 9 +-- .../components/TransferPanel/TokenButton.tsx | 2 +- .../src/hooks/useNetworks.ts | 6 +- .../src/token-bridge-sdk/utils.ts | 8 +-- .../src/types/ChainQueryParam.ts | 14 +++++ .../src/util/bridgeUiConfig.ts | 19 ++++++ .../src/util/isDepositMode.ts | 7 ++- .../arb-token-bridge-ui/src/util/networks.ts | 59 ++++++++++++++++-- .../src/util/orbitChainsData.json | 50 +++++++++++++++ .../src/util/wagmi/setup.ts | 18 +++++- 14 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 packages/arb-token-bridge-ui/public/images/BaseWhite.svg create mode 100644 packages/arb-token-bridge-ui/public/images/PolterTestnetLogo.png create mode 100644 packages/arb-token-bridge-ui/public/images/ghst.png diff --git a/packages/arb-token-bridge-ui/.env.local.sample b/packages/arb-token-bridge-ui/.env.local.sample index f1b1d7ea73..e7605f04b2 100644 --- a/packages/arb-token-bridge-ui/.env.local.sample +++ b/packages/arb-token-bridge-ui/.env.local.sample @@ -8,8 +8,10 @@ NEXT_PUBLIC_INFURA_KEY_SEPOLIA= # L2 NEXT_PUBLIC_INFURA_KEY_ARBITRUM_ONE= +NEXT_PUBLIC_INFURA_KEY_BASE= # L2 Testnet NEXT_PUBLIC_INFURA_KEY_ARBITRUM_SEPOLIA= +NEXT_PUBLIC_INFURA_KEY_BASE_SEPOLIA= NEXT_PUBLIC_SENTRY_DSN= diff --git a/packages/arb-token-bridge-ui/public/images/BaseWhite.svg b/packages/arb-token-bridge-ui/public/images/BaseWhite.svg new file mode 100644 index 0000000000..72e52ac2f8 --- /dev/null +++ b/packages/arb-token-bridge-ui/public/images/BaseWhite.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/arb-token-bridge-ui/public/images/PolterTestnetLogo.png b/packages/arb-token-bridge-ui/public/images/PolterTestnetLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..70ee5c61fb6933d164c6c5432178686fb49a90c4 GIT binary patch literal 15086 zcmeHNNoW*76s<9?7mcE(YD`QJg}8tLMTp=Af?h-r6~P6!g9kxDM8repq=E-g^dKHY zMQ{O8au5|!yeN2b!Gov_BA();dSWzc%=cCI^f)s;J-sI;)WDxVT~)vS>))@I{!@&l zSRHF?W6&+^`W(iVF!t}dp0ST8v+MVbX6!f`w5m3coe*WGKCKf>RrW=OAT2rungf~x zngf~xBbWnO+}nr1B6;6`5tF=_TDEZeya4tW8h;GqTE~BA_lY|G!!!O}Qznv}IXSrS zyRpt&A^GETnsqb-_FEc%$-JxM@8C$S0?nTi?x-Av=1(oUIO>L)KSZpKq*w#FLXt0b z0Q4vrD*V*bFrN&561cw<=kL5&<^k7HJ(&2ZyP*X!J_gKhi4g;M;1zsF>xcT;Ziq^h8N7Gms-Mqfs(_zivyvF>*CDa9+q>Ii*JH~EC; z*$jMKbtvXcd!v2-KrFw2pK>N62F z7c^PAjz|{#**aUeep1jGOAjaoTv=1c{H4xmwLn%vis!Vdyd4hWK1+|=VK8nrAME#3 z{t2}w&U_f@UEuPgV$MbKr=I?$I2xA!$W4tg zbL)n08Ah zl7B0g%6|^Fe?03&kj@Bx3q0|?|FZUIR=)dVbiV<48kE<%eXw~z$1Blz)tW_9NV${? zWl~fj{T-Q97Q#9*NQq>S&%mabU^f8ihnQIqS2rq8Q4eW>6!R1*TvU8U*0|;;%)Nu! zKiFc39{=~qw^f8k?eTMw?DJwh_8OZ?Gq`UK{K2M<7=_rT!m~c#ehBA z(i;8|e|{P^Z_wr(+P0V4s^26VHoMzn|7o4K7*lCyU!(uK?)J6g2fG9AwrYK?VhtAF}0WN0&h literal 0 HcmV?d00001 diff --git a/packages/arb-token-bridge-ui/public/images/ghst.png b/packages/arb-token-bridge-ui/public/images/ghst.png new file mode 100644 index 0000000000000000000000000000000000000000..b571b7eef9e2bfa9b7322247afd384f4a50a2360 GIT binary patch literal 1548 zcmV+n2J`ueP)jUm)3i-t#<5ve__Elx-3y z(21xB6oK~Xc#N`U|ZE)n4Cm!$A7=hGen@DiHA=kB;-3UsI#ZablwJjb>xRt2N6 zT^MF3!3;c?=fbC9^?$q4P)blHp3@WIuwWDimLimm=XF&ZyI}uDRT@ef%*b=QqV=kD z7=bb&%=0_azg6j31j>wA-ouvGcBjJ#lqt@h39Gwd|0*t2-q<`RtUR0!B2Xd7y*u2( z_tXd)D+%hvd*;;=8Y&UqGp81O=}`nKl;W4ofBRBU$?(2enyZ11JGfINLmhckV^By7Ppc-6AbKOtch{9pr(wR)yuTHAZ(V;X;QI?Vy2<<#8qZx&ncl61+{JT= z&n*UZ<^7dgxWP^AYHnZBSR<9RzK*6o@L7TPS7!Vva0{op;a6>~wSITglqDZo<){6r z00M5{mc)9oRh4fls42f@%9Mu(|7e}U2i#!gv%)7k8TI)t8|%vG(lZmLT=_5#z#la! zaLUSnd*w-Yt}no3ONI5$09Ui>mRxEfbbOsyDO8mNfiM*LPofgzpHIQZH6gfCZ+#}6G|5Xo zg6GeN@-yBPW9sEN#N*aKo!J!?$Sgs#t!Qm+P4`WQXAPfKl&g4Sh3g0I5AjN(d>0lV zXr>j3^1|C&J7&sW2<69yBv|E(x*7PeHpDYHmMGBs=oNkaP{S4^wc=NRndQkx@XW2^1{nA$zU9S3r!k0 z#i~U4Lv=$sXPe~8fBoXP;pG`*F%H1_rexqeK46y%ZN&?aMEQ3yJn@}m`Ajd*AWt&; zyNBoSK_@JRw)BAcBnrHP;fXU?o_sgE@B8RKIk}WsUU>OzJ7kq7oo&{@DI>4W!Q1ub zbAl*vH z1v*Z*Xy69ngZH1lZ!`?)47Nl~`{ZKexpmz)_|mxH<@-2+I`ZCG`U-b)i|(cwcpVFz z!t#7uAx=JZSN9Qon^SmSlY%XYQ3Tv#uthaJW`*O;5z}KXQ2YxLq`_7UUV-qQdG);l z)u+%S~V% yx-hUS;97kBveV(cYUh!?s)|4nRN9yOz0&{0p7!99EAIgS0000 { actions.app.setConnectionState(ConnectionState.LOADING) const { - isArbitrum: isConnectedToArbitrum, - isOrbitChain: isConnectedToOrbitChain + isArbitrum: isSourceChainArbitrum, + isOrbitChain: isSourceChainOrbitChain, + isBase: isSourceChainBaseChain } = isNetwork(networks.sourceChain.id) const isParentChainEthereum = isNetwork( parentChain.id @@ -114,8 +115,8 @@ const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => { }) if ( - (isParentChainEthereum && isConnectedToArbitrum) || - isConnectedToOrbitChain + (isParentChainEthereum && isSourceChainArbitrum) || + (isSourceChainOrbitChain && !isSourceChainBaseChain) ) { console.info('Withdrawal mode detected:') actions.app.setConnectionState(ConnectionState.L2_CONNECTED) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx index eaa43c8007..942fc555d4 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react' +import { useEffect, useMemo } from 'react' import { Popover } from '@headlessui/react' import { ChevronDownIcon } from '@heroicons/react/24/outline' import { twMerge } from 'tailwind-merge' diff --git a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts index 64a394d3fb..7a3809422a 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts @@ -12,7 +12,9 @@ import { arbitrumSepolia, localL1Network as local, localL2Network as arbitrumLocal, - localL3Network as l3Local + localL3Network as l3Local, + base, + baseSepolia } from '../util/wagmi/wagmiAdditionalNetworks' import { getDestinationChainIds } from '../util/networks' @@ -37,7 +39,9 @@ export function isSupportedChainId( holesky.id, arbitrum.id, arbitrumNova.id, + base.id, arbitrumSepolia.id, + baseSepolia.id, arbitrumLocal.id, l3Local.id, local.id, diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts index 7dbf694b29..c256eb62c4 100644 --- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts +++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts @@ -11,6 +11,7 @@ import { EthL1L3Bridger, getArbitrumNetwork } from '@arbitrum/sdk' +import { isDepositMode } from '../util/isDepositMode' export const getAddressFromSigner = async (signer: Signer) => { const address = await signer.getAddress() @@ -28,8 +29,6 @@ export const getBridgeTransferProperties = ( const sourceChainId = props.sourceChainId const destinationChainId = props.destinationChainId - const isSourceChainEthereumMainnetOrTestnet = - isNetwork(sourceChainId).isEthereumMainnetOrTestnet const isDestinationChainEthereumMainnetOrTestnet = isNetwork(destinationChainId).isEthereumMainnetOrTestnet @@ -37,11 +36,8 @@ export const getBridgeTransferProperties = ( const isDestinationChainArbitrum = isNetwork(destinationChainId).isArbitrum const isSourceChainOrbit = isNetwork(sourceChainId).isOrbitChain - const isDestinationChainOrbit = isNetwork(destinationChainId).isOrbitChain - const isDeposit = - isSourceChainEthereumMainnetOrTestnet || - (isSourceChainArbitrum && isDestinationChainOrbit) + const isDeposit = isDepositMode({ sourceChainId, destinationChainId }) const isWithdrawal = (isSourceChainArbitrum && isDestinationChainEthereumMainnetOrTestnet) || // l2 arbitrum chains to l1 diff --git a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts index 6a9dde793a..e47e93ec97 100644 --- a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts +++ b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts @@ -15,7 +15,9 @@ const chainQueryParams = [ 'sepolia', 'arbitrum-one', 'arbitrum-nova', + 'base', 'arbitrum-sepolia', + 'base-sepolia', 'custom-localhost', 'arbitrum-localhost', 'l3-localhost' @@ -50,12 +52,18 @@ export function getChainQueryParamForChain(chainId: ChainId): ChainQueryParam { case ChainId.ArbitrumNova: return 'arbitrum-nova' + case ChainId.Base: + return 'base' + case ChainId.Sepolia: return 'sepolia' case ChainId.ArbitrumSepolia: return 'arbitrum-sepolia' + case ChainId.BaseSepolia: + return 'base-sepolia' + case ChainId.Local: return 'custom-localhost' @@ -100,9 +108,15 @@ export function getChainForChainKeyQueryParam( case 'arbitrum-nova': return customChains.arbitrumNova + case 'base': + return customChains.base + case 'arbitrum-sepolia': return customChains.arbitrumSepolia + case 'base-sepolia': + return customChains.baseSepolia + case 'custom-localhost': return customChains.localL1Network diff --git a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts index d68e0a1719..bc2055ef64 100644 --- a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts +++ b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts @@ -104,6 +104,25 @@ export function getBridgeUiConfigForChain(chainId: number): BridgeUiConfig { 'AnyTrust protocol. Low fees for high-volume transactions. Secured by a trust-minimized Data Availability Committee (DAC).' } } + case ChainId.Base: + return { + color: '#0052ff', + network: { + name: 'Base', + logo: '/images/BaseWhite.svg', + description: + 'Base is built as an Ethereum L2, decentralized with the Optimism Superchain, and incubated by Coinbase.' + } + } + case ChainId.BaseSepolia: + return { + color: '#0052ff', + network: { + name: 'Base Sepolia', + logo: '/images/BaseWhite.svg', + description: 'Base Sepolia is an Ethereum L2 testnet by Coinbase.' + } + } default: { // added Orbit chains const orbitChain = orbitChains[chainId] diff --git a/packages/arb-token-bridge-ui/src/util/isDepositMode.ts b/packages/arb-token-bridge-ui/src/util/isDepositMode.ts index 86f49391ed..dd22cceb7c 100644 --- a/packages/arb-token-bridge-ui/src/util/isDepositMode.ts +++ b/packages/arb-token-bridge-ui/src/util/isDepositMode.ts @@ -9,13 +9,16 @@ export function isDepositMode({ }) { const { isEthereumMainnetOrTestnet: isSourceChainEthereum, - isArbitrum: isSourceChainArbitrum + isArbitrum: isSourceChainArbitrum, + isBase: isSourceChainBase } = isNetwork(sourceChainId) const { isOrbitChain: isDestinationChainOrbit } = isNetwork(destinationChainId) const isDepositMode = - isSourceChainEthereum || (isSourceChainArbitrum && isDestinationChainOrbit) + isSourceChainEthereum || + isSourceChainBase || + (isSourceChainArbitrum && isDestinationChainOrbit) return isDepositMode } diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index c8094f4e8c..2d947698b0 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -58,8 +58,29 @@ const l1Networks: { [chainId: number]: L1Network } = { } } +export type BaseNetwork = L1Network & { isBase: true } + +const baseNetworks: { [chainId: number]: BaseNetwork } = { + [ChainId.Base]: { + chainId: ChainId.Base, + blockTime: 2, + isTestnet: false, + isBase: true + }, + [ChainId.BaseSepolia]: { + chainId: ChainId.BaseSepolia, + blockTime: 2, + isTestnet: true, + isBase: true + } +} + export const getChains = () => { - const chains = [...Object.values(l1Networks), ...getArbitrumNetworks()] + const chains = [ + ...Object.values(l1Networks), + ...Object.values(baseNetworks), + ...getArbitrumNetworks() + ] return chains.filter(chain => { // exclude L1 chains with no child chains @@ -93,7 +114,7 @@ export function getBaseChainIdByChainId({ return chainId } - let currentParentChain: L1Network | ArbitrumNetwork + let currentParentChain: L1Network | ArbitrumNetwork | BaseNetwork try { currentParentChain = getArbitrumNetwork(chainId) @@ -101,6 +122,10 @@ export function getBaseChainIdByChainId({ return chainId } + if (isBaseChain(currentParentChain)) { + return currentParentChain.parentChainId + } + // keep following the parent chains until we find the L1 chain while (true) { if (isL1Chain(currentParentChain)) { @@ -189,7 +214,9 @@ export function removeCustomChainFromLocalStorage(chainId: number) { export const supportedCustomOrbitParentChains = [ ChainId.Sepolia, ChainId.Holesky, - ChainId.ArbitrumSepolia + ChainId.ArbitrumSepolia, + ChainId.BaseSepolia, + ChainId.Base ] export const rpcURLs: { [chainId: number]: string } = { @@ -248,14 +275,27 @@ export const getExplorerUrl = (chainId: ChainId) => { export const getL1BlockTime = (chainId: number) => { const chain = getChainByChainId(getBaseChainIdByChainId({ chainId })) - if (!chain || !isL1Chain(chain)) { + if (!chain || (!isL1Chain(chain) && !isBaseChain(chain))) { throw new Error(`Couldn't get block time. Unexpected chain ID: ${chainId}`) } + const { isBase } = isNetwork(chainId) + + if (isBase) { + // For Arbitrum L3s built on top of an OP Stack L2, `block.number` will return the L2 block number. + // L2 blocks in OP Stack chains are produced every 2 seconds + return 2 + } + return chain.blockTime } export const getConfirmPeriodBlocks = (chainId: ChainId) => { + // Base is not an Arbitrum chain so it doesn't work in the same way, and we don't support deposits from L1, or withdrawals from Base chains + if (isNetwork(chainId).isBase) { + return 0 + } + return getArbitrumNetwork(chainId).confirmPeriodBlocks } @@ -389,6 +429,11 @@ function isTestnetChain(chainId: ChainId) { return l1Network.isTestnet } + const baseNetwork = baseNetworks[chainId] + if (baseNetwork) { + return baseNetwork.isTestnet + } + try { return getArbitrumNetwork(chainId).isTestnet } catch { @@ -494,6 +539,12 @@ function isArbitrumChain( return typeof (chain as ArbitrumNetwork).parentChainId !== 'undefined' } +function isBaseChain( + chain: L1Network | ArbitrumNetwork | BaseNetwork +): chain is BaseNetwork { + return (chain as BaseNetwork).isBase === true +} + export const TELEPORT_ALLOWLIST: { [id: number]: number[] } = { [ChainId.Ethereum]: [1380012617, 70700, 70701], // Rari, PopApex and PopBoss [ChainId.Sepolia]: [1918988905] // RARI Testnet diff --git a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json index 01673e0071..6cac6b87f1 100644 --- a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json +++ b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json @@ -779,6 +779,56 @@ "logoUrl": "/images/xrTokenLogo.png" } } + }, + { + "chainId": 631571, + "confirmPeriodBlocks": 900, + "ethBridge": { + "bridge": "0x133634FA8F372e59422744759a67796F01428BDD", + "inbox": "0x81Bf51dEC736adA7E256ed6C092CAe24D62a1ca7", + "outbox": "0x020e1cb41cF68999D988c20Ef40E2C58e1947db2", + "rollup": "0xAFcb6cF53AB01ac39577A592E141F614171c9371", + "sequencerInbox": "0x2453eb0d6F58C01Adb87505A4348fB5EEceB007D" + }, + "nativeToken": "0xe97f36a00058AA7DfC4E85d23532C3f70453a7aE", + "explorerUrl": "https://polter-testnet.explorer.alchemy.com", + "rpcUrl": "https://geist-polter.g.alchemy.com/public", + "isCustom": true, + "isTestnet": true, + "name": "Polter Testnet", + "slug": "polter-testnet", + "parentChainId": 84532, + "retryableLifetimeSeconds": 604800, + "tokenBridge": { + "parentCustomGateway": "0x24e1e6375f0f0Eecd38266357cADE57cA3A348F3", + "parentErc20Gateway": "0x9014E7244116b965F0D1059f80e2bD8169957117", + "parentGatewayRouter": "0xE38553a7989feD9e240DE8B0f5ed166BF75a088A", + "parentMultiCall": "0xE0753Df74d86D6B25aCd2d049389c7E52e2dd728", + "parentProxyAdmin": "0x0000000000000000000000000000000000000000", + "parentWeth": "0x0000000000000000000000000000000000000000", + "parentWethGateway": "0x0000000000000000000000000000000000000000", + "childCustomGateway": "0x7965162499751ABf89b8e3C640f8229AD8EeB022", + "childErc20Gateway": "0xA8E8b5D957e4ad9335E504442e877E513BD50729", + "childGatewayRouter": "0xF654086B1118fE98ea045De8D6dC0F1C53Da5B76", + "childMultiCall": "0xb97c5bC7DB7532471726550480A855484a408d00", + "childProxyAdmin": "0xda11A4ecaAcA51b1f2e2109a2EEFaC438409b68D", + "childWeth": "0x0000000000000000000000000000000000000000", + "childWethGateway": "0x0000000000000000000000000000000000000000" + }, + "bridgeUiConfig": { + "color": "#03AB2A", + "network": { + "name": "Polter Testnet", + "logo": "/images/PolterTestnetLogo.png", + "description": "A gaming testnet for Aavegotchi's Geist Mainnet." + }, + "nativeTokenData": { + "name": "Aavegotchi GHST Token", + "symbol": "GHST", + "decimals": 18, + "logoUrl": "/images/ghst.png" + } + } } ] } diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts index 0023574b53..8f4ae1d634 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts @@ -11,7 +11,9 @@ import { localL1Network as local, localL2Network as arbitrumLocal, localL3Network as l3Local, - holesky + holesky, + base, + baseSepolia } from './wagmiAdditionalNetworks' import { isTestingEnvironment } from '../CommonUtils' import { getCustomChainsFromLocalStorage, ChainId } from '../networks' @@ -32,9 +34,11 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, + base, // sepolia & arb sepolia are for tx history panel tests sepolia, arbitrumSepolia, + baseSepolia, holesky, // Orbit chains ...wagmiOrbitChains, @@ -49,8 +53,10 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, + base, sepolia, arbitrumSepolia, + baseSepolia, holesky, ...wagmiOrbitChains, ...customChains @@ -71,8 +77,10 @@ enum TargetChainKey { Ethereum = 'mainnet', ArbitrumOne = 'arbitrum-one', ArbitrumNova = 'arbitrum-nova', + Base = 'base', Sepolia = 'sepolia', - ArbitrumSepolia = 'arbitrum-sepolia' + ArbitrumSepolia = 'arbitrum-sepolia', + BaseSepolia = 'base-sepolia' } function sanitizeTargetChainKey(targetChainKey: string | null): TargetChainKey { @@ -100,11 +108,17 @@ function getChainId(targetChainKey: TargetChainKey): number { case TargetChainKey.ArbitrumNova: return ChainId.ArbitrumNova + case TargetChainKey.Base: + return ChainId.Base + case TargetChainKey.Sepolia: return ChainId.Sepolia case TargetChainKey.ArbitrumSepolia: return ChainId.ArbitrumSepolia + + case TargetChainKey.BaseSepolia: + return ChainId.BaseSepolia } } From a08344f8a56fd1fd21e6493ee98b55cd37dfb5ec Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:13:26 +0100 Subject: [PATCH 03/19] make withdrawal work --- .../src/components/TransferPanel/TokenButton.tsx | 2 +- packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx index 942fc555d4..eaa43c8007 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenButton.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo } from 'react' +import { useMemo } from 'react' import { Popover } from '@headlessui/react' import { ChevronDownIcon } from '@heroicons/react/24/outline' import { twMerge } from 'tailwind-merge' diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts index c256eb62c4..54e7483bbf 100644 --- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts +++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts @@ -37,12 +37,15 @@ export const getBridgeTransferProperties = ( const isSourceChainOrbit = isNetwork(sourceChainId).isOrbitChain + const { isBase: isDestinationChainBase } = isNetwork(destinationChainId) + const isDeposit = isDepositMode({ sourceChainId, destinationChainId }) const isWithdrawal = (isSourceChainArbitrum && isDestinationChainEthereumMainnetOrTestnet) || // l2 arbitrum chains to l1 (isSourceChainOrbit && isDestinationChainEthereumMainnetOrTestnet) || // l2 orbit chains to l1 - (isSourceChainOrbit && isDestinationChainArbitrum) // l3 orbit chains to l1 + (isSourceChainOrbit && isDestinationChainArbitrum) || // l3 orbit chains to l1 + (isSourceChainOrbit && isDestinationChainBase) // l3 orbit chain to Base l2 const isTeleport = isValidTeleportChainPair({ sourceChainId, From 1e98126288df510083ff8eb8818e3ea8730422f7 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:29:43 +0100 Subject: [PATCH 04/19] hide base --- .../arb-token-bridge-ui/src/hooks/useNetworks.ts | 3 ++- .../src/types/ChainQueryParam.ts | 13 ++++++++----- packages/arb-token-bridge-ui/src/util/networks.ts | 4 ++-- .../src/util/wagmi/getWagmiChain.ts | 5 +++-- .../arb-token-bridge-ui/src/util/wagmi/setup.ts | 5 +++-- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts index 7a3809422a..c05da2902b 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts @@ -39,7 +39,8 @@ export function isSupportedChainId( holesky.id, arbitrum.id, arbitrumNova.id, - base.id, + // Enable when there are Orbit Chains on Base + // base.id, arbitrumSepolia.id, baseSepolia.id, arbitrumLocal.id, diff --git a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts index e47e93ec97..b55d3feeb8 100644 --- a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts +++ b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts @@ -15,7 +15,8 @@ const chainQueryParams = [ 'sepolia', 'arbitrum-one', 'arbitrum-nova', - 'base', + // Enable when there are Orbit Chains on Base + // 'base', 'arbitrum-sepolia', 'base-sepolia', 'custom-localhost', @@ -52,8 +53,9 @@ export function getChainQueryParamForChain(chainId: ChainId): ChainQueryParam { case ChainId.ArbitrumNova: return 'arbitrum-nova' - case ChainId.Base: - return 'base' + // Enable when there are Orbit Chains on Base + // case ChainId.Base: + // return 'base' case ChainId.Sepolia: return 'sepolia' @@ -108,8 +110,9 @@ export function getChainForChainKeyQueryParam( case 'arbitrum-nova': return customChains.arbitrumNova - case 'base': - return customChains.base + // Enable when there are Orbit Chains on Base + // case 'base': + // return customChains.base case 'arbitrum-sepolia': return customChains.arbitrumSepolia diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index 2d947698b0..c3e3d3920f 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -76,9 +76,9 @@ const baseNetworks: { [chainId: number]: BaseNetwork } = { } export const getChains = () => { - const chains = [ + const chains: (L1Network | ArbitrumNetwork | BaseNetwork)[] = [ ...Object.values(l1Networks), - ...Object.values(baseNetworks), + baseNetworks[ChainId.BaseSepolia] as BaseNetwork, ...getArbitrumNetworks() ] diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts index 66de1b1b0f..3ed18ae2af 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts @@ -39,8 +39,9 @@ export function getWagmiChain(chainId: number): Chain { case ChainId.ArbitrumNova: return arbitrumNova - case ChainId.Base: - return base + // Enable when there are Orbit Chains on Base + // case ChainId.Base: + // return base // Testnets case ChainId.Sepolia: diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts index 8f4ae1d634..359d0c5a56 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts @@ -108,8 +108,9 @@ function getChainId(targetChainKey: TargetChainKey): number { case TargetChainKey.ArbitrumNova: return ChainId.ArbitrumNova - case TargetChainKey.Base: - return ChainId.Base + // Enable when there are Orbit Chains on Base + // case TargetChainKey.Base: + // return ChainId.Base case TargetChainKey.Sepolia: return ChainId.Sepolia From d8b9b92c944522b27dd9bd75e717b06f974244f8 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:36:23 +0100 Subject: [PATCH 05/19] hide base --- packages/arb-token-bridge-ui/src/util/wagmi/setup.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts index 359d0c5a56..10c5d564b0 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts @@ -34,7 +34,8 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, - base, + // Enable when there are Orbit Chains on Base + // base, // sepolia & arb sepolia are for tx history panel tests sepolia, arbitrumSepolia, @@ -53,7 +54,8 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, - base, + // Enable when there are Orbit Chains on Base + // base, sepolia, arbitrumSepolia, baseSepolia, @@ -77,7 +79,8 @@ enum TargetChainKey { Ethereum = 'mainnet', ArbitrumOne = 'arbitrum-one', ArbitrumNova = 'arbitrum-nova', - Base = 'base', + // Enable when there are Orbit Chains on Base + // Base = 'base', Sepolia = 'sepolia', ArbitrumSepolia = 'arbitrum-sepolia', BaseSepolia = 'base-sepolia' From dc63d92d6dce5f6d765937c99cb54c54bc4a4989 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:44:57 +0100 Subject: [PATCH 06/19] fix --- packages/scripts/src/addOrbitChain/schemas.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/scripts/src/addOrbitChain/schemas.ts b/packages/scripts/src/addOrbitChain/schemas.ts index fb4441652b..175ff35fb0 100644 --- a/packages/scripts/src/addOrbitChain/schemas.ts +++ b/packages/scripts/src/addOrbitChain/schemas.ts @@ -135,7 +135,7 @@ export const chainSchema = z chainId: 8453, name: "Base", }; - case 8453: // Base + case 84532: // Base Sepolia return { rpcUrl: "https://sepolia.base.org", blockExplorer: "https://sepolia.basescan.io", From a7720e90ef0abb280dff781d777812eea7f4ef62 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 11:42:10 +0100 Subject: [PATCH 07/19] add networks test for base sepolia and base --- .../src/util/__tests__/networks.test.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) 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 554663bf91..4c79cbbf28 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 @@ -52,6 +52,15 @@ beforeAll(() => { }) registerCustomArbitrumNetwork(xaiTestnet) + + const polterTestnetChainId = 631571 + const polterTestnet = orbitTestnets[polterTestnetChainId] + + if (!polterTestnet) { + throw new Error(`Could not find Xai Testnet in the Orbit chains list.`) + } + + registerCustomArbitrumNetwork(polterTestnet) }) describe('getBaseChainIdByChainId', () => { @@ -254,4 +263,20 @@ describe('getDestinationChainIds', () => { expect(defaultChainId).toBe(ChainId.Sepolia) expect(isAscending(nonDefaultChainIds)).toBe(true) }) + + it('should return a sorted list for Base Sepolia', () => { + const destinationChainIds = getDestinationChainIds(ChainId.BaseSepolia) + const defaultChainId = destinationChainIds[0] + const nonDefaultChainIds = destinationChainIds.slice(1) + + expect(defaultChainId).toBe(631571) + expect(isAscending(nonDefaultChainIds)).toBe(true) + }) + + // Enable when there are Orbit Chains on Base + it('should not return a list for Base', () => { + const destinationChainIds = getDestinationChainIds(ChainId.Base) + + expect(destinationChainIds).toHaveLength(0) + }) }) From 6e4a3af3e73258dd77b480cb671cd38b2d6d0c3b Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:34:53 +0100 Subject: [PATCH 08/19] enable Base but without query param slug --- .../arb-token-bridge-ui/src/hooks/useNetworks.ts | 3 +-- packages/arb-token-bridge-ui/src/util/networks.ts | 9 ++++++--- .../src/util/wagmi/getWagmiChain.ts | 5 ++--- .../arb-token-bridge-ui/src/util/wagmi/setup.ts | 14 +++++--------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts index c05da2902b..7a3809422a 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts @@ -39,8 +39,7 @@ export function isSupportedChainId( holesky.id, arbitrum.id, arbitrumNova.id, - // Enable when there are Orbit Chains on Base - // base.id, + base.id, arbitrumSepolia.id, baseSepolia.id, arbitrumLocal.id, diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index c3e3d3920f..8ae9fe5a5b 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -78,13 +78,16 @@ const baseNetworks: { [chainId: number]: BaseNetwork } = { export const getChains = () => { const chains: (L1Network | ArbitrumNetwork | BaseNetwork)[] = [ ...Object.values(l1Networks), - baseNetworks[ChainId.BaseSepolia] as BaseNetwork, + ...Object.values(baseNetworks), ...getArbitrumNetworks() ] return chains.filter(chain => { - // exclude L1 chains with no child chains - if (isL1Chain(chain) && getChildrenForNetwork(chain.chainId).length === 0) { + // exclude L1 chains or Base Chains with no child chains + if ( + !('parentChainId' in chain) && + getChildrenForNetwork(chain.chainId).length === 0 + ) { return false } diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts index 3ed18ae2af..66de1b1b0f 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts @@ -39,9 +39,8 @@ export function getWagmiChain(chainId: number): Chain { case ChainId.ArbitrumNova: return arbitrumNova - // Enable when there are Orbit Chains on Base - // case ChainId.Base: - // return base + case ChainId.Base: + return base // Testnets case ChainId.Sepolia: diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts index 10c5d564b0..8f4ae1d634 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts @@ -34,8 +34,7 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, - // Enable when there are Orbit Chains on Base - // base, + base, // sepolia & arb sepolia are for tx history panel tests sepolia, arbitrumSepolia, @@ -54,8 +53,7 @@ const chainList = isTestingEnvironment mainnet, arbitrum, arbitrumNova, - // Enable when there are Orbit Chains on Base - // base, + base, sepolia, arbitrumSepolia, baseSepolia, @@ -79,8 +77,7 @@ enum TargetChainKey { Ethereum = 'mainnet', ArbitrumOne = 'arbitrum-one', ArbitrumNova = 'arbitrum-nova', - // Enable when there are Orbit Chains on Base - // Base = 'base', + Base = 'base', Sepolia = 'sepolia', ArbitrumSepolia = 'arbitrum-sepolia', BaseSepolia = 'base-sepolia' @@ -111,9 +108,8 @@ function getChainId(targetChainKey: TargetChainKey): number { case TargetChainKey.ArbitrumNova: return ChainId.ArbitrumNova - // Enable when there are Orbit Chains on Base - // case TargetChainKey.Base: - // return ChainId.Base + case TargetChainKey.Base: + return ChainId.Base case TargetChainKey.Sepolia: return ChainId.Sepolia From 9b25da4e4b30751c86723ca650d6172fa21de64e Mon Sep 17 00:00:00 2001 From: Fionna Chan <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:36:19 +0100 Subject: [PATCH 09/19] typo Co-authored-by: Bartek --- .../arb-token-bridge-ui/src/util/__tests__/networks.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4c79cbbf28..2dbeb6f3cb 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 @@ -57,7 +57,7 @@ beforeAll(() => { const polterTestnet = orbitTestnets[polterTestnetChainId] if (!polterTestnet) { - throw new Error(`Could not find Xai Testnet in the Orbit chains list.`) + throw new Error(`Could not find Polter Testnet in the Orbit chains list.`) } registerCustomArbitrumNetwork(polterTestnet) From 00e73da51bb2320b7f68f9c838297d9e2e828639 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:49:07 +0100 Subject: [PATCH 10/19] support base --- .../src/hooks/useNetworks.ts | 20 +++++++++++++++++-- .../src/types/ChainQueryParam.ts | 13 +++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts index 7a3809422a..b141f2d144 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts @@ -78,7 +78,15 @@ export function sanitizeQueryParams({ isSupportedChainId(destinationChainId) ) { const [defaultSourceChainId] = getDestinationChainIds(destinationChainId) - return { sourceChainId: defaultSourceChainId!, destinationChainId } + + if (typeof defaultSourceChainId === 'undefined') { + return { + sourceChainId: ChainId.Ethereum, + destinationChainId: ChainId.ArbitrumOne + } + } + + return { sourceChainId: defaultSourceChainId, destinationChainId } } // sourceChainId is valid and destinationChainId is undefined @@ -87,9 +95,17 @@ export function sanitizeQueryParams({ !isSupportedChainId(destinationChainId) ) { const [defaultDestinationChainId] = getDestinationChainIds(sourceChainId) + + if (typeof defaultDestinationChainId === 'undefined') { + return { + sourceChainId: ChainId.Ethereum, + destinationChainId: ChainId.ArbitrumOne + } + } + return { sourceChainId: sourceChainId, - destinationChainId: defaultDestinationChainId! + destinationChainId: defaultDestinationChainId } } diff --git a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts index b55d3feeb8..e47e93ec97 100644 --- a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts +++ b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts @@ -15,8 +15,7 @@ const chainQueryParams = [ 'sepolia', 'arbitrum-one', 'arbitrum-nova', - // Enable when there are Orbit Chains on Base - // 'base', + 'base', 'arbitrum-sepolia', 'base-sepolia', 'custom-localhost', @@ -53,9 +52,8 @@ export function getChainQueryParamForChain(chainId: ChainId): ChainQueryParam { case ChainId.ArbitrumNova: return 'arbitrum-nova' - // Enable when there are Orbit Chains on Base - // case ChainId.Base: - // return 'base' + case ChainId.Base: + return 'base' case ChainId.Sepolia: return 'sepolia' @@ -110,9 +108,8 @@ export function getChainForChainKeyQueryParam( case 'arbitrum-nova': return customChains.arbitrumNova - // Enable when there are Orbit Chains on Base - // case 'base': - // return customChains.base + case 'base': + return customChains.base case 'arbitrum-sepolia': return customChains.arbitrumSepolia From 98ed213cf4b8c5f2ef59fd559835f627d7d95d60 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:19:07 +0100 Subject: [PATCH 11/19] update --- .../arb-token-bridge-ui/src/util/networks.ts | 46 ++++++------------- .../src/util/orbitChainsData.json | 2 +- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index 8ae9fe5a5b..aa977e8cfe 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -112,8 +112,8 @@ export function getBaseChainIdByChainId({ }: { chainId: number }): number { - // the chain provided is an L1 chain, so we can return early - if (isL1Chain({ chainId })) { + // the chain provided is an L1 chain or Base chain, so we can return early + if (isNonArbParentChain({ chainId })) { return chainId } @@ -125,13 +125,9 @@ export function getBaseChainIdByChainId({ return chainId } - if (isBaseChain(currentParentChain)) { - return currentParentChain.parentChainId - } - - // keep following the parent chains until we find the L1 chain + // keep following the parent chains until we find the L1/Base chain while (true) { - if (isL1Chain(currentParentChain)) { + if (isNonArbParentChain(currentParentChain)) { return currentParentChain.chainId } @@ -278,18 +274,10 @@ export const getExplorerUrl = (chainId: ChainId) => { export const getL1BlockTime = (chainId: number) => { const chain = getChainByChainId(getBaseChainIdByChainId({ chainId })) - if (!chain || (!isL1Chain(chain) && !isBaseChain(chain))) { + if (!chain || !('blockTime' in chain)) { throw new Error(`Couldn't get block time. Unexpected chain ID: ${chainId}`) } - const { isBase } = isNetwork(chainId) - - if (isBase) { - // For Arbitrum L3s built on top of an OP Stack L2, `block.number` will return the L2 block number. - // L2 blocks in OP Stack chains are produced every 2 seconds - return 2 - } - return chain.blockTime } @@ -532,20 +520,13 @@ export function mapCustomChainToNetworkData(chain: ChainWithRpcUrl) { explorerUrls[chain.chainId] = chain.explorerUrl } -function isL1Chain(chain: { chainId: number }): chain is L1Network { - return typeof l1Networks[chain.chainId] !== 'undefined' -} - -function isArbitrumChain( - chain: L1Network | ArbitrumNetwork -): chain is ArbitrumNetwork { - return typeof (chain as ArbitrumNetwork).parentChainId !== 'undefined' -} - -function isBaseChain( - chain: L1Network | ArbitrumNetwork | BaseNetwork -): chain is BaseNetwork { - return (chain as BaseNetwork).isBase === true +function isNonArbParentChain(chain: { + chainId: number +}): chain is L1Network | BaseNetwork { + return ( + typeof l1Networks[chain.chainId] !== 'undefined' || + typeof baseNetworks[chain.chainId] !== 'undefined' + ) } export const TELEPORT_ALLOWLIST: { [id: number]: number[] } = { @@ -593,7 +574,8 @@ export function getDestinationChainIds(chainId: ChainId): ChainId[] { return [] } - const parentChainId = isArbitrumChain(chain) ? chain.parentChainId : undefined + const parentChainId = + 'parentChainId' in chain ? chain.parentChainId : undefined const validDestinationChainIds = getChildChainIds(chain) diff --git a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json index 6cac6b87f1..6cbb4622a1 100644 --- a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json +++ b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json @@ -820,7 +820,7 @@ "network": { "name": "Polter Testnet", "logo": "/images/PolterTestnetLogo.png", - "description": "A gaming testnet for Aavegotchi's Geist Mainnet." + "description": "A gaming testnet for Aavegotchi's Geist Mainnet." }, "nativeTokenData": { "name": "Aavegotchi GHST Token", From c48ae9a877ad82c47eae2d30c4b472d2285f7264 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:33:29 +0100 Subject: [PATCH 12/19] update --- .../src/util/wagmi/setup.ts | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts index 8f4ae1d634..fac6d8c971 100644 --- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts +++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts @@ -28,18 +28,22 @@ const wagmiOrbitChains = getOrbitChains().map(chain => getWagmiChain(chain.chainId) ) +const defaultChains = [ + // mainnet, arb1, & arb nova are for network switch tests + mainnet, + arbitrum, + arbitrumNova, + base, + // sepolia & arb sepolia are for tx history panel tests + sepolia, + arbitrumSepolia, + baseSepolia, + holesky +] + const chainList = isTestingEnvironment ? [ - // mainnet, arb1, & arb nova are for network switch tests - mainnet, - arbitrum, - arbitrumNova, - base, - // sepolia & arb sepolia are for tx history panel tests - sepolia, - arbitrumSepolia, - baseSepolia, - holesky, + ...defaultChains, // Orbit chains ...wagmiOrbitChains, // add local environments during testing @@ -49,18 +53,7 @@ const chainList = isTestingEnvironment // user-added custom chains ...customChains ] - : [ - mainnet, - arbitrum, - arbitrumNova, - base, - sepolia, - arbitrumSepolia, - baseSepolia, - holesky, - ...wagmiOrbitChains, - ...customChains - ] + : [...defaultChains, ...wagmiOrbitChains, ...customChains] const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID! From 7b6c89dabe66ce3075ef02ac5ed15b760f915816 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:50:15 +0100 Subject: [PATCH 13/19] update type --- .../arb-token-bridge-ui/src/util/networks.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index aa977e8cfe..bca7f5573f 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -29,13 +29,13 @@ export enum ChainId { L3Local = 333333 } -type L1Network = { +type NonArbParentNetwork = { chainId: ChainId blockTime: number isTestnet: boolean } -const l1Networks: { [chainId: number]: L1Network } = { +const l1Networks: { [chainId: number]: NonArbParentNetwork } = { [ChainId.Ethereum]: { chainId: ChainId.Ethereum, blockTime: 12, @@ -58,25 +58,21 @@ const l1Networks: { [chainId: number]: L1Network } = { } } -export type BaseNetwork = L1Network & { isBase: true } - -const baseNetworks: { [chainId: number]: BaseNetwork } = { +const baseNetworks: { [chainId: number]: NonArbParentNetwork } = { [ChainId.Base]: { chainId: ChainId.Base, blockTime: 2, - isTestnet: false, - isBase: true + isTestnet: false }, [ChainId.BaseSepolia]: { chainId: ChainId.BaseSepolia, blockTime: 2, - isTestnet: true, - isBase: true + isTestnet: true } } export const getChains = () => { - const chains: (L1Network | ArbitrumNetwork | BaseNetwork)[] = [ + const chains: (NonArbParentNetwork | ArbitrumNetwork)[] = [ ...Object.values(l1Networks), ...Object.values(baseNetworks), ...getArbitrumNetworks() @@ -522,7 +518,7 @@ export function mapCustomChainToNetworkData(chain: ChainWithRpcUrl) { function isNonArbParentChain(chain: { chainId: number -}): chain is L1Network | BaseNetwork { +}): chain is NonArbParentNetwork { return ( typeof l1Networks[chain.chainId] !== 'undefined' || typeof baseNetworks[chain.chainId] !== 'undefined' From 2eda65c8ea0d987cb483dabebae2e221bd8ab5d5 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:57:27 +0100 Subject: [PATCH 14/19] update --- packages/arb-token-bridge-ui/src/util/networks.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index bca7f5573f..a1de8b502c 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -113,7 +113,7 @@ export function getBaseChainIdByChainId({ return chainId } - let currentParentChain: L1Network | ArbitrumNetwork | BaseNetwork + let currentParentChain: NonArbParentNetwork | ArbitrumNetwork try { currentParentChain = getArbitrumNetwork(chainId) @@ -308,7 +308,7 @@ export const l2MoonGatewayAddresses: { [chainId: number]: string } = { [ChainId.ArbitrumNova]: '0xA430a792c14d3E49d9D00FD7B4BA343F516fbB81' } -const defaultL1Network: L1Network = { +const defaultL1Network: NonArbParentNetwork = { blockTime: 10, chainId: 1337, isTestnet: true @@ -530,7 +530,7 @@ export const TELEPORT_ALLOWLIST: { [id: number]: number[] } = { [ChainId.Sepolia]: [1918988905] // RARI Testnet } -export function getChildChainIds(chain: ArbitrumNetwork | L1Network) { +export function getChildChainIds(chain: ArbitrumNetwork | NonArbParentNetwork) { const childChainIds = [ ...getChildrenForNetwork(chain.chainId).map(chain => chain.chainId), ...(TELEPORT_ALLOWLIST[chain.chainId] ?? []) // for considering teleport (L1-L3 transfers) we will get the L3 children of the chain, if present From 7786875d82ecf83c010acdec73b6aebbe2d2344d Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:11:07 +0100 Subject: [PATCH 15/19] update desc --- packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts index bc2055ef64..d7d4461918 100644 --- a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts +++ b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts @@ -111,7 +111,7 @@ export function getBridgeUiConfigForChain(chainId: number): BridgeUiConfig { name: 'Base', logo: '/images/BaseWhite.svg', description: - 'Base is built as an Ethereum L2, decentralized with the Optimism Superchain, and incubated by Coinbase.' + 'Base is an Optimistic Rollup built by Coinbase with the OP Stack.' } } case ChainId.BaseSepolia: From 199a74635c57ea6ca9c1f22de115e4899ab45429 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:06:14 +0100 Subject: [PATCH 16/19] other chains --- .../common/NetworkSelectionContainer.tsx | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx index 95994fa261..6e11fe4d39 100644 --- a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx +++ b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx @@ -32,10 +32,11 @@ import { useActions } from '../../state' import { useChainIdsForNetworkSelection } from '../../hooks/TransferPanel/useChainIdsForNetworkSelection' import { useAccountType } from '../../hooks/useAccountType' -type NetworkType = 'core' | 'orbit' +type NetworkType = 'core' | 'other' | 'orbit' enum ChainGroupName { core = 'CORE CHAINS', + other = 'OTHER CHAINS', orbit = 'ORBIT CHAINS' } @@ -48,6 +49,19 @@ const chainGroupInfo: { [key in NetworkType]: ChainGroupInfo } = { core: { name: ChainGroupName.core }, + other: { + name: ChainGroupName.other, + description: ( +

+ + + Independent projects using non-Arbitrum technology. These chains have + varying degrees of decentralization.{' '} + Bridge at your own risk. + +

+ ) + }, orbit: { name: ChainGroupName.orbit, description: ( @@ -71,7 +85,7 @@ function ChainTypeInfoRow({ style: CSSProperties }) { const { name, description } = chainGroup - const isCoreGroup = chainGroup.name === ChainGroupName.core + const isOrbitGroup = chainGroup.name === ChainGroupName.orbit return (
@@ -236,14 +250,16 @@ function NetworksPanel({ } const coreNetworks = chainIds.filter( - chainId => !isNetwork(chainId).isOrbitChain + chainId => isNetwork(chainId).isCoreChain ) + const otherNetworks = chainIds.filter(chainId => isNetwork(chainId).isBase) const orbitNetworks = chainIds.filter( chainId => isNetwork(chainId).isOrbitChain ) return { core: coreNetworks, + other: otherNetworks, orbit: orbitNetworks } }, [debouncedNetworkSearched, chainIds]) @@ -262,6 +278,10 @@ function NetworksPanel({ groupedNetworks.push(ChainGroupName.core, ...networksToShow.core) } + if (networksToShow.other.length > 0) { + groupedNetworks.push(ChainGroupName.other, ...networksToShow.other) + } + if (networksToShow.orbit.length > 0) { groupedNetworks.push(ChainGroupName.orbit, ...networksToShow.orbit) } @@ -302,6 +322,12 @@ function NetworksPanel({ ) } + if (networkOrChainTypeName === ChainGroupName.other) { + return ( + + ) + } + if (networkOrChainTypeName === ChainGroupName.orbit) { return ( From bc449afe05651dea3ee1b68ff1809a6e16e55e50 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:33:54 +0100 Subject: [PATCH 17/19] update --- .../src/components/common/NetworkSelectionContainer.tsx | 5 ++++- packages/arb-token-bridge-ui/src/util/networks.ts | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx index 6e11fe4d39..522a69e6cb 100644 --- a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx +++ b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx @@ -252,7 +252,10 @@ function NetworksPanel({ const coreNetworks = chainIds.filter( chainId => isNetwork(chainId).isCoreChain ) - const otherNetworks = chainIds.filter(chainId => isNetwork(chainId).isBase) + const otherNetworks = chainIds.filter( + chainId => + !isNetwork(chainId).isCoreChain && !isNetwork(chainId).isOrbitChain + ) const orbitNetworks = chainIds.filter( chainId => isNetwork(chainId).isOrbitChain ) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index faa46ed6e2..c177be40c8 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -81,7 +81,7 @@ export const getChains = () => { return chains.filter(chain => { // exclude L1 chains or Base Chains with no child chains if ( - !('parentChainId' in chain) && + isNonArbParentChain(chain) && getChildrenForNetwork(chain.chainId).length === 0 ) { return false @@ -206,12 +206,12 @@ export function removeCustomChainFromLocalStorage(chainId: number) { ) } +// Only support testnet chains export const supportedCustomOrbitParentChains = [ ChainId.Sepolia, ChainId.Holesky, ChainId.ArbitrumSepolia, - ChainId.BaseSepolia, - ChainId.Base + ChainId.BaseSepolia ] export const rpcURLs: { [chainId: number]: string } = { @@ -270,7 +270,7 @@ export const getExplorerUrl = (chainId: ChainId) => { export const getL1BlockTime = (chainId: number) => { const chain = getChainByChainId(getBaseChainIdByChainId({ chainId })) - if (!chain || !('blockTime' in chain)) { + if (!chain || !isNonArbParentChain(chain)) { throw new Error(`Couldn't get block time. Unexpected chain ID: ${chainId}`) } From f72375c1cd97bd94901217a72e58a0dd58c6dd53 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:42:41 +0100 Subject: [PATCH 18/19] revive --- packages/arb-token-bridge-ui/src/util/networks.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index c177be40c8..35b446f26e 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -524,6 +524,12 @@ export function mapCustomChainToNetworkData(chain: ChainWithRpcUrl) { explorerUrls[chain.chainId] = chain.explorerUrl } +function isArbitrumChain( + chain: NonArbParentNetwork | ArbitrumNetwork +): chain is ArbitrumNetwork { + return typeof (chain as ArbitrumNetwork).parentChainId !== 'undefined' +} + function isNonArbParentChain(chain: { chainId: number }): chain is NonArbParentNetwork { @@ -578,8 +584,7 @@ export function getDestinationChainIds(chainId: ChainId): ChainId[] { return [] } - const parentChainId = - 'parentChainId' in chain ? chain.parentChainId : undefined + const parentChainId = isArbitrumChain(chain) ? chain.parentChainId : undefined const validDestinationChainIds = getChildChainIds(chain) From 9998d33cea91471702b67d27aeb80a00a2f69f62 Mon Sep 17 00:00:00 2001 From: Fionna <13184582+fionnachan@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:00:01 +0100 Subject: [PATCH 19/19] rename --- .../arb-token-bridge-ui/src/util/networks.ts | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts index 35b446f26e..5dc8e5627c 100644 --- a/packages/arb-token-bridge-ui/src/util/networks.ts +++ b/packages/arb-token-bridge-ui/src/util/networks.ts @@ -29,13 +29,14 @@ export enum ChainId { L3Local = 333333 } -type NonArbParentNetwork = { +/** The network that you reference when calling `block.number` in solidity */ +type BlockNumberReferenceNetwork = { chainId: ChainId blockTime: number isTestnet: boolean } -const l1Networks: { [chainId: number]: NonArbParentNetwork } = { +const l1Networks: { [chainId: number]: BlockNumberReferenceNetwork } = { [ChainId.Ethereum]: { chainId: ChainId.Ethereum, blockTime: 12, @@ -58,7 +59,7 @@ const l1Networks: { [chainId: number]: NonArbParentNetwork } = { } } -const baseNetworks: { [chainId: number]: NonArbParentNetwork } = { +const baseNetworks: { [chainId: number]: BlockNumberReferenceNetwork } = { [ChainId.Base]: { chainId: ChainId.Base, blockTime: 2, @@ -72,7 +73,7 @@ const baseNetworks: { [chainId: number]: NonArbParentNetwork } = { } export const getChains = () => { - const chains: (NonArbParentNetwork | ArbitrumNetwork)[] = [ + const chains: (BlockNumberReferenceNetwork | ArbitrumNetwork)[] = [ ...Object.values(l1Networks), ...Object.values(baseNetworks), ...getArbitrumNetworks() @@ -81,7 +82,7 @@ export const getChains = () => { return chains.filter(chain => { // exclude L1 chains or Base Chains with no child chains if ( - isNonArbParentChain(chain) && + isBlockNumberReferenceNetwork(chain) && getChildrenForNetwork(chain.chainId).length === 0 ) { return false @@ -109,11 +110,11 @@ export function getBaseChainIdByChainId({ chainId: number }): number { // the chain provided is an L1 chain or Base chain, so we can return early - if (isNonArbParentChain({ chainId })) { + if (isBlockNumberReferenceNetwork({ chainId })) { return chainId } - let currentParentChain: NonArbParentNetwork | ArbitrumNetwork + let currentParentChain: BlockNumberReferenceNetwork | ArbitrumNetwork try { currentParentChain = getArbitrumNetwork(chainId) @@ -123,7 +124,7 @@ export function getBaseChainIdByChainId({ // keep following the parent chains until we find the L1/Base chain while (true) { - if (isNonArbParentChain(currentParentChain)) { + if (isBlockNumberReferenceNetwork(currentParentChain)) { return currentParentChain.chainId } @@ -270,7 +271,7 @@ export const getExplorerUrl = (chainId: ChainId) => { export const getL1BlockTime = (chainId: number) => { const chain = getChainByChainId(getBaseChainIdByChainId({ chainId })) - if (!chain || !isNonArbParentChain(chain)) { + if (!chain || !isBlockNumberReferenceNetwork(chain)) { throw new Error(`Couldn't get block time. Unexpected chain ID: ${chainId}`) } @@ -308,7 +309,7 @@ export const l2MoonGatewayAddresses: { [chainId: number]: string } = { [ChainId.ArbitrumNova]: '0xA430a792c14d3E49d9D00FD7B4BA343F516fbB81' } -const defaultL1Network: NonArbParentNetwork = { +const defaultL1Network: BlockNumberReferenceNetwork = { blockTime: 10, chainId: 1337, isTestnet: true @@ -525,14 +526,14 @@ export function mapCustomChainToNetworkData(chain: ChainWithRpcUrl) { } function isArbitrumChain( - chain: NonArbParentNetwork | ArbitrumNetwork + chain: BlockNumberReferenceNetwork | ArbitrumNetwork ): chain is ArbitrumNetwork { return typeof (chain as ArbitrumNetwork).parentChainId !== 'undefined' } -function isNonArbParentChain(chain: { +function isBlockNumberReferenceNetwork(chain: { chainId: number -}): chain is NonArbParentNetwork { +}): chain is BlockNumberReferenceNetwork { return ( typeof l1Networks[chain.chainId] !== 'undefined' || typeof baseNetworks[chain.chainId] !== 'undefined' @@ -544,7 +545,9 @@ export const TELEPORT_ALLOWLIST: { [id: number]: number[] } = { [ChainId.Sepolia]: [1918988905] // RARI Testnet } -export function getChildChainIds(chain: ArbitrumNetwork | NonArbParentNetwork) { +export function getChildChainIds( + chain: ArbitrumNetwork | BlockNumberReferenceNetwork +) { const childChainIds = [ ...getChildrenForNetwork(chain.chainId).map(chain => chain.chainId), ...(TELEPORT_ALLOWLIST[chain.chainId] ?? []) // for considering teleport (L1-L3 transfers) we will get the L3 children of the chain, if present