diff --git a/src/components/UnwrapNative.tsx b/src/components/UnwrapNative.tsx index 06042dc98..951d26e3e 100644 --- a/src/components/UnwrapNative.tsx +++ b/src/components/UnwrapNative.tsx @@ -9,6 +9,7 @@ import { CHAIN_ID_NEON, CHAIN_ID_OASIS, CHAIN_ID_POLYGON, + CHAIN_ID_BASE, ethers_contracts, } from "@certusone/wormhole-sdk"; import { @@ -26,6 +27,7 @@ import { useCallback, useEffect, useState } from "react"; import { useEthereumProvider } from "../contexts/EthereumProviderContext"; import useIsWalletReady from "../hooks/useIsWalletReady"; import arbitrumIcon from "../icons/arbitrum.svg"; +import baseIcon from "../icons/base.svg"; import avaxIcon from "../icons/avax.svg"; import bnbIcon from "../icons/bnb.svg"; import ethIcon from "../icons/eth.svg"; @@ -64,6 +66,8 @@ import { WNEON_DECIMALS, WROSE_ADDRESS, WROSE_DECIMALS, + BASE_WETH_ADDRESS, + BASE_WETH_DECIMALS } from "../utils/consts"; import parseError from "../utils/parseError"; import ButtonWithLoader from "./ButtonWithLoader"; @@ -164,6 +168,12 @@ const supportedTokens = { address: ARBWETH_ADDRESS, decimals: ARBWETH_DECIMALS, }, + [CHAIN_ID_BASE]: { + symbol: "WETH", + icon: baseIcon, + address: BASE_WETH_ADDRESS, + decimals: BASE_WETH_DECIMALS, + } } as const; type SupportedChain = keyof typeof supportedTokens; diff --git a/src/hooks/useGetSourceParsedTokenAccounts.ts b/src/hooks/useGetSourceParsedTokenAccounts.ts index f7bf6d825..94e02f8be 100644 --- a/src/hooks/useGetSourceParsedTokenAccounts.ts +++ b/src/hooks/useGetSourceParsedTokenAccounts.ts @@ -26,6 +26,7 @@ import { CHAIN_ID_INJECTIVE, CHAIN_ID_SUI, CHAIN_ID_ARBITRUM, + CHAIN_ID_BASE, } from "@certusone/wormhole-sdk"; import { Dispatch } from "@reduxjs/toolkit"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; @@ -53,6 +54,7 @@ import acalaIcon from "../icons/acala.svg"; import arbitrumIcon from "../icons/arbitrum.svg"; import auroraIcon from "../icons/aurora.svg"; import avaxIcon from "../icons/avax.svg"; +import baseIcon from "../icons/base.svg"; import bnbIcon from "../icons/bnb.svg"; import celoIcon from "../icons/celo.svg"; import ethIcon from "../icons/eth.svg"; @@ -130,10 +132,12 @@ import { WNEON_DECIMALS, WROSE_ADDRESS, WROSE_DECIMALS, - CLUSTER, - SUI_NATIVE_TOKEN_KEY, ARBWETH_ADDRESS, ARBWETH_DECIMALS, + BASE_WETH_ADDRESS, + BASE_WETH_DECIMALS, + CLUSTER, + SUI_NATIVE_TOKEN_KEY, } from "../utils/consts"; import { makeNearAccount } from "../utils/near"; import { @@ -291,6 +295,29 @@ const createNativeEthParsedTokenAccount = ( }); }; +const createNativeBaseParsedTokenAccount = ( + provider: Provider, + signerAddress: string | undefined +) => { + return !(provider && signerAddress) + ? Promise.reject() + : provider.getBalance(signerAddress).then((balanceInWei) => { + const balanceInEth = ethers.utils.formatEther(balanceInWei); + return createParsedTokenAccount( + signerAddress, //public key + BASE_WETH_ADDRESS, //Mint key, On the other side this will be WETH, so this is hopefully a white lie. + balanceInWei.toString(), //amount, in wei + BASE_WETH_DECIMALS, //Luckily both ETH and WETH have 18 decimals, so this should not be an issue. + parseFloat(balanceInEth), //This loses precision, but is a limitation of the current datamodel. This field is essentially deprecated + balanceInEth.toString(), //This is the actual display field, which has full precision. + "baseETH", //A white lie for display purposes + "Base Ethereum", //A white lie for display purposes + baseIcon, + true //isNativeAsset + ); + }); +}; + const createNativeBscParsedTokenAccount = ( provider: Provider, signerAddress: string | undefined @@ -1355,6 +1382,40 @@ function useGetAvailableTokens(nft: boolean = false) { }; }, [lookupChain, provider, signerAddress, nft, ethNativeAccount]); + //Base native asset load + useEffect(() => { + let cancelled = false; + if ( + signerAddress && + lookupChain === CHAIN_ID_BASE && + !ethNativeAccount && + !nft + ) { + setEthNativeAccountLoading(true); + createNativeBaseParsedTokenAccount(provider, signerAddress).then( + (result) => { + console.log("create native account returned with value", result); + if (!cancelled) { + setEthNativeAccount(result); + setEthNativeAccountLoading(false); + setEthNativeAccountError(""); + } + }, + (error) => { + if (!cancelled) { + setEthNativeAccount(undefined); + setEthNativeAccountLoading(false); + setEthNativeAccountError("Unable to retrieve your ETH balance."); + } + } + ); + } + + return () => { + cancelled = true; + }; + }, [lookupChain, provider, signerAddress, nft, ethNativeAccount]); + //Binance Smart Chain native asset load useEffect(() => { let cancelled = false; diff --git a/src/utils/consts.ts b/src/utils/consts.ts index 5eefcbbbe..05a55c2a6 100644 --- a/src/utils/consts.ts +++ b/src/utils/consts.ts @@ -1360,6 +1360,14 @@ export const WETH_ADDRESS = : "0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E"; export const WETH_DECIMALS = 18; +export const BASE_WETH_ADDRESS = + CLUSTER === "mainnet" + ? "0x4200000000000000000000000000000000000006" + : CLUSTER === "testnet" + ? "0x4200000000000000000000000000000000000006" + : "0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E"; +export const BASE_WETH_DECIMALS = 18; + export const WBNB_ADDRESS = CLUSTER === "mainnet" ? "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"