From e0beb04254ea607497d6b996f029bdc5efef4479 Mon Sep 17 00:00:00 2001 From: rustin01 <141540002+rustin01@users.noreply.github.com> Date: Sun, 20 Oct 2024 12:25:01 +0800 Subject: [PATCH] Feat/improve send token (#175) --- apps/wallet/src/components/TokenList.tsx | 2 +- .../src/pages/send-token/confirm-page.tsx | 24 ++++--------------- apps/wallet/src/pages/send-token/index.tsx | 10 +++++--- apps/wallet/src/pages/send-token/store.ts | 21 ++++++++++++++++ apps/wallet/src/pages/token-detail/index.tsx | 2 +- .../chain/chain-wallets/dfinity/index.ts | 15 ++++++++++-- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/apps/wallet/src/components/TokenList.tsx b/apps/wallet/src/components/TokenList.tsx index 345adf11..d5afcb55 100644 --- a/apps/wallet/src/components/TokenList.tsx +++ b/apps/wallet/src/components/TokenList.tsx @@ -20,7 +20,7 @@ const TokenListItem: FC<{ token: RootAssetInfo }> = ({ token }) => { >
- {balanceQuery.isFetching ? ( + {balanceQuery.isLoading ? ( ) : ( {balanceQuery.data?.toString() ?? '0'} diff --git a/apps/wallet/src/pages/send-token/confirm-page.tsx b/apps/wallet/src/pages/send-token/confirm-page.tsx index 677faada..fb469b29 100644 --- a/apps/wallet/src/pages/send-token/confirm-page.tsx +++ b/apps/wallet/src/pages/send-token/confirm-page.tsx @@ -10,7 +10,7 @@ import BigNumber from "bignumber.js"; import toaster from "../../components/Toaster"; import { useMutation, useQuery } from "@tanstack/react-query"; import CopyButton from "../../components/CopyButton"; -import { sendTokenStore } from "./store"; +import { sendTokenStore, useFeeQuery } from "./store"; import { formatNumber } from "../../utils/formatter"; import { ChainAssetType } from "../../utils/basicTypes"; import { getChainTxLink } from "../../utils/link"; @@ -33,20 +33,7 @@ const SendTokenConfirmPage: FC = observer(() => { enabled: !!tokenListQuery.data }) const nativeBalanceQuery = useTokenBalanceQuery(nativeTokenQuery.data || undefined) - const feeQuery = useQuery({ - queryKey: ['estimatedFee', state], - queryFn: async () => { - if (!hibitIdSession.walletPool || !state.token) { - return null - } - return await hibitIdSession.walletPool.getEstimatedFee( - state.toAddress, - new BigNumber(state.amount), - state.token, - ) - }, - refetchInterval: 5000, - }) + const feeQuery = useFeeQuery(state.toAddress, state.amount, state.token) const minNativeBalance = useMemo(() => { if (!feeQuery.data || !state.token) { @@ -55,7 +42,7 @@ const SendTokenConfirmPage: FC = observer(() => { if (state.token.chainAssetType.equals(ChainAssetType.Native)) { return new BigNumber(state.amount).plus(feeQuery.data) } else { - return feeQuery.data + return hibitIdSession.chainInfo.feeTokenType === 'native' ? feeQuery.data : new BigNumber(0) } }, [state, feeQuery.data]) @@ -180,12 +167,9 @@ const SendTokenConfirmPage: FC = observer(() => {
- {!feeQuery.isPending ? ( + {!feeQuery.isLoading ? ( ~{formatNumber(feeQuery.data)} - {feeQuery.isFetching && ( - - )} ) : ( diff --git a/apps/wallet/src/pages/send-token/index.tsx b/apps/wallet/src/pages/send-token/index.tsx index 42b8ee89..1250b7d4 100644 --- a/apps/wallet/src/pages/send-token/index.tsx +++ b/apps/wallet/src/pages/send-token/index.tsx @@ -13,7 +13,7 @@ import { walletAddressValidate } from "../../utils/validator"; import { yupResolver } from "@hookform/resolvers/yup"; import { Controller, useForm } from "react-hook-form"; import { SYSTEM_MAX_DECIMALS } from "../../utils/formatter/numberFormatter"; -import { sendTokenStore } from "./store"; +import { sendTokenStore, useFeeQuery } from "./store"; import PageHeader from "../../components/PageHeader"; import { useTranslation } from "react-i18next"; @@ -60,6 +60,7 @@ const SendTokenPage: FC = observer(() => { control, handleSubmit, formState: { errors }, + watch, } = useForm({ defaultValues: { toAddress: state.toAddress || '', @@ -68,6 +69,9 @@ const SendTokenPage: FC = observer(() => { resolver: yupResolver(formSchema), mode: 'onChange' }) + const values = watch() + + useFeeQuery(values.toAddress, values.amount, token) useEffect(() => { if (state.token) { @@ -84,7 +88,7 @@ const SendTokenPage: FC = observer(() => { setState({ toAddress, token, - amount + amount, }) navigate('/send/confirm') }) @@ -127,7 +131,7 @@ const SendTokenPage: FC = observer(() => { }} > {t('common_max')}: - {balanceQuery.isFetching ? ( + {balanceQuery.isLoading ? ( ) : ( {formatNumber(balanceQuery.data || 0)} diff --git a/apps/wallet/src/pages/send-token/store.ts b/apps/wallet/src/pages/send-token/store.ts index e62c1edc..b4ae7b5b 100644 --- a/apps/wallet/src/pages/send-token/store.ts +++ b/apps/wallet/src/pages/send-token/store.ts @@ -1,5 +1,8 @@ +import BigNumber from "bignumber.js"; import { RootAssetInfo } from "../../apis/models"; import { makeAutoObservable } from "mobx"; +import { useQuery } from "@tanstack/react-query"; +import hibitIdSession from "../../stores/session"; export interface SendTokenState { token: RootAssetInfo | null @@ -32,3 +35,21 @@ export class SendTokenStore { } export const sendTokenStore = new SendTokenStore() + +export const useFeeQuery = (toAddress: string, amount: string, token: RootAssetInfo | null) => { + return useQuery({ + queryKey: ['estimatedFee', toAddress, amount, token], + queryFn: async () => { + if (!hibitIdSession.walletPool || !token) { + return null + } + return await hibitIdSession.walletPool.getEstimatedFee( + toAddress, + new BigNumber(amount), + token, + ) + }, + staleTime: 10000, + refetchInterval: 5000, + }) +} diff --git a/apps/wallet/src/pages/token-detail/index.tsx b/apps/wallet/src/pages/token-detail/index.tsx index eee818b8..59bac459 100644 --- a/apps/wallet/src/pages/token-detail/index.tsx +++ b/apps/wallet/src/pages/token-detail/index.tsx @@ -43,7 +43,7 @@ const TokenDetailPage: FC = observer(() => {
- {balanceQuery.isFetching ? ( + {balanceQuery.isLoading ? ( ) : ( {`${formatNumber(balanceQuery.data)} ${token.assetSymbol}`} diff --git a/apps/wallet/src/utils/chain/chain-wallets/dfinity/index.ts b/apps/wallet/src/utils/chain/chain-wallets/dfinity/index.ts index a608edd0..1808b2b4 100644 --- a/apps/wallet/src/utils/chain/chain-wallets/dfinity/index.ts +++ b/apps/wallet/src/utils/chain/chain-wallets/dfinity/index.ts @@ -20,6 +20,7 @@ export class DfinityChainWallet extends BaseChainWallet { private identity: Secp256k1KeyIdentity | null = null private agent: HttpAgent | null = null private readyPromise: Promise + private feeCache: Record = {} constructor(chainInfo: ChainInfo, phrase: string) { if (!chainInfo.chainId.type.equals(Chain.Dfinity)) { @@ -122,17 +123,27 @@ export class DfinityChainWallet extends BaseChainWallet { // native if (assetInfo.chainAssetType.equals(ChainAssetType.Native)) { + if (this.feeCache['native']) { + return this.feeCache['native'] + } const ledger = this.getIcpLedger() const fee = await ledger.transactionFee() - return new BigNumber(String(fee)).shiftedBy(-assetInfo.decimalPlaces.value) + const result = new BigNumber(String(fee)).shiftedBy(-assetInfo.decimalPlaces.value) + this.feeCache['native'] = result + return result } // ICRC if (assetInfo.chainAssetType.equals(ChainAssetType.ICRC1)) { + if (this.feeCache[assetInfo.contractAddress]) { + return this.feeCache[assetInfo.contractAddress] + } const ledger = this.getIcrcLedger(assetInfo.contractAddress) const fee = await ledger.transactionFee({}) const decimals = assetInfo.decimalPlaces?.value ?? (await this.getIcrcDecimals(ledger)) - return new BigNumber(String(fee)).shiftedBy(-decimals) + const result = new BigNumber(String(fee)).shiftedBy(-decimals) + this.feeCache[assetInfo.contractAddress] = result + return result } throw new Error(`Dfinity: unsupported chain asset type ${assetInfo.chainAssetType.toString()}`);