", "Path to the orbitChainsData.json file")
28 | .action((file: string) => {
29 | try {
30 | const data = fs.readFileSync(file, "utf8");
31 | const orbitChainsList = JSON.parse(data);
32 | validateOrbitChainsList(orbitChainsList).catch((error) => {
33 | console.error(`Error in validateOrbitChainsList: ${error}`);
34 | process.exit(1);
35 | });
36 | } catch (error) {
37 | console.error("Error reading or parsing file:", error);
38 | process.exit(1);
39 | }
40 | });
41 |
42 | // Add more commands here as needed, for example:
43 | // program
44 | // .command('some-other-script')
45 | // .description('Description of the other script')
46 | // .action(() => {
47 | // // Call the function for the other script
48 | // });
49 |
50 | program.parse(process.argv);
51 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Cache build artifacts
2 |
3 | on:
4 | workflow_call:
5 |
6 | env:
7 | NEXT_PUBLIC_INFURA_KEY: ${{ secrets.NEXT_PUBLIC_INFURA_KEY }}
8 | NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID }}
9 | THE_GRAPH_NETWORK_API_KEY: ${{ secrets.THE_GRAPH_NETWORK_API_KEY }}
10 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 |
12 | jobs:
13 | check-build-cache:
14 | name: Check cache for build artifacts
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v4
19 |
20 | - name: Check cache for build artifacts
21 | id: cache
22 | uses: actions/cache/restore@v4
23 | with:
24 | path: |
25 | ./packages/arb-token-bridge-ui/build
26 | key: build-artifacts-${{ github.run_id }}
27 |
28 | - name: Install node_modules
29 | if: steps.cache.outputs.cache-hit != 'true'
30 | uses: OffchainLabs/actions/node-modules/install@main
31 |
32 | - name: Build
33 | if: steps.cache.outputs.cache-hit != 'true'
34 | shell: bash
35 | run: yarn build
36 | env:
37 | NEXT_PUBLIC_IS_E2E_TEST: true
38 | NEXT_PUBLIC_INFURA_KEY: ${{ secrets.NEXT_PUBLIC_INFURA_KEY }}
39 | NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID }}
40 | THE_GRAPH_NETWORK_API_KEY: ${{ secrets.THE_GRAPH_NETWORK_API_KEY }}
41 |
42 | - name: Cache build artifacts
43 | if: steps.cache.outputs.cache-hit != 'true'
44 | uses: actions/cache/save@v4
45 | with:
46 | path: |
47 | ./packages/arb-token-bridge-ui/build
48 | key: build-artifacts-${{ github.run_id }}
49 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/public/images/UsdcLogo.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts:
--------------------------------------------------------------------------------
1 | import { Provider } from '@ethersproject/providers'
2 | import { getArbitrumNetwork } from '@arbitrum/sdk'
3 |
4 | import {
5 | l2ArbReverseGatewayAddresses,
6 | l2DaiGatewayAddresses,
7 | l2LptGatewayAddresses,
8 | l2MoonGatewayAddresses,
9 | l2UsdcGatewayAddresses,
10 | l2wstETHGatewayAddresses
11 | } from '../util/networks'
12 |
13 | /**
14 | * Fetch L2 gateways for a given L2 network using its provider. Useful for specifying which gateways to use when fetching withdrawals.
15 | *
16 | * @param l2Provider Provider for the L2 network
17 | */
18 | export async function fetchL2Gateways(l2Provider: Provider) {
19 | const l2Network = await getArbitrumNetwork(l2Provider)
20 |
21 | const gatewaysToUse = []
22 | const l2ArbReverseGateway = l2ArbReverseGatewayAddresses[l2Network.chainId]
23 | const l2DaiGateway = l2DaiGatewayAddresses[l2Network.chainId]
24 | const l2wstETHGateway = l2wstETHGatewayAddresses[l2Network.chainId]
25 | const l2LptGateway = l2LptGatewayAddresses[l2Network.chainId]
26 | const l2MoonGateway = l2MoonGatewayAddresses[l2Network.chainId]
27 | const l2UsdcGateway = l2UsdcGatewayAddresses[l2Network.chainId]
28 |
29 | if (l2ArbReverseGateway) {
30 | gatewaysToUse.push(l2ArbReverseGateway)
31 | }
32 | if (l2DaiGateway) {
33 | gatewaysToUse.push(l2DaiGateway)
34 | }
35 | if (l2wstETHGateway) {
36 | gatewaysToUse.push(l2wstETHGateway)
37 | }
38 | if (l2LptGateway) {
39 | gatewaysToUse.push(l2LptGateway)
40 | }
41 | if (l2MoonGateway) {
42 | gatewaysToUse.push(l2MoonGateway)
43 | }
44 | if (l2UsdcGateway) {
45 | gatewaysToUse.push(l2UsdcGateway)
46 | }
47 |
48 | return gatewaysToUse
49 | }
50 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/TransactionHistory/EmptyTransactionHistory.tsx:
--------------------------------------------------------------------------------
1 | import { GET_HELP_LINK } from '../../constants'
2 | import { ExternalLink } from '../common/ExternalLink'
3 | import {
4 | ContentWrapper,
5 | HistoryLoader,
6 | LoadMoreButton
7 | } from './TransactionHistoryTable'
8 |
9 | export const EmptyTransactionHistory = ({
10 | loading,
11 | isError,
12 | paused,
13 | resume,
14 | tabType
15 | }: {
16 | loading: boolean
17 | isError: boolean
18 | paused: boolean
19 | resume: () => void
20 | tabType: 'pending' | 'settled'
21 | }) => {
22 | if (loading) {
23 | return (
24 |
25 |
26 |
27 | )
28 | }
29 | if (isError) {
30 | return (
31 |
32 |
33 | We seem to be having a difficult time loading your data, we're
34 | working hard to resolve it.
35 |
36 | Please give it a moment and then try refreshing the page.
37 |
38 | If the problem persists, please file a ticket{' '}
39 |
40 | here
41 |
42 | .
43 |
44 |
45 | )
46 | }
47 | if (paused) {
48 | return (
49 |
50 | There are no recent {tabType} transactions.
51 |
52 |
53 | )
54 | }
55 | return (
56 |
57 | No {tabType} transactions.
58 |
59 | )
60 | }
61 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/Sidebar/AppMobileSidebar.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { PlusCircleIcon } from '@heroicons/react/24/outline'
3 | import { MenuItem } from '@offchainlabs/cobalt'
4 | import { ConnectButton } from '@rainbow-me/rainbowkit'
5 | import dynamic from 'next/dynamic'
6 | import { usePostHog } from 'posthog-js/react'
7 | import { useAccount } from 'wagmi'
8 | import { AccountMenuItem } from './AccountMenuItem'
9 |
10 | // Dynamically import the MobileSidebar component with SSR disabled
11 | const DynamicMobileSidebar = dynamic(
12 | () =>
13 | import('@offchainlabs/cobalt').then(mod => ({
14 | default: mod.MobileSidebar
15 | })),
16 | { ssr: false }
17 | )
18 |
19 | export const AppMobileSidebar: React.FC = () => {
20 | const posthog = usePostHog()
21 | const { isConnected } = useAccount()
22 |
23 | return (
24 |
25 |
30 | {isConnected ? (
31 |
32 | ) : (
33 |
34 | {({ openConnectModal }) => (
35 | }
39 | className="border-lime-dark bg-lime-dark py-3"
40 | isMobile
41 | />
42 | )}
43 |
44 | )}
45 |
46 |
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/public/images/sidebar/home.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/public/images/header/headerLogo_governance.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/scripts/utils.ts:
--------------------------------------------------------------------------------
1 | import { ArbitrumNetwork } from '@arbitrum/sdk'
2 | import { OrbitChainConfig } from '../src/util/orbitChainsList'
3 | import { getExplorerUrl, rpcURLs } from '../src/util/networks'
4 |
5 | export interface ChainToMonitor extends ArbitrumNetwork {
6 | parentRpcUrl: string
7 | orbitRpcUrl: string
8 | explorerUrl: string
9 | parentExplorerUrl: string
10 | }
11 |
12 | export const sanitizeExplorerUrl = (url: string) => {
13 | // we want explorer urls to have a trailing slash
14 | if (url.endsWith('/')) {
15 | return url
16 | } else {
17 | return url + '/'
18 | }
19 | }
20 |
21 | export const sanitizeRpcUrl = (url: string) => {
22 | // we want rpc urls to NOT have a trailing slash
23 | if (url.endsWith('/')) {
24 | return url.slice(0, -1)
25 | } else {
26 | return url
27 | }
28 | }
29 |
30 | const hasExplorerUrl = (
31 | chain: ArbitrumNetwork | OrbitChainConfig
32 | ): chain is OrbitChainConfig => {
33 | return typeof (chain as OrbitChainConfig).explorerUrl !== 'undefined'
34 | }
35 |
36 | // make the chain data compatible with that required by the retryable-monitoring script
37 | // TODO: in a later refactor, we will update the term `orbitRpcUrl` to chain-agnostic, `rpcUrl`
38 | export const getChainToMonitor = ({
39 | chain,
40 | rpcUrl
41 | }: {
42 | chain: ArbitrumNetwork | OrbitChainConfig
43 | rpcUrl: string
44 | }): ChainToMonitor => ({
45 | ...chain,
46 | explorerUrl: sanitizeExplorerUrl(
47 | hasExplorerUrl(chain) ? chain.explorerUrl : getExplorerUrl(chain.chainId)
48 | ),
49 | orbitRpcUrl: sanitizeRpcUrl(rpcUrl),
50 | parentRpcUrl: sanitizeRpcUrl(rpcURLs[chain.parentChainId]),
51 | parentExplorerUrl: sanitizeExplorerUrl(getExplorerUrl(chain.parentChainId))
52 | })
53 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/common/Transition.tsx:
--------------------------------------------------------------------------------
1 | import { Transition as HeadlessUiTransition } from '@headlessui/react'
2 | import { PropsWithChildren } from 'react'
3 | import { twMerge } from 'tailwind-merge'
4 |
5 | type TransitionSpeed = 'slow' | 'normal' | 'fast'
6 |
7 | type TransitionOptions = {
8 | enterSpeed?: TransitionSpeed
9 | leaveSpeed?: TransitionSpeed
10 | unmountOnLeave?: boolean
11 | }
12 |
13 | type TransitionProps = PropsWithChildren<{
14 | isOpen?: boolean
15 | options?: TransitionOptions
16 | className?: string
17 | afterLeave?: () => void
18 | }>
19 |
20 | function getDurationClassName(speed: TransitionSpeed) {
21 | switch (speed) {
22 | case 'slow':
23 | return 'duration-1000'
24 | case 'normal':
25 | return 'duration-500'
26 | case 'fast':
27 | return 'duration-200'
28 | }
29 | }
30 |
31 | export const Transition = (props: TransitionProps) => {
32 | const { options, children, className, isOpen, afterLeave } = props
33 |
34 | const enterSpeed = options?.enterSpeed ?? 'fast'
35 | const leaveSpeed = options?.leaveSpeed ?? 'fast'
36 | const unmountOnLeave = options?.unmountOnLeave ?? true
37 |
38 | return (
39 |
51 | {children}
52 |
53 | )
54 | }
55 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/public/images/ArbitrumOneLogo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts:
--------------------------------------------------------------------------------
1 | import { Chain } from 'wagmi'
2 | import { mainnet, arbitrum } from 'wagmi/chains'
3 |
4 | import {
5 | chainToWagmiChain,
6 | sepolia,
7 | holesky,
8 | arbitrumNova,
9 | arbitrumSepolia,
10 | localL1Network,
11 | localL2Network,
12 | localL3Network,
13 | baseSepolia,
14 | base
15 | } from './wagmiAdditionalNetworks'
16 | import { ChainId, getCustomChainFromLocalStorageById } from '../networks'
17 | import { orbitChains } from '../orbitChainsList'
18 |
19 | export function getWagmiChain(chainId: number): Chain {
20 | const customChain = getCustomChainFromLocalStorageById(chainId)
21 | const orbitChain = orbitChains[chainId]
22 |
23 | if (customChain) {
24 | return chainToWagmiChain(customChain)
25 | }
26 |
27 | if (orbitChain) {
28 | return chainToWagmiChain(orbitChain)
29 | }
30 |
31 | switch (chainId) {
32 | case ChainId.Ethereum:
33 | return mainnet
34 |
35 | case ChainId.ArbitrumOne:
36 | return arbitrum
37 |
38 | case ChainId.ArbitrumNova:
39 | return arbitrumNova
40 |
41 | case ChainId.Base:
42 | return base
43 |
44 | // Testnets
45 | case ChainId.Sepolia:
46 | return sepolia
47 |
48 | case ChainId.Holesky:
49 | return holesky
50 |
51 | case ChainId.ArbitrumSepolia:
52 | return arbitrumSepolia
53 |
54 | case ChainId.BaseSepolia:
55 | return baseSepolia
56 |
57 | // Local networks
58 | case ChainId.Local:
59 | return localL1Network
60 |
61 | case ChainId.ArbitrumLocal:
62 | return localL2Network
63 |
64 | case ChainId.L3Local:
65 | return localL3Network
66 |
67 | default:
68 | throw new Error(`[getWagmiChain] Unexpected chain id: ${chainId}`)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/useNativeCurrencyBalances.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react'
2 | import { BigNumber } from 'ethers'
3 |
4 | import { useNativeCurrency } from '../../../hooks/useNativeCurrency'
5 | import { useNetworks } from '../../../hooks/useNetworks'
6 | import { useNetworksRelationship } from '../../../hooks/useNetworksRelationship'
7 | import { useBalances } from '../../../hooks/useBalances'
8 |
9 | export function useNativeCurrencyBalances(): {
10 | sourceBalance: BigNumber | null
11 | destinationBalance: BigNumber | null
12 | } {
13 | const [networks] = useNetworks()
14 | const { childChainProvider, isDepositMode } =
15 | useNetworksRelationship(networks)
16 | const nativeCurrency = useNativeCurrency({ provider: childChainProvider })
17 |
18 | const { ethParentBalance, erc20ParentBalances, ethChildBalance } =
19 | useBalances()
20 |
21 | return useMemo(() => {
22 | if (!nativeCurrency.isCustom) {
23 | return {
24 | sourceBalance: isDepositMode ? ethParentBalance : ethChildBalance,
25 | destinationBalance: isDepositMode ? ethChildBalance : ethParentBalance
26 | }
27 | }
28 |
29 | const customFeeTokenParentBalance =
30 | erc20ParentBalances?.[nativeCurrency.address] ?? null
31 | const customFeeTokenChildBalance = ethChildBalance
32 |
33 | return {
34 | sourceBalance: isDepositMode
35 | ? customFeeTokenParentBalance
36 | : customFeeTokenChildBalance,
37 | destinationBalance: isDepositMode
38 | ? customFeeTokenChildBalance
39 | : customFeeTokenParentBalance
40 | }
41 | }, [
42 | nativeCurrency,
43 | erc20ParentBalances,
44 | ethChildBalance,
45 | isDepositMode,
46 | ethParentBalance
47 | ])
48 | }
49 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/scripts/generateCoreChainsToMonitor.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import 'dotenv/config'
3 | import { getArbitrumNetwork } from '@arbitrum/sdk'
4 | import { ChainId, rpcURLs } from '../src/util/networks'
5 | import { getChainToMonitor } from './utils'
6 |
7 | // github secrets return '' for empty values, so we need to sanitize the value
8 | const sanitizeEnvValue = (envValue: any) => {
9 | return typeof envValue === 'string' && envValue !== '' ? envValue : undefined
10 | }
11 |
12 | async function generateCoreChainsToMonitor() {
13 | const novaChain = {
14 | ...getArbitrumNetwork(ChainId.ArbitrumNova),
15 | rpcURL:
16 | sanitizeEnvValue(process.env.NOVA_MONITOR_RPC_URL) ??
17 | rpcURLs[ChainId.ArbitrumNova]
18 | }
19 | const arbOneChain = {
20 | ...getArbitrumNetwork(ChainId.ArbitrumOne),
21 | rpcURL:
22 | sanitizeEnvValue(process.env.ARB_ONE_MONITOR_RPC_URL) ??
23 | rpcURLs[ChainId.ArbitrumOne]
24 | }
25 |
26 | // don't need to monitor arbOne chain in case of retryable-monitoring
27 | const chains =
28 | process.env.INCLUDE_ARB_ONE_AS_CORE_CHAIN === 'true'
29 | ? [arbOneChain, novaChain]
30 | : [novaChain]
31 |
32 | // make the chain data compatible with that required by the monitoring script
33 | const coreChainsToMonitor = chains.map(coreChain =>
34 | getChainToMonitor({
35 | chain: coreChain,
36 | rpcUrl: coreChain.rpcURL
37 | })
38 | )
39 |
40 | // write to orbit-chains.json, we will use this json as an input to the monitoring script
41 | const resultsJson = JSON.stringify(
42 | {
43 | childChains: coreChainsToMonitor
44 | },
45 | null,
46 | 2
47 | )
48 | fs.writeFileSync('./public/__auto-generated-core-chains.json', resultsJson)
49 | }
50 |
51 | generateCoreChainsToMonitor()
52 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/public/images/header/headerLogo_help.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/util/L2NativeUtils.ts:
--------------------------------------------------------------------------------
1 | import { ChainId } from '../util/networks'
2 | import { CommonAddress } from './CommonAddressUtils'
3 |
4 | export type L2NativeToken = {
5 | name: string
6 | symbol: string
7 | address: string
8 | decimals: number
9 | logoURI: string
10 | }
11 |
12 | export const ArbOneNativeUSDC = {
13 | name: 'USD Coin',
14 | symbol: 'USDC',
15 | address: CommonAddress.ArbitrumOne.USDC,
16 | decimals: 6,
17 | logoURI: 'https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png'
18 | }
19 |
20 | const L2NativeTokens: { [chainId: number]: L2NativeToken[] } = {
21 | [ChainId.ArbitrumOne]: [
22 | {
23 | name: 'GMX',
24 | symbol: 'GMX',
25 | address: '0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a',
26 | decimals: 18,
27 | logoURI: 'https://s2.coinmarketcap.com/static/img/coins/64x64/11857.png'
28 | },
29 | {
30 | name: 'STASIS EURO',
31 | symbol: 'EURS',
32 | address: '0xD22a58f79e9481D1a88e00c343885A588b34b68B',
33 | decimals: 2,
34 | logoURI: 'https://s2.coinmarketcap.com/static/img/coins/64x64/2989.png'
35 | }
36 | ],
37 | [ChainId.ArbitrumNova]: []
38 | }
39 |
40 | function find(erc20L2Address: string, l2ChainId: number) {
41 | return (
42 | (L2NativeTokens[l2ChainId] ?? [])
43 | //
44 | .find(
45 | token => token.address.toLowerCase() === erc20L2Address.toLowerCase()
46 | )
47 | )
48 | }
49 |
50 | export function getL2NativeToken(
51 | erc20L2Address: string,
52 | l2ChainId: number
53 | ): L2NativeToken {
54 | const token = find(erc20L2Address, l2ChainId)
55 |
56 | if (typeof token === 'undefined') {
57 | throw new Error(
58 | `Can't find L2-native token with address ${erc20L2Address} on chain ${l2ChainId}`
59 | )
60 | }
61 |
62 | return token
63 | }
64 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/TransferPanel/CctpTabContent.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren } from 'react'
2 | import { CCTP_DOCUMENTATION } from '../../constants'
3 | import { useCCTPIsBlocked } from '../../hooks/CCTP/useCCTPIsBlocked'
4 | import { ExternalLink } from '../common/ExternalLink'
5 | import { getExplorerUrl, getNetworkName } from '../../util/networks'
6 | import { CCTPSupportedChainId, getUSDCAddresses } from '../../state/cctpState'
7 |
8 | export const CctpTabContent = ({
9 | destinationChainId,
10 | children
11 | }: PropsWithChildren<{
12 | destinationChainId: CCTPSupportedChainId
13 | }>) => {
14 | const { data: isCctpBlocked, isLoading: isLoadingIsCctpBlocked } =
15 | useCCTPIsBlocked()
16 |
17 | if (isLoadingIsCctpBlocked || isCctpBlocked) {
18 | return (
19 |
20 | Access to Circle's bridge is restricted in certain jurisdictions.
21 | For more details, please consult Circle's{' '}
22 |
23 | documentation.
24 | {' '}
25 |
26 | )
27 | }
28 |
29 | return (
30 | <>
31 |
32 | Receive{' '}
33 |
39 | Native USDC
40 | {' '}
41 | on {getNetworkName(destinationChainId)} with Circle's{' '}
42 |
43 | Cross-Chain Transfer Protocol
44 | {' '}
45 | within the Arbitrum Bridge.
46 |
47 | {children}
48 | >
49 | )
50 | }
51 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/src/components/Sidebar/AccountMenuItem.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ArrowLeftOnRectangleIcon,
3 | ArrowTopRightOnSquareIcon,
4 | Cog6ToothIcon,
5 | DocumentTextIcon
6 | } from '@heroicons/react/24/outline'
7 | import { MenuItem, MenuItemExpandable } from '@offchainlabs/cobalt'
8 |
9 | import { getExplorerUrl } from '../../util/networks'
10 | import { SafeImage } from '../common/SafeImage'
11 | import { useAccountMenu } from '../../hooks/useAccountMenu'
12 | import { CustomBoringAvatar } from '../common/CustomBoringAvatar'
13 |
14 | export const AccountMenuItem = () => {
15 | const {
16 | address,
17 | accountShort,
18 | ensName,
19 | ensAvatar,
20 | disconnect,
21 | udInfo,
22 | chain,
23 | setQueryParams
24 | } = useAccountMenu()
25 |
26 | return (
27 | }
35 | />
36 | }
37 | >
38 | {chain && (
39 | }
42 | href={`${getExplorerUrl(chain.id)}/address/${address}`}
43 | isMobile
44 | />
45 | )}
46 | }
49 | onClick={() => setQueryParams({ settingsOpen: true })}
50 | isMobile
51 | />
52 | }
55 | onClick={() => disconnect()}
56 | isMobile
57 | />
58 |
59 | )
60 | }
61 |
--------------------------------------------------------------------------------
/packages/arb-token-bridge-ui/tests/e2e/specfiles.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Login and balance check",
4 | "file": "tests/e2e/specs/**/login.cy.{js,jsx,ts,tsx}",
5 | "recordVideo": "false"
6 | },
7 | {
8 | "name": "Deposit native token",
9 | "file": "tests/e2e/specs/**/depositNativeToken.cy.{js,jsx,ts,tsx}",
10 | "recordVideo": "false"
11 | },
12 | {
13 | "name": "Withdraw native token",
14 | "file": "tests/e2e/specs/**/withdrawNativeToken.cy.{js,jsx,ts,tsx}",
15 | "recordVideo": "false"
16 | },
17 | {
18 | "name": "Deposit ERC20",
19 | "file": "tests/e2e/specs/**/depositERC20.cy.{js,jsx,ts,tsx}",
20 | "recordVideo": "false"
21 | },
22 | {
23 | "name": "Withdraw ERC20",
24 | "file": "tests/e2e/specs/**/withdrawERC20.cy.{js,jsx,ts,tsx}",
25 | "recordVideo": "false"
26 | },
27 | {
28 | "name": "Batch deposit",
29 | "file": "tests/e2e/specs/**/batchDeposit.cy.{js,jsx,ts,tsx}",
30 | "recordVideo": "false"
31 | },
32 | {
33 | "name": "TX history",
34 | "file": "tests/e2e/specs/**/txHistory.cy.{js,jsx,ts,tsx}",
35 | "recordVideo": "false"
36 | },
37 | {
38 | "name": "Approve ERC20",
39 | "file": "tests/e2e/specs/**/approveToken.cy.{js,jsx,ts,tsx}",
40 | "recordVideo": "false"
41 | },
42 | {
43 | "name": "Import test ERC20",
44 | "file": "tests/e2e/specs/**/importToken.cy.{js,jsx,ts,tsx}",
45 | "recordVideo": "false"
46 | },
47 | {
48 | "name": "Read classic deposits",
49 | "file": "tests/e2e/specs/**/readClassicDeposits.cy.{js,jsx,ts,tsx}",
50 | "recordVideo": "false"
51 | },
52 | {
53 | "name": "Redeem Retryable",
54 | "file": "tests/e2e/specs/**/redeemRetryable.cy.{js,jsx,ts,tsx}",
55 | "recordVideo": "false"
56 | },
57 | {
58 | "name": "Switch network",
59 | "file": "tests/e2e/specs/**/switchNetworks.cy.{js,jsx,ts,tsx}",
60 | "recordVideo": "false"
61 | }
62 | ]
63 |
--------------------------------------------------------------------------------