const sender = Ethers.send("eth_requestAccounts", [])[0]; if (!sender) return <Web3Connect connectLabel="Connect Web3 Wallet" />; const networks = ["ethereum", "aurora"]; const testnetChainIds = { ethereum: 5, aurora: 1313161555, }; const testnetNetworkNames = { ethereum: "Goerli Testnet", aurora: "Aurora Testnet", }; const mainnetChainIds = { ethereum: 1, aurora: 1313161554, }; const mainnetNetworkNames = { ethereum: "Ethereum Mainnet", aurora: "Aurora Mainnet", }; const testnetConfig = { etherCustodianAddress: "0x84a82Bb39c83989D5Dc07e1310281923D2544dC2", }; const mainnetConfig = { etherCustodianAddress: "0x6BFaD42cFC4EfC96f529D786D643Ff4A8B89FA52", }; const tokens = { ETH: { symbol: "ETH", name: "Ethereum", ethereumAddress: undefined, nearAddress: "aurora", auroraAddress: undefined, decimals: 18, origin: "ethereum", }, FAU: { symbol: "FAU", name: "FaucetToken", ethereumAddress: "0xba62bcfcaafc6622853cca2be6ac7d845bc0f2dc", nearAddress: "ba62bcfcaafc6622853cca2be6ac7d845bc0f2dc.factory.goerli.testnet", auroraAddress: "0xf93cd0e464f74c240d8ebb7ed55ce6b43452f913", decimals: 18, origin: "ethereum", }, }; // Get balance on network switch. const fetchBalance = (tokenSymbol) => { const tokenAddress = tokens[tokenSymbol][`${state.sourceNetwork}Address`]; if (tokenAddress?.length) { // erc-20 const erc20 = new ethers.Contract( tokenAddress, ["function balanceOf(address) view returns (uint)"], Ethers.provider() ); erc20.balanceOf(sender).then((balance) => { State.update({ senderBalance: ethers.BigNumber.from(balance), tokenSymbol, }); }); } else if (tokenAddress === undefined) { Ethers.provider() .getBalance(sender) .then((balance) => { State.update({ senderBalance: ethers.BigNumber.from(balance), tokenSymbol, }); }); } else { // Token address = null: not bridged on this network. State.update({ senderBalance: ethers.BigNumber.from(0), tokenSymbol }); } }; initState({ tokenSymbol: null, sourceTokenBalance: ethers.BigNumber.from(0), senderBalance: ethers.BigNumber.from(0), amount: "", bigNumberAmount: ethers.BigNumber.from(0), sourceNetwork: "ethereum", destinationNetwork: "aurora", initialized: false, }); Ethers.provider() .getNetwork() .then((network) => { if (!state.initialized) { // Choose testnet or mainnet config depending on connected network. const walletChainId = network.chainId; const isTestnet = walletChainId === testnetChainIds.aurora || walletChainId === testnetChainIds.ethereum; // Set the bridge direction on network switch: // bos.gg doesn't keep the component state on wallet network switch ! const sourceNetwork = testnetChainIds.ethereum === walletChainId || mainnetChainIds.ethereum === walletChainId ? "ethereum" : "aurora"; State.update({ walletChainId: network.chainId, chainIds: isTestnet ? testnetChainIds : mainnetChainIds, networkNames: isTestnet ? testnetNetworkNames : mainnetNetworkNames, config: isTestnet ? testnetConfig : mainnetConfig, isTestnet, sourceNetwork, destinationNetwork: sourceNetwork === "ethereum" ? "aurora" : "ethereum", initialized: true, }); } }); const wrongWalletNetwork = state.walletChainId !== state.chainIds[state.sourceNetwork]; if (wrongWalletNetwork) { State.update({ tokenSymbol: null, amount: "", senderBalance: ethers.BigNumber.from(0), bigNumberAmount: ethers.BigNumber.from(0), }); } const bridgeTokens = () => { console.log("WIP"); return; if (state.sourceNetwork !== "ethereum") { console.log("Coming soon..."); return; } const iface = new ethers.utils.Interface([ "function depositToEvm(string,uint) payable", ]); const data = iface.encodeFunctionData("depositToEvm", [ sender.slice(2).toLowerCase(), 0, ]); console.log(data); const ethTokenLocker = new ethers.Contract( state.config.etherCustodianAddress, ["function depositToEvm(string,uint) payable"], Ethers.provider().getSigner() ); // Cannot call a contract with data: // Error: Not a function call expression ethTokenLocker .submit(state.config.etherCustodianAddress, { value: state.bigNumberAmount.toHexString(), data, }) .then((txHash) => { console.log(txHash); }); ethTokenLocker.depositToEVM(sender.slice(2).toLowerCase(), 0, { value: state.bigNumberAmount.toHexString(), }); //.then((txHash) => console.log(txHash)); }; if (!state.initialized) return <></>; return ( <> <h2> {" "} 🌈 {state.isTestnet ? "Testnet Rainbow Bridge" : "Rainbow Bridge (alpha)"}{" "} 🌈{" "} </h2> <div class="mb-3 col-lg-6"> <label for="selectSourceNetwork">Select Source Network</label> <select class="form-select" id="selectSourceNetwork" onChange={(e) => { State.update({ sourceNetwork: e.target.value }); if (state.destinationNetwork === e.target.value) { State.update({ destinationNetwork: networks.find( (network) => network !== e.target.value ), }); } }} > <option selected={state.sourceNetwork === "aurora"} value={"aurora"}> {state.networkNames.aurora} </option> <option selected={state.sourceNetwork === "ethereum"} value={"ethereum"} > {state.networkNames.ethereum} </option> </select> {state.walletChainId !== state.chainIds[state.sourceNetwork] && ( <p> Connect your wallet network to{" "} {state.networkNames[state.sourceNetwork]} </p> )} </div> <div class="mb-3 col-lg-6"> <label for="selectToken">Select token</label> <select class="form-select" id="selectToken" disabled={wrongWalletNetwork} onChange={(e) => { if (e.target.value === "...") { State.update({ tokenSymbol: null, amount: "", bigNumberAmount: ethers.BigNumber.from(0), }); return; } State.update({ tokenSymbol: e.target.value, }); fetchBalance(e.target.value); }} > <option selected={state.tokenSymbol === null} value={null}> ... </option> {Object.keys(tokens).map((symbol) => ( <option value={symbol}>{symbol}</option> ))} </select> </div> <div class="mb-3 col-lg-6"> <label for="amount" class="form-label"> Enter the amount </label> <input value={state.amount} class="form-control" id="amount" disabled={wrongWalletNetwork || !state.tokenSymbol} placeholder="" onChange={(e) => { const bigNumberAmount = ethers.utils.parseUnits( e.target.value !== "" ? e.target.value : "0", tokens[state.tokenSymbol].decimals ); State.update({ amount: e.target.value, bigNumberAmount }); }} /> {state.tokenSymbol && ( <div> Balance:{" "} {ethers.utils.formatUnits( state.senderBalance, tokens[state.tokenSymbol].decimals )}{" "} {state.tokenSymbol} </div> )} </div> <div class="mb-3 col-lg-6"> <label for="selectDestinationNetwork">Select Destination Network</label> <select class="form-select" id="selectDestinationNetwork" onChange={(e) => { State.update({ destinationNetwork: e.target.value }); if (state.sourceNetwork === e.target.value) { State.update({ sourceNetwork: networks.find( (network) => network !== e.target.value ), }); } }} > <option selected={state.destinationNetwork === "aurora"} value={"aurora"} > {state.networkNames.aurora} </option> <option selected={state.destinationNetwork === "ethereum"} value={"ethereum"} > {state.networkNames.ethereum} </option> </select> </div> <div class="mb-3"> <button disabled={ !state.tokenSymbol || state.bigNumberAmount.isZero() || state.senderBalance.lt(state.bigNumberAmount) } onClick={bridgeTokens} > Bridge tokens </button> </div> <p class="col-lg-6"> NOTE: Please make sure that your wallet is compatible with the Destination Network before sending tokens. Visit rainbowbridge.app. </p> <h3> Recent transfers </h3> </> );