From 85653549e978475b93cf8af6b718a8d44625acfd Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 22 Jul 2024 11:06:09 +0300 Subject: [PATCH] fix tracking, deposit (#38) --- app/page.tsx | 13 +- components/Swap/Layout.tsx | 28 ++- components/Swap/hooks/useCrossChainFee.ts | 46 +++-- .../Swap/hooks/useDestinationAddress.ts | 4 - components/Swap/hooks/useDestinationAmount.ts | 11 +- components/Swap/hooks/useSendTransaction.ts | 169 ++++++++++-------- components/Swap/hooks/useTokenSelection.ts | 4 +- components/Swap/index.tsx | 158 ++++++++-------- components/Swap/lib/utils.ts | 21 +++ context/BalanceContext.tsx | 1 + context/CCTXsContext.tsx | 8 +- lib/utils.ts | 22 +-- package.json | 2 +- yarn.lock | 18 +- 14 files changed, 286 insertions(+), 219 deletions(-) create mode 100644 components/Swap/lib/utils.ts diff --git a/app/page.tsx b/app/page.tsx index f030afe..9950d46 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,11 +2,13 @@ import { useEffect, useState } from "react" import { useBalanceContext } from "@/context/BalanceContext" +import { useCCTXsContext } from "@/context/CCTXsContext" import { usePricesContext } from "@/context/PricesContext" import { useStakingContext } from "@/context/StakingContext" import { RefreshCw } from "lucide-react" import { useAccount } from "wagmi" +import { useZetaChainClient } from "@/hooks/useZetaChainClient" import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { Button } from "@/components/ui/button" import { Skeleton } from "@/components/ui/skeleton" @@ -36,9 +38,13 @@ const ConnectWallet = () => { ) } +const universalSwapContract = "0xb459F14260D1dc6484CE56EB0826be317171e91F" + export default function IndexPage() { + const { client } = useZetaChainClient() const { stakingDelegations } = useStakingContext() const { prices } = usePricesContext() + const { trackTransaction } = useCCTXsContext() const { balances, balancesLoading, balancesRefreshing, fetchBalances } = useBalanceContext() @@ -132,7 +138,12 @@ export default function IndexPage() { )}
- +
diff --git a/components/Swap/Layout.tsx b/components/Swap/Layout.tsx index ce9c860..adc02d8 100644 --- a/components/Swap/Layout.tsx +++ b/components/Swap/Layout.tsx @@ -29,23 +29,17 @@ interface SwapLayoutProps { sendType: string | null sourceAmount: any setSourceAmount: (value: any) => any - sourceTokenOpen: boolean - setSourceTokenOpen: (open: boolean) => void sourceTokenSelected: any balancesLoading: boolean sourceBalances: any[] setSourceToken: (token: any) => void destinationAmount: string destinationAmountIsLoading: boolean - destinationTokenOpen: boolean - setDestinationTokenOpen: (open: boolean) => void destinationTokenSelected: any destinationBalances: any[] setDestinationToken: (token: any) => void computeSendType: (sourceToken: any, destinationToken: any) => string | null addressSelected: any - customAddressOpen: boolean - setCustomAddressOpen: (open: boolean) => void canChangeAddress: boolean isAddressSelectedValid: boolean formatAddress: (address: string) => string @@ -59,8 +53,6 @@ interface SwapLayoutProps { symbol: string formatted: string } | null - isFeeOpen: boolean - setIsFeeOpen: (open: boolean) => void isRightChain: boolean handleSend: (sendType: any) => void sendDisabled: boolean @@ -76,23 +68,17 @@ const SwapLayout: React.FC = ({ sendType, sourceAmount, setSourceAmount, - sourceTokenOpen, - setSourceTokenOpen, sourceTokenSelected, balancesLoading, sourceBalances, setSourceToken, destinationAmount, destinationAmountIsLoading, - destinationTokenOpen, - setDestinationTokenOpen, destinationTokenSelected, destinationBalances, setDestinationToken, computeSendType, addressSelected, - customAddressOpen, - setCustomAddressOpen, canChangeAddress, isAddressSelectedValid, formatAddress, @@ -101,8 +87,6 @@ const SwapLayout: React.FC = ({ isCustomAddressValid, saveCustomAddress, crossChainFee, - isFeeOpen, - setIsFeeOpen, isRightChain, handleSend, sendDisabled, @@ -112,6 +96,16 @@ const SwapLayout: React.FC = ({ isLoading, pendingChainId, }) => { + const [sourceTokenOpen, setSourceTokenOpen] = useState(false) + const [destinationTokenOpen, setDestinationTokenOpen] = useState(false) + const [isFeeOpen, setIsFeeOpen] = useState(false) + const [customAddressOpen, setCustomAddressOpen] = useState(false) + + const confirmCustomAddress = () => { + saveCustomAddress() + setCustomAddressOpen(false) + } + return (

@@ -318,7 +312,7 @@ const SwapLayout: React.FC = ({ disabled={!isCustomAddressValid} size="icon" variant="outline" - onClick={saveCustomAddress} + onClick={confirmCustomAddress} > diff --git a/components/Swap/hooks/useCrossChainFee.ts b/components/Swap/hooks/useCrossChainFee.ts index 8e3ea82..c8e9ce0 100644 --- a/components/Swap/hooks/useCrossChainFee.ts +++ b/components/Swap/hooks/useCrossChainFee.ts @@ -1,19 +1,16 @@ import { useEffect, useState } from "react" -import { useFeesContext } from "@/context/FeesContext" -import { utils } from "ethers" +import { ethers, utils } from "ethers" -import { roundNumber } from "@/lib/utils" -import { useZetaChainClient } from "@/hooks/useZetaChainClient" +import { computeSendType } from "@/components/Swap/hooks/useSendType" +import { roundNumber } from "../lib/utils" import type { CrossChainFee, Token } from "./types" const useCrossChainFee = ( sourceTokenSelected: Token | null, destinationTokenSelected: Token | null, - sendType: string | null + client: any ) => { - const { fees } = useFeesContext() - const { client } = useZetaChainClient() const [crossChainFee, setCrossChainFee] = useState(null) const [loading, setLoading] = useState(false) @@ -22,10 +19,15 @@ const useCrossChainFee = ( setLoading(true) setCrossChainFee(null) try { - const fee = await getCrossChainFee( + const st = computeSendType( sourceTokenSelected, destinationTokenSelected ) + const fee = await getCrossChainFee( + sourceTokenSelected, + destinationTokenSelected, + st + ) setCrossChainFee(fee) } catch (error) { console.error("Error fetching cross-chain fee:", error) @@ -37,23 +39,35 @@ const useCrossChainFee = ( if (sourceTokenSelected && destinationTokenSelected) { fetchCrossChainFee() } - }, [sourceTokenSelected, destinationTokenSelected, sendType]) + }, [sourceTokenSelected, destinationTokenSelected]) const getCrossChainFee = async ( s: Token | null, - d: Token | null + d: Token | null, + sendType: string | null ): Promise => { if (!sendType || !s || !d) return null if (["crossChainZeta"].includes(sendType)) { - if (!fees) return null const dest = d.chain_name + console.log("feess....") + console.log("sendType", sendType) + + const API = client.getEndpoint("cosmos-http", `zeta_testnet`) + const url = `${API}/zeta-chain/crosschain/convertGasToZeta?chainId=${ + d.chain_id + }&gasLimit=${500000}` + const response = await fetch(url) + if (!response.ok) { + return null + } + const data = await response.json() + const gasFee = ethers.BigNumber.from(data.outboundGasInZeta) + const protocolFee = ethers.BigNumber.from(data.protocolFeeInZeta) + const totalFee = utils.formatUnits(gasFee.add(protocolFee), 18) + const toZetaChain = dest === "zeta_testnet" - const fee = fees["messaging"].find( - (f: { chainID: number }) => f.chainID === d.chain_id - ) - if (!fee) return null - const amount = toZetaChain ? "0" : fee.totalFee + const amount = toZetaChain ? "0" : totalFee const formatted = parseFloat(amount) === 0 ? "Fee: 0 ZETA" diff --git a/components/Swap/hooks/useDestinationAddress.ts b/components/Swap/hooks/useDestinationAddress.ts index a81f1e1..9fb09e0 100644 --- a/components/Swap/hooks/useDestinationAddress.ts +++ b/components/Swap/hooks/useDestinationAddress.ts @@ -15,7 +15,6 @@ const useDestinationAddress = ( const [customAddressSelected, setCustomAddressSelected] = useState< string | null >(null) - const [customAddressOpen, setCustomAddressOpen] = useState(false) const [isCustomAddressValid, setIsCustomAddressValid] = useState(false) useEffect(() => { @@ -64,7 +63,6 @@ const useDestinationAddress = ( if (isCustomAddressValid) { setCustomAddressSelected(customAddress) setCustomAddress(customAddress) - setCustomAddressOpen(false) } } @@ -94,8 +92,6 @@ const useDestinationAddress = ( return { addressSelected, isAddressSelectedValid, - customAddressOpen, - setCustomAddressOpen, canChangeAddress: true, customAddress, setCustomAddress, diff --git a/components/Swap/hooks/useDestinationAmount.ts b/components/Swap/hooks/useDestinationAmount.ts index 9233fb1..be8f4f6 100644 --- a/components/Swap/hooks/useDestinationAmount.ts +++ b/components/Swap/hooks/useDestinationAmount.ts @@ -1,11 +1,8 @@ import { useEffect, useState } from "react" -import { useBalanceContext } from "@/context/BalanceContext" import { utils } from "ethers" import debounce from "lodash/debounce" -import { roundNumber } from "@/lib/utils" -import { useZetaChainClient } from "@/hooks/useZetaChainClient" - +import { roundNumber } from "../lib/utils" import type { Balance, CrossChainFee, Token } from "./types" const useDestinationAmount = ( @@ -13,13 +10,13 @@ const useDestinationAmount = ( destinationTokenSelected: Token | null, sourceAmount: string, crossChainFee: CrossChainFee | null, - sendType: string | null + sendType: string | null, + balances: any, + client: any ) => { - const { client } = useZetaChainClient() const [destinationAmount, setDestinationAmount] = useState("") const [destinationAmountIsLoading, setDestinationAmountIsLoading] = useState(false) - const { balances } = useBalanceContext() useEffect(() => { setDestinationAmount("") diff --git a/components/Swap/hooks/useSendTransaction.ts b/components/Swap/hooks/useSendTransaction.ts index b4cecbd..1041196 100644 --- a/components/Swap/hooks/useSendTransaction.ts +++ b/components/Swap/hooks/useSendTransaction.ts @@ -3,12 +3,11 @@ import ERC20_ABI from "@openzeppelin/contracts/build/contracts/ERC20.json" import { ParamChainName, getAddress } from "@zetachain/protocol-contracts" import ERC20Custody from "@zetachain/protocol-contracts/abi/evm/ERC20Custody.sol/ERC20Custody.json" import WETH9 from "@zetachain/protocol-contracts/abi/zevm/WZETA.sol/WETH9.json" +import { bech32 } from "bech32" import { ethers } from "ethers" import { parseEther, parseUnits } from "viem" import { useAccount } from "wagmi" -import { useEthersSigner } from "@/hooks/useEthersSigner" - import SwapToAnyToken from "./SwapToAnyToken.json" import type { Inbound, Token } from "./types" @@ -20,13 +19,11 @@ const useSendTransaction = ( addressSelected: string, setSourceAmount: (amount: string) => void, omnichainSwapContractAddress: string, - inbounds: Inbound[], - setInbounds: (inbounds: Inbound[]) => void, bitcoinAddress: string, - client: any + client: any, + track?: any ) => { const { address } = useAccount() - const signer = useEthersSigner() const [isSending, setIsSending] = useState(false) const handleSend = async () => { @@ -104,12 +101,11 @@ const useSendTransaction = ( window.xfi.bitcoin.request( bitcoinXDEFITransfer(bitcoinAddress, bitcoinTSSAddress, a, memo), (error: any, hash: any) => { - if (!error) { - const inbound = { - inboundHash: hash, + if (!error && track) { + track({ + hash: hash, desc: `Sent ${sourceAmount} tBTC`, - } - setInbounds([...inbounds, inbound]) + }) } } ) @@ -134,19 +130,18 @@ const useSendTransaction = ( window.xfi.bitcoin.request( bitcoinXDEFITransfer(bitcoinAddress, bitcoinTSSAddress, a, memo), (error: any, hash: any) => { - if (!error) { - const inbound = { - inboundHash: hash, + if (!error && track) { + track({ + hash: hash, desc: `Sent ${a} tBTC`, - } - setInbounds([...inbounds, inbound]) + }) } } ) } m.transferNativeEVM = async () => { - await signer?.sendTransaction({ + await client.signer?.sendTransaction({ to: addressSelected, value: parseEther(sourceAmount), }) @@ -164,11 +159,12 @@ const useSendTransaction = ( recipient: address as string, amount: sourceAmount, }) - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ZETA from ${from} to ${to}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ZETA from ${from} to ${to}`, + }) } - setInbounds([...inbounds, inbound]) } m.withdrawBTC = async () => { @@ -184,11 +180,12 @@ const useSendTransaction = ( amount: sourceAmount, recipient: addressSelected, }) - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ${token} from ${from} to ${to}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${token} from ${from} to ${to}`, + }) } - setInbounds([...inbounds, inbound]) } m.wrapZeta = async () => { @@ -196,7 +193,7 @@ const useSendTransaction = ( if (!zetaTokenAddress) { throw new Error("ZetaToken address not found.") } - signer?.sendTransaction({ + client.signer?.sendTransaction({ to: zetaTokenAddress, value: parseEther(sourceAmount), }) @@ -207,8 +204,12 @@ const useSendTransaction = ( if (!zetaTokenAddress) { throw new Error("ZetaToken address not found.") } - if (signer) { - const contract = new ethers.Contract(zetaTokenAddress, WETH9.abi, signer) + if (client.signer) { + const contract = new ethers.Contract( + zetaTokenAddress, + WETH9.abi, + client.signer + ) contract.withdraw(parseEther(sourceAmount)) } } @@ -220,7 +221,7 @@ const useSendTransaction = ( const contract = new ethers.Contract( sourceTokenSelected.contract as string, ERC20_ABI.abi, - signer + client.signer ) const approve = await contract.approve( addressSelected, @@ -251,11 +252,12 @@ const useSendTransaction = ( const token = sourceTokenSelected.symbol const from = sourceTokenSelected.chain_name const dest = destinationTokenSelected.chain_name - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ${token} from ${from} to ${dest}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${token} from ${from} to ${dest}`, + }) } - setInbounds([...inbounds, inbound]) } m.depositNative = async () => { @@ -270,11 +272,12 @@ const useSendTransaction = ( amount: sourceAmount, recipient: addressSelected, }) - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ${token} from ${from} to ${to}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${token} from ${from} to ${to}`, + }) } - setInbounds([...inbounds, inbound]) } m.fromZetaChainSwapAndWithdraw = async () => { @@ -284,7 +287,7 @@ const useSendTransaction = ( const swapContract = new ethers.Contract( omnichainSwapContractAddress, SwapToAnyToken.abi, - signer + client.signer ) const amount = ethers.utils.parseUnits( sourceAmount, @@ -295,7 +298,7 @@ const useSendTransaction = ( const erc20Contract = new ethers.Contract( sourceToken as string, ERC20_ABI.abi, - signer + client.signer ) const approve = await erc20Contract.approve( omnichainSwapContractAddress, @@ -310,11 +313,12 @@ const useSendTransaction = ( recipient, true ) - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ${sourceTokenSelected.symbol} from ZetaChain to ${destinationTokenSelected.chain_name}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${sourceTokenSelected.symbol} from ZetaChain to ${destinationTokenSelected.chain_name}`, + }) } - setInbounds([...inbounds, inbound]) } m.fromZetaChainSwap = async () => { @@ -324,7 +328,7 @@ const useSendTransaction = ( const swapContract = new ethers.Contract( omnichainSwapContractAddress, SwapToAnyToken.abi, - signer + client.signer ) const amount = ethers.utils.parseUnits( sourceAmount, @@ -335,7 +339,7 @@ const useSendTransaction = ( const erc20Contract = new ethers.Contract( sourceToken as string, ERC20_ABI.abi, - signer + client.signer ) const approve = await erc20Contract.approve( omnichainSwapContractAddress, @@ -363,7 +367,7 @@ const useSendTransaction = ( const custodyContract = new ethers.Contract( custodyAddress as string, ERC20Custody.abi, - signer + client.signer ) const assetAddress = sourceTokenSelected.contract const amount = ethers.utils.parseUnits( @@ -374,7 +378,7 @@ const useSendTransaction = ( const contract = new ethers.Contract( assetAddress as string, ERC20_ABI.abi, - signer + client.signer ) await (await contract.approve(custodyAddress, amount)).wait() const tx = await custodyContract.deposit( @@ -387,11 +391,12 @@ const useSendTransaction = ( const token = sourceTokenSelected.symbol const from = sourceTokenSelected.chain_name const dest = destinationTokenSelected.chain_name - const inbound = { - inboundHash: tx.hash, - desc: `Sent ${sourceAmount} ${token} from ${from} to ${dest}`, + if (track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${token} from ${from} to ${dest}`, + }) } - setInbounds([...inbounds, inbound]) } catch (error) { console.error("Error during deposit: ", error) } @@ -410,37 +415,45 @@ const useSendTransaction = ( } const crossChainSwapHandle = async (withdraw: boolean) => { - if (!address) { - console.error("EVM address undefined.") + if (!sourceTokenSelected || !destinationTokenSelected) { return } - if (!bitcoinAddress) { - console.error("Bitcoin address undefined.") - return + + const tiker = sourceTokenSelected.ticker + const from = sourceTokenSelected.chain_name + const dest = destinationTokenSelected.chain_name + + let recipient + try { + if (bech32.decode(addressSelected)) { + recipient = ethers.utils.solidityPack( + ["bytes"], + [ethers.utils.toUtf8Bytes(addressSelected)] + ) + } + } catch (e) { + recipient = addressSelected } - if (!destinationTokenSelected) { - console.error("Destination token not selected.") - return + const d = destinationTokenSelected + const zrc20 = d.coin_type === "ZRC20" ? d.contract : d.zrc20 + const params = { + chain: from, + amount: sourceAmount, + recipient: omnichainSwapContractAddress, + message: [ + ["address", "bytes", "bool"], + [zrc20, recipient, withdraw], + ], + erc20: sourceTokenSelected.contract, + } + const tx = await client.deposit(params) + + if (tx && track) { + track({ + hash: tx.hash, + desc: `Sent ${sourceAmount} ${tiker} from ${from} to ${dest}`, + }) } - const a = parseFloat(sourceAmount) * 1e8 - const bitcoinTSSAddress = "tb1qy9pqmk2pd9sv63g27jt8r657wy0d9ueeh0nqur" - const contract = omnichainSwapContractAddress.replace(/^0x/, "") - const zrc20 = destinationTokenSelected.zrc20?.replace(/^0x/, "") - const dest = address.replace(/^0x/, "") - const withdrawFlag = withdraw ? "00" : "01" - const memo = `hex::${contract}${zrc20}${dest}${withdrawFlag}` - window.xfi.bitcoin.request( - bitcoinXDEFITransfer(bitcoinAddress, bitcoinTSSAddress, a, memo), - (error: any, hash: any) => { - if (!error) { - const inbound = { - inboundHash: hash, - desc: `Sent ${sourceAmount} tBTC`, - } - setInbounds([...inbounds, inbound]) - } - } - ) } m.crossChainSwapBTC = async () => crossChainSwapHandle(true) diff --git a/components/Swap/hooks/useTokenSelection.ts b/components/Swap/hooks/useTokenSelection.ts index 5935013..bb7d1c7 100644 --- a/components/Swap/hooks/useTokenSelection.ts +++ b/components/Swap/hooks/useTokenSelection.ts @@ -1,10 +1,8 @@ import { useEffect, useState } from "react" -import { useBalanceContext } from "@/context/BalanceContext" import type { Balance, Token } from "./types" -const useTokenSelection = () => { - const { balances, bitcoinAddress } = useBalanceContext() +const useTokenSelection = (balances: any, bitcoinAddress: string) => { const [sourceToken, setSourceToken] = useState() const [sourceTokenSelected, setSourceTokenSelected] = useState( null diff --git a/components/Swap/index.tsx b/components/Swap/index.tsx index 1bc1adf..15743ad 100644 --- a/components/Swap/index.tsx +++ b/components/Swap/index.tsx @@ -1,44 +1,69 @@ "use client" import { useEffect, useState } from "react" -import { useBalanceContext } from "@/context/BalanceContext" -import { useCCTXsContext } from "@/context/CCTXsContext" import { useAccount, useNetwork, useSwitchNetwork } from "wagmi" -import { formatAddress } from "@/lib/utils" -import { useZetaChainClient } from "@/hooks/useZetaChainClient" -import useSendType, { - computeSendType, - sendTypeDetails, -} from "@/components/Swap/hooks/useSendType" -import useTokenSelection from "@/components/Swap/hooks/useTokenSelection" - import SwapLayout from "./Layout" import useAmountValidation from "./hooks/useAmountValidation" import useCrossChainFee from "./hooks/useCrossChainFee" import useDestinationAddress from "./hooks/useDestinationAddress" import useDestinationAmount from "./hooks/useDestinationAmount" import useSendTransaction from "./hooks/useSendTransaction" +import useSendType, { + computeSendType, + sendTypeDetails, +} from "./hooks/useSendType" import useSwapErrors from "./hooks/useSwapErrors" +import useTokenSelection from "./hooks/useTokenSelection" +import { formatAddress } from "./lib/utils" + +interface SwapProps { + contract: string + client: any + track?: any + balances?: any +} -const omnichainSwapContractAddress = - "0xb459F14260D1dc6484CE56EB0826be317171e91F" - -const Swap = () => { - const { client } = useZetaChainClient() +const Swap: React.FC = ({ + contract, + track, + balances: balancesProp, + client, +}) => { const { isLoading, pendingChainId, switchNetwork } = useSwitchNetwork() - const { setInbounds, inbounds } = useCCTXsContext() - const { balancesLoading, bitcoinAddress } = useBalanceContext() const { chain } = useNetwork() const { address } = useAccount() + const bitcoinAddress = "" // temporary + const [sourceAmount, setSourceAmount] = useState("") - const [sourceTokenOpen, setSourceTokenOpen] = useState(false) - const [destinationTokenOpen, setDestinationTokenOpen] = useState(false) const [isRightChain, setIsRightChain] = useState(true) - const [isFeeOpen, setIsFeeOpen] = useState(false) const [sendButtonText, setSendButtonText] = useState("Send tokens") + const [balances, setBalances] = useState(balancesProp || []) + const [balancesLoading, setBalancesLoading] = useState(true) + + useEffect(() => { + const fetchBalances = async () => { + setBalancesLoading(true) + try { + const result = await client.getBalances({ evmAddress: address }) + setBalancesLoading(result) + } catch (error) { + console.error("Error fetching local balances:", error) + } finally { + setBalancesLoading(false) + } + } + + if (balancesProp) { + setBalances(balancesProp) + setBalancesLoading(false) + } else { + fetchBalances() + } + }, [balancesProp]) + const { setSourceToken, sourceTokenSelected, @@ -46,14 +71,14 @@ const Swap = () => { setDestinationToken, destinationTokenSelected, destinationBalances, - } = useTokenSelection() + } = useTokenSelection(balances, bitcoinAddress) const sendType = useSendType(sourceTokenSelected, destinationTokenSelected) const { crossChainFee } = useCrossChainFee( sourceTokenSelected, destinationTokenSelected, - sendType + client ) const { isAmountGTFee, isAmountLTBalance } = useAmountValidation( @@ -69,7 +94,9 @@ const Swap = () => { destinationTokenSelected, sourceAmount, crossChainFee, - sendType + sendType, + balances, + client ) const { priorityErrors } = useSwapErrors( @@ -85,8 +112,6 @@ const Swap = () => { const { addressSelected, isAddressSelectedValid, - customAddressOpen, - setCustomAddressOpen, canChangeAddress, customAddress, setCustomAddress, @@ -101,11 +126,10 @@ const Swap = () => { sourceAmount, addressSelected, setSourceAmount, - omnichainSwapContractAddress, - inbounds, - setInbounds, + contract, bitcoinAddress, - client + client, + track ) const sendDisabled = @@ -146,47 +170,41 @@ const Swap = () => { } return ( - +
+ +
) } diff --git a/components/Swap/lib/utils.ts b/components/Swap/lib/utils.ts new file mode 100644 index 0000000..899871f --- /dev/null +++ b/components/Swap/lib/utils.ts @@ -0,0 +1,21 @@ +export const roundNumber = (value: number): number => { + const roundToSignificantDigits = ( + value: number, + significantDigits: number + ): number => { + if (value === 0) return 0 + const digits = + -Math.floor(Math.log10(Math.abs(value))) + (significantDigits - 1) + const factor = 10 ** digits + return Math.round(value * factor) / factor + } + + if (value >= 1) { + return parseFloat(value.toFixed(1)) + } + return roundToSignificantDigits(value, 2) +} + +export const formatAddress = (address: any) => { + return `${address.slice(0, 4)}...${address.slice(-4)}` +} diff --git a/context/BalanceContext.tsx b/context/BalanceContext.tsx index 83e0391..57b3bc4 100644 --- a/context/BalanceContext.tsx +++ b/context/BalanceContext.tsx @@ -34,6 +34,7 @@ export const BalanceProvider = ({ if (!isConnected) { return setBalances([]) } + console.log("FETCHING BALANCES...") const b = await client.getBalances({ evmAddress: address, btcAddress: btc, diff --git a/context/CCTXsContext.tsx b/context/CCTXsContext.tsx index 12d60fa..39d635d 100644 --- a/context/CCTXsContext.tsx +++ b/context/CCTXsContext.tsx @@ -28,6 +28,10 @@ export const CCTXsProvider = ({ children }: { children: React.ReactNode }) => { }) } + const trackTransaction = ({ hash, desc }: { hash: string; desc: string }) => { + setInbounds([...inbounds, { inboundHash: hash, desc }]) + } + useEffect(() => { const cctxList = cctxs.map((c: any) => c.inboundHash) for (let i of inbounds) { @@ -77,14 +81,14 @@ export const CCTXsProvider = ({ children }: { children: React.ReactNode }) => { }) }) - client.trackCCTX(i.inboundHash, false, emitter) + client.trackCCTX({ hash: i.inboundHash, json: false, emitter }) setCCTXs([...cctxs, { inboundHash: i.inboundHash, desc: i.desc }]) } } }, [inbounds]) return ( - + {children} ) diff --git a/lib/utils.ts b/lib/utils.ts index 86e1cc7..3f98e70 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -5,18 +5,18 @@ export const cn = (...inputs: ClassValue[]) => { return twMerge(clsx(inputs)) } -export const roundToSignificantDigits = ( - value: number, - significantDigits: number -): number => { - if (value === 0) return 0 - const digits = - -Math.floor(Math.log10(Math.abs(value))) + (significantDigits - 1) - const factor = 10 ** digits - return Math.round(value * factor) / factor -} - export const roundNumber = (value: number): number => { + const roundToSignificantDigits = ( + value: number, + significantDigits: number + ): number => { + if (value === 0) return 0 + const digits = + -Math.floor(Math.log10(Math.abs(value))) + (significantDigits - 1) + const factor = 10 ** digits + return Math.round(value * factor) / factor + } + if (value >= 1) { return parseFloat(value.toFixed(1)) } diff --git a/package.json b/package.json index 9bb68e3..d9ce559 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@uniswap/v3-core": "^1.0.1", "@uniswap/v3-sdk": "^3.10.0", "@zetachain/example-contracts": "1.0.0-rc1", - "@zetachain/toolkit": "11.0.0-rc1", + "@zetachain/toolkit": "11.0.0-rc2", "bech32": "^2.0.0", "class-variance-authority": "^0.4.0", "clsx": "^1.2.1", diff --git a/yarn.lock b/yarn.lock index aa86963..2ff7eda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3664,10 +3664,10 @@ typescript "5.0.4" zod "3.19.1" -"@zetachain/networks@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@zetachain/networks/-/networks-7.0.0.tgz#a5f8a188d633e2064ee7c77499351381ba891441" - integrity sha512-/amSq+KNJe+EGj0ioZS+DZJtsnbPSDotp9LsrAbaEVMAxKvBK/XkvggH73sJyRWWeMpfhHrNPlrKTLrN+mRkIg== +"@zetachain/networks@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@zetachain/networks/-/networks-8.0.0.tgz#3e838bb6b14e4a8d381f95b4cbc2f1172e851e4e" + integrity sha512-I0HhH5qOGW0Jkjq5o5Mi6qGls6ycHnhWjc+r+Ud8u8YW+HU4lEUn4gvulxj+ccHKj3nV/0gEsmNrWRY9ct49nQ== dependencies: dotenv "^16.1.4" @@ -3676,10 +3676,10 @@ resolved "https://registry.yarnpkg.com/@zetachain/protocol-contracts/-/protocol-contracts-7.0.0.tgz#20eb6c62d805d7470408ccdff0e3614684bca174" integrity sha512-8JTNFZxVZYmDtAXJIEr+tkakuML12X42Fya4bJ1NkfWiVMkcSej92BSTl/35qYtHdjY7vXy9uMrfXEqfw5rsPw== -"@zetachain/toolkit@11.0.0-rc1": - version "11.0.0-rc1" - resolved "https://registry.yarnpkg.com/@zetachain/toolkit/-/toolkit-11.0.0-rc1.tgz#06f1e0daf8d4ed79ca080bf07c1e1b48d987b04b" - integrity sha512-RW7PnabX4R3Qsx7i8M+CcyybgNXC94TfokjHZhLc1bzk/vZOPnQdHiOZvUs6wMLZ/simzTl1WDCnAdxTaKuLlw== +"@zetachain/toolkit@11.0.0-rc2": + version "11.0.0-rc2" + resolved "https://registry.yarnpkg.com/@zetachain/toolkit/-/toolkit-11.0.0-rc2.tgz#5be95e232a76042b805d9bffb63a5d3ca941ff37" + integrity sha512-HwgwJOJfGYcImJz228qc9L5P41sAnTOgp+cNyasJ/4RVQLrk+cCtvhV/ROfvKu1dmC98Npt6dfqaFXOfa/xJcw== dependencies: "@inquirer/prompts" "^2.1.1" "@inquirer/select" "1.1.3" @@ -3687,7 +3687,7 @@ "@openzeppelin/contracts" "^4.9.6" "@uniswap/v2-periphery" "^1.1.0-beta.0" "@zetachain/faucet-cli" "^4.0.1" - "@zetachain/networks" "7.0.0" + "@zetachain/networks" "^8.0.0" "@zetachain/protocol-contracts" "7.0.0" axios "^1.4.0" bech32 "^2.0.0"