diff --git a/packages/bridge-ui/src/App.svelte b/packages/bridge-ui/src/App.svelte index a9909313c22..6d0e3ef7da5 100644 --- a/packages/bridge-ui/src/App.svelte +++ b/packages/bridge-ui/src/App.svelte @@ -14,9 +14,9 @@ import Home from './pages/home/Home.svelte'; import { setupI18n } from './i18n'; import { BridgeType } from './domain/bridge'; - import { ETHBridge } from './eth/ETHBridge'; + import { ETHBridge } from './bridge/ETHBridge'; + import { ERC20Bridge } from './bridge/ERC20Bridge'; import { bridges, chainIdToTokenVaultAddress } from './store/bridge'; - import { ERC20Bridge } from './erc20/ERC20Bridge'; import { pendingTransactions, transactioner, @@ -28,15 +28,6 @@ import { wagmiClient } from './store/wagmi'; setupI18n({ withLocale: 'en' }); - import { - chains, - CHAIN_ID_MAINNET, - CHAIN_ID_TAIKO, - CHAIN_MAINNET, - CHAIN_TKO, - mainnet, - taiko, - } from './domain/chain'; import SwitchEthereumChainModal from './components/modals/SwitchEthereumChainModal.svelte'; import { ProofService } from './proof/ProofService'; import { ethers } from 'ethers'; @@ -53,24 +44,32 @@ import { RelayerAPIService } from './relayer-api/RelayerAPIService'; import type { RelayerAPI } from './domain/relayerApi'; import { relayerApi, relayerBlockInfoMap } from './store/relayerApi'; + import { + L1_CHAIN_ID, + L1_TOKEN_VAULT_ADDRESS, + L2_CHAIN_ID, + L2_TOKEN_VAULT_ADDRESS, + } from './constants/envVars'; + import { + chainsRecord, + mainnetWagmiChain, + taikoWagmiChain, + } from './chain/chains'; - const providerMap: Map = new Map< - number, - ethers.providers.JsonRpcProvider - >(); + const providerMap = new Map(); providerMap.set( - CHAIN_ID_MAINNET, + L1_CHAIN_ID, new ethers.providers.JsonRpcProvider(import.meta.env.VITE_L1_RPC_URL), ); providerMap.set( - CHAIN_ID_TAIKO, + L2_CHAIN_ID, new ethers.providers.JsonRpcProvider(import.meta.env.VITE_L2_RPC_URL), ); providers.set(providerMap); const { chains: wagmiChains, provider } = configureChains( - [mainnet, taiko], + [mainnetWagmiChain, taikoWagmiChain], [ publicProvider(), jsonRpcProvider({ @@ -115,11 +114,8 @@ }); chainIdToTokenVaultAddress.update((store) => { - store.set(CHAIN_TKO.id, import.meta.env.VITE_TAIKO_TOKEN_VAULT_ADDRESS); - store.set( - CHAIN_MAINNET.id, - import.meta.env.VITE_MAINNET_TOKEN_VAULT_ADDRESS, - ); + store.set(L2_CHAIN_ID, L2_TOKEN_VAULT_ADDRESS); + store.set(L1_CHAIN_ID, L1_TOKEN_VAULT_ADDRESS); return store; }); @@ -221,7 +217,7 @@ if (!tx.msgHash) return; const contract = new ethers.Contract( - chains[tx.toChainId].bridgeAddress, + chainsRecord[tx.toChainId].bridgeAddress, BridgeABI, provider, ); diff --git a/packages/bridge-ui/src/erc20/ERC20Bridge.spec.ts b/packages/bridge-ui/src/bridge/ERC20Bridge.spec.ts similarity index 92% rename from packages/bridge-ui/src/erc20/ERC20Bridge.spec.ts rename to packages/bridge-ui/src/bridge/ERC20Bridge.spec.ts index 67637621de0..aa4b356aee3 100644 --- a/packages/bridge-ui/src/erc20/ERC20Bridge.spec.ts +++ b/packages/bridge-ui/src/bridge/ERC20Bridge.spec.ts @@ -1,13 +1,8 @@ import { BigNumber, ethers, Wallet } from 'ethers'; -import { - CHAIN_ID_MAINNET, - CHAIN_ID_TAIKO, - mainnet, - taiko, -} from '../domain/chain'; import type { ApproveOpts, Bridge, BridgeOpts } from '../domain/bridge'; import { ERC20Bridge } from './ERC20Bridge'; import { Message, MessageStatus } from '../domain/message'; +import { L1_CHAIN_ID, L2_CHAIN_ID } from '../constants/envVars'; const mockSigner = { getAddress: jest.fn(), @@ -48,8 +43,8 @@ const opts: BridgeOpts = { amountInWei: BigNumber.from(1), signer: wallet, tokenAddress: '0xtoken', - fromChainId: mainnet.id, - toChainId: taiko.id, + fromChainId: L1_CHAIN_ID, + toChainId: L2_CHAIN_ID, tokenVaultAddress: '0x456', processingFeeInWei: BigNumber.from(2), memo: 'memo', @@ -226,8 +221,8 @@ describe('bridge tests', () => { amountInWei: BigNumber.from(1), signer: wallet, tokenAddress: '0xtoken', - fromChainId: mainnet.id, - toChainId: taiko.id, + fromChainId: L1_CHAIN_ID, + toChainId: L2_CHAIN_ID, tokenVaultAddress: '0x456', to: await wallet.getAddress(), }; @@ -261,8 +256,8 @@ describe('bridge tests', () => { await expect( bridge.Claim({ message: { - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), gasLimit: BigNumber.from(1), } as unknown as Message, msgHash: '0x', @@ -285,8 +280,8 @@ describe('bridge tests', () => { await expect( bridge.Claim({ message: { - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), gasLimit: BigNumber.from(1), } as unknown as Message, msgHash: '0x', @@ -314,8 +309,8 @@ describe('bridge tests', () => { bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), gasLimit: BigNumber.from(1), } as unknown as Message, msgHash: '0x', @@ -348,8 +343,8 @@ describe('bridge tests', () => { await bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -384,8 +379,8 @@ describe('bridge tests', () => { await bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -421,8 +416,8 @@ describe('bridge tests', () => { bridge.ReleaseTokens({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -456,8 +451,8 @@ describe('bridge tests', () => { await bridge.ReleaseTokens({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, diff --git a/packages/bridge-ui/src/erc20/ERC20Bridge.ts b/packages/bridge-ui/src/bridge/ERC20Bridge.ts similarity index 94% rename from packages/bridge-ui/src/erc20/ERC20Bridge.ts rename to packages/bridge-ui/src/bridge/ERC20Bridge.ts index 3cc484d0a91..b2c701f1a54 100644 --- a/packages/bridge-ui/src/erc20/ERC20Bridge.ts +++ b/packages/bridge-ui/src/bridge/ERC20Bridge.ts @@ -12,7 +12,7 @@ import ERC20 from '../constants/abi/ERC20'; import type { Prover } from '../domain/proof'; import { MessageStatus } from '../domain/message'; import BridgeABI from '../constants/abi/Bridge'; -import { chains } from '../domain/chain'; +import { chainsRecord } from '../chain/chains'; export class ERC20Bridge implements Bridge { private readonly prover: Prover; @@ -179,9 +179,9 @@ export class ERC20Bridge implements Bridge { srcBridgeAddress: opts.srcBridgeAddress, destChain: opts.message.destChainId.toNumber(), destHeaderSyncAddress: - chains[opts.message.destChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.destChainId.toNumber()].headerSyncAddress, srcSignalServiceAddress: - chains[opts.message.srcChainId.toNumber()].signalServiceAddress, + chainsRecord[opts.message.srcChainId.toNumber()].signalServiceAddress, }); if (opts.message.gasLimit.gt(BigNumber.from(2500000))) { @@ -224,9 +224,9 @@ export class ERC20Bridge implements Bridge { destBridgeAddress: opts.destBridgeAddress, destChain: opts.message.destChainId.toNumber(), destHeaderSyncAddress: - chains[opts.message.destChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.destChainId.toNumber()].headerSyncAddress, srcHeaderSyncAddress: - chains[opts.message.srcChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.srcChainId.toNumber()].headerSyncAddress, }; const proof = await this.prover.GenerateReleaseProof(proofOpts); diff --git a/packages/bridge-ui/src/eth/ETHBridge.spec.ts b/packages/bridge-ui/src/bridge/ETHBridge.spec.ts similarity index 90% rename from packages/bridge-ui/src/eth/ETHBridge.spec.ts rename to packages/bridge-ui/src/bridge/ETHBridge.spec.ts index 14051ad5de8..334f926d2ad 100644 --- a/packages/bridge-ui/src/eth/ETHBridge.spec.ts +++ b/packages/bridge-ui/src/bridge/ETHBridge.spec.ts @@ -1,13 +1,8 @@ import { BigNumber, ethers, Wallet } from 'ethers'; -import { - CHAIN_ID_MAINNET, - CHAIN_ID_TAIKO, - mainnet, - taiko, -} from '../domain/chain'; import type { Bridge, BridgeOpts } from '../domain/bridge'; import { ETHBridge } from './ETHBridge'; import { Message, MessageStatus } from '../domain/message'; +import { L1_CHAIN_ID, L2_CHAIN_ID } from '../constants/envVars'; const mockSigner = { getAddress: jest.fn(), @@ -79,8 +74,8 @@ describe('bridge tests', () => { amountInWei: BigNumber.from(1), signer: wallet, tokenAddress: '', - fromChainId: mainnet.id, - toChainId: taiko.id, + fromChainId: L1_CHAIN_ID, + toChainId: L2_CHAIN_ID, tokenVaultAddress: '0x456', processingFeeInWei: BigNumber.from(2), memo: 'memo', @@ -113,8 +108,8 @@ describe('bridge tests', () => { amountInWei: BigNumber.from(1), signer: wallet, tokenAddress: '', - fromChainId: mainnet.id, - toChainId: taiko.id, + fromChainId: L1_CHAIN_ID, + toChainId: L2_CHAIN_ID, tokenVaultAddress: '0x456', to: await wallet.getAddress(), }; @@ -143,8 +138,8 @@ describe('bridge tests', () => { await expect( bridge.Claim({ message: { - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), gasLimit: BigNumber.from(1), } as unknown as Message, msgHash: '0x', @@ -172,8 +167,8 @@ describe('bridge tests', () => { bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), gasLimit: BigNumber.from(1), } as unknown as Message, msgHash: '0x', @@ -206,8 +201,8 @@ describe('bridge tests', () => { await bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -242,8 +237,8 @@ describe('bridge tests', () => { await bridge.Claim({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -279,8 +274,8 @@ describe('bridge tests', () => { bridge.ReleaseTokens({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, @@ -314,8 +309,8 @@ describe('bridge tests', () => { await bridge.ReleaseTokens({ message: { owner: '0x', - srcChainId: BigNumber.from(CHAIN_ID_TAIKO), - destChainId: BigNumber.from(CHAIN_ID_MAINNET), + srcChainId: BigNumber.from(L2_CHAIN_ID), + destChainId: BigNumber.from(L1_CHAIN_ID), sender: '0x01', gasLimit: BigNumber.from(1), } as unknown as Message, diff --git a/packages/bridge-ui/src/eth/ETHBridge.ts b/packages/bridge-ui/src/bridge/ETHBridge.ts similarity index 93% rename from packages/bridge-ui/src/eth/ETHBridge.ts rename to packages/bridge-ui/src/bridge/ETHBridge.ts index 0bbb9439ae4..6c590584aab 100644 --- a/packages/bridge-ui/src/eth/ETHBridge.ts +++ b/packages/bridge-ui/src/bridge/ETHBridge.ts @@ -11,7 +11,7 @@ import TokenVault from '../constants/abi/TokenVault'; import type { Prover } from '../domain/proof'; import { MessageStatus } from '../domain/message'; import BridgeABI from '../constants/abi/Bridge'; -import { chains } from '../domain/chain'; +import { chainsRecord } from '../chain/chains'; export class ETHBridge implements Bridge { private readonly prover: Prover; @@ -127,9 +127,9 @@ export class ETHBridge implements Bridge { srcBridgeAddress: opts.srcBridgeAddress, destChain: opts.message.destChainId.toNumber(), destHeaderSyncAddress: - chains[opts.message.destChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.destChainId.toNumber()].headerSyncAddress, srcSignalServiceAddress: - chains[opts.message.srcChainId.toNumber()].signalServiceAddress, + chainsRecord[opts.message.srcChainId.toNumber()].signalServiceAddress, }; const proof = await this.prover.GenerateProof(proofOpts); @@ -168,9 +168,9 @@ export class ETHBridge implements Bridge { destBridgeAddress: opts.destBridgeAddress, destChain: opts.message.destChainId.toNumber(), destHeaderSyncAddress: - chains[opts.message.destChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.destChainId.toNumber()].headerSyncAddress, srcHeaderSyncAddress: - chains[opts.message.srcChainId.toNumber()].headerSyncAddress, + chainsRecord[opts.message.srcChainId.toNumber()].headerSyncAddress, }; const proof = await this.prover.GenerateReleaseProof(proofOpts); diff --git a/packages/bridge-ui/src/chain/chains.ts b/packages/bridge-ui/src/chain/chains.ts new file mode 100644 index 00000000000..6e98495421b --- /dev/null +++ b/packages/bridge-ui/src/chain/chains.ts @@ -0,0 +1,87 @@ +import type { Chain as WagmiChain } from '@wagmi/core'; +import { + L1_BRIDGE_ADDRESS, + L1_CHAIN_ID, + L1_CHAIN_NAME, + L1_EXPLORER_URL, + L1_HEADER_SYNC_ADDRESS, + L1_RPC, + L1_SIGNAL_SERVICE_ADDRESS, + L2_BRIDGE_ADDRESS, + L2_CHAIN_ID, + L2_CHAIN_NAME, + L2_EXPLORER_URL, + L2_HEADER_SYNC_ADDRESS, + L2_RPC, + L2_SIGNAL_SERVICE_ADDRESS, +} from '../constants/envVars'; +import type { Chain } from '../domain/chain'; +import Eth from '../components/icons/ETH.svelte'; +import Taiko from '../components/icons/TKO.svelte'; + +export const mainnetChain: Chain = { + id: L1_CHAIN_ID, + name: L1_CHAIN_NAME, + rpc: L1_RPC, + enabled: true, + icon: Eth, + bridgeAddress: L1_BRIDGE_ADDRESS, + headerSyncAddress: L1_HEADER_SYNC_ADDRESS, + explorerUrl: L1_EXPLORER_URL, + signalServiceAddress: L1_SIGNAL_SERVICE_ADDRESS, +}; + +export const taikoChain: Chain = { + id: L2_CHAIN_ID, + name: L2_CHAIN_NAME, + rpc: L2_RPC, + enabled: true, + icon: Taiko, + bridgeAddress: L2_BRIDGE_ADDRESS, + headerSyncAddress: L2_HEADER_SYNC_ADDRESS, + explorerUrl: L2_EXPLORER_URL, + signalServiceAddress: L2_SIGNAL_SERVICE_ADDRESS, +}; + +export const chainsRecord: Record = { + [L1_CHAIN_ID]: mainnetChain, + [L2_CHAIN_ID]: taikoChain, +}; + +// TODO: can we not merge this chain into mainnetChain? +export const mainnetWagmiChain: WagmiChain = { + id: L1_CHAIN_ID, + name: L1_CHAIN_NAME, + network: '', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { + http: [L1_RPC], + }, + }, + blockExplorers: { + default: { + name: 'Main', + url: L1_EXPLORER_URL, + }, + }, +}; + +// TODO: same here, merge it into taikoChain +export const taikoWagmiChain: WagmiChain = { + id: L2_CHAIN_ID, + name: L2_CHAIN_NAME, + network: '', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { + http: [L2_RPC], + }, + }, + blockExplorers: { + default: { + name: 'Main', + url: L2_EXPLORER_URL, + }, + }, +}; diff --git a/packages/bridge-ui/src/components/ChainDropdown.svelte b/packages/bridge-ui/src/components/ChainDropdown.svelte index 6e036a487ce..db6d8e8c485 100644 --- a/packages/bridge-ui/src/components/ChainDropdown.svelte +++ b/packages/bridge-ui/src/components/ChainDropdown.svelte @@ -1,12 +1,13 @@