diff --git a/apps/namadillo/package.json b/apps/namadillo/package.json index 45988b06e8..b26009def2 100644 --- a/apps/namadillo/package.json +++ b/apps/namadillo/package.json @@ -12,7 +12,7 @@ "@keplr-wallet/types": "^0.12.136", "@namada/chain-registry": "^1.5.2", "@namada/indexer-client": "4.0.5", - "@namada/sdk-multicore": "0.23.0-beta.1", + "@namada/sdk-multicore": "file:.yalc/@namada/sdk-multicore", "@tailwindcss/container-queries": "^0.1.1", "@tanstack/query-core": "^5.40.0", "@tanstack/react-query": "^5.40.0", diff --git a/apps/namadillo/src/App/Common/TransactionFee.tsx b/apps/namadillo/src/App/Common/TransactionFee.tsx index 9ebfa58017..a0a61623be 100644 --- a/apps/namadillo/src/App/Common/TransactionFee.tsx +++ b/apps/namadillo/src/App/Common/TransactionFee.tsx @@ -6,12 +6,14 @@ type TransactionFeeProps = { displayAmount: BigNumber; symbol: string; compact?: boolean; + isLoading?: boolean; }; export const TransactionFee = ({ displayAmount, symbol, compact = false, + isLoading = false, }: TransactionFeeProps): JSX.Element => { return (
@@ -24,11 +26,21 @@ export const TransactionFee = ({ > {compact ? "Fee:" : "Transaction Fee"} - + {isLoading ? +
+ : + }
); }; diff --git a/apps/namadillo/src/App/Common/TransactionFeeButton.tsx b/apps/namadillo/src/App/Common/TransactionFeeButton.tsx index 05141011c7..45e2546d91 100644 --- a/apps/namadillo/src/App/Common/TransactionFeeButton.tsx +++ b/apps/namadillo/src/App/Common/TransactionFeeButton.tsx @@ -14,11 +14,13 @@ export const TransactionFeeButton = ({ className, isShieldedTransfer = false, compact = false, + isLoading = false, }: { feeProps: TransactionFeeProps; className?: string; isShieldedTransfer?: boolean; compact?: boolean; + isLoading?: boolean; }): JSX.Element => { const [modalOpen, setModalOpen] = useState(false); @@ -45,6 +47,7 @@ export const TransactionFeeButton = ({ compact={compact} displayAmount={gasDisplayAmount?.totalDisplayAmount || BigNumber(0)} symbol={(!compact && gasDisplayAmount?.asset.symbol) || ""} + isLoading={isLoading} />
{!compact &&
Fees:
} diff --git a/apps/namadillo/src/App/Staking/IncrementBonding.tsx b/apps/namadillo/src/App/Staking/IncrementBonding.tsx index 9a9fcbd88f..c730d12627 100644 --- a/apps/namadillo/src/App/Staking/IncrementBonding.tsx +++ b/apps/namadillo/src/App/Staking/IncrementBonding.tsx @@ -12,7 +12,9 @@ import { accountBalanceAtom, defaultAccountAtom } from "atoms/accounts"; import { chainParametersAtom } from "atoms/chain"; import { createBondTxAtom } from "atoms/staking"; import { allValidatorsAtom } from "atoms/validators"; +import BigNumber from "bignumber.js"; import clsx from "clsx"; +import { useDryRunGas } from "hooks/useDryRunGas"; import { useStakeModule } from "hooks/useStakeModule"; import { useTransaction } from "hooks/useTransaction"; import { useValidatorFilter } from "hooks/useValidatorFilter"; @@ -92,6 +94,23 @@ const IncrementBonding = (): JSX.Element => { }, }); + const gasQuery = useDryRunGas( + createBondTxAtom, + parseUpdatedAmounts(), + "tpknam1qpf0urw04xpqdu6pt0k0pe9f8krv3j6j4jj57t8vvmqqcxxa9vc3gpk3xgf" + ); + + const feePropsModified = { + ...feeProps, + gasConfig: { + ...feeProps.gasConfig, + gasLimit: + gasQuery.data ? + BigNumber(gasQuery.data.toString()) + : feeProps.gasConfig.gasLimit, + }, + }; + const filteredValidators = useValidatorFilter({ validators: validators.isSuccess ? validators.data : [], myValidatorsAddresses: Array.from( @@ -224,6 +243,7 @@ const IncrementBonding = (): JSX.Element => {
+ DUPA: {gasQuery.data?.toString() ?? "no data"} { {isPerformingBonding ? "Processing..." : errorMessage || "Stake"}
- +
diff --git a/apps/namadillo/src/hooks/useDryRunGas.tsx b/apps/namadillo/src/hooks/useDryRunGas.tsx new file mode 100644 index 0000000000..d6301cc11b --- /dev/null +++ b/apps/namadillo/src/hooks/useDryRunGas.tsx @@ -0,0 +1,56 @@ +import { useDebounce } from "@namada/hooks"; +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import { defaultAccountAtom } from "atoms/accounts"; +import BigNumber from "bignumber.js"; +import invariant from "invariant"; +import { Atom, useAtomValue } from "jotai"; +import { AtomWithMutationResult } from "jotai-tanstack-query"; +import { dryRunTransaction, EncodedTxData } from "lib/query"; +import { BuildTxAtomParams } from "types"; +import { useTransactionFee } from "./useTransactionFee"; + +//TODO: reuse +type AtomType = Atom< + AtomWithMutationResult< + EncodedTxData | undefined, + unknown, + BuildTxAtomParams, + unknown + > +>; + +export const useDryRunGas = ( + createTxAtom: AtomType, + params: T[], + publicKey: string +): UseQueryResult => { + const { mutateAsync: performBuildTx } = useAtomValue(createTxAtom); + const { data: account } = useAtomValue(defaultAccountAtom); + // TODO: we only do this to get gasToken + const feeProps = useTransactionFee(["TransparentTransfer"], false); + const gasConfig = { ...feeProps.gasConfig, gasLimit: BigNumber(500_000) }; // set high gas limit for dry run}; + const paramsDebounced = useDebounce(JSON.stringify(params), 1000); + + const transactionQuery = useQuery({ + queryKey: ["dry-run-gas", gasConfig.gasToken, paramsDebounced], + enabled: params.length > 0, + queryFn: async () => { + invariant(account, "Default account is not set"); + const variables = { + params, + gasConfig, + account, + //TODO: do we need additionalParams for gas? + // ...txAdditionalParams, + }; + + const encodedTxData = await performBuildTx(variables); + const txsBytes = encodedTxData?.txs.map((tx) => tx.bytes); + const gas = await dryRunTransaction(txsBytes!, publicKey); + + return gas; + }, + }); + + return transactionQuery; +}; diff --git a/apps/namadillo/src/lib/query.ts b/apps/namadillo/src/lib/query.ts index 2e09dc6bf3..5cc9da704c 100644 --- a/apps/namadillo/src/lib/query.ts +++ b/apps/namadillo/src/lib/query.ts @@ -209,6 +209,26 @@ export const broadcastTransaction = async ( return response; }; +export const dryRunTransaction = async ( + signedTxs: Uint8Array[], + publicKey: string +): Promise => { + const { rpc } = await getSdkInstance(); + const response = await Promise.allSettled( + signedTxs.map((tx) => rpc.dryRunTx(tx, publicKey)) + ); + + const gas = response.reduce((acc, res) => { + if (res.status === "fulfilled") { + // TODO: + acc += res.value as unknown as bigint; + } + return acc; + }, BigInt(0)); + + return gas; +}; + // We use this to prevent dispatching events for transfer events // as they are handled by useTransactionWatcher export const isTransferEventType = ( diff --git a/yarn.lock b/yarn.lock index eb793f0c18..6f40643dd2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3772,7 +3772,7 @@ __metadata: "@keplr-wallet/types": "npm:^0.12.136" "@namada/chain-registry": "npm:^1.5.2" "@namada/indexer-client": "npm:4.0.5" - "@namada/sdk-multicore": "npm:0.23.0-beta.1" + "@namada/sdk-multicore": "file:.yalc/@namada/sdk-multicore" "@namada/sdk-node": "npm:0.23.0-beta.1" "@namada/vite-esbuild-plugin": "npm:^1.0.1" "@playwright/test": "npm:^1.24.1" @@ -3858,9 +3858,9 @@ __metadata: languageName: unknown linkType: soft -"@namada/sdk-multicore@npm:0.23.0-beta.1": +"@namada/sdk-multicore@file:.yalc/@namada/sdk-multicore::locator=%40namada%2Fnamadillo%40workspace%3Aapps%2Fnamadillo": version: 0.23.0-beta.1 - resolution: "@namada/sdk-multicore@npm:0.23.0-beta.1" + resolution: "@namada/sdk-multicore@file:.yalc/@namada/sdk-multicore#.yalc/@namada/sdk-multicore::hash=dba331&locator=%40namada%2Fnamadillo%40workspace%3Aapps%2Fnamadillo" dependencies: "@cosmjs/encoding": "npm:^0.29.0" "@dao-xyz/borsh": "npm:^5.1.5" @@ -3871,7 +3871,7 @@ __metadata: buffer: "npm:^6.0.3" semver: "npm:^7.7.2" slip44: "npm:^3.0.18" - checksum: 10c0/e3a76c702e5dd1d43c0a269b57cc2fae5803a7cb02a3b9556d189d2c5a5b34f1ac4332d0e81d7000f98afacaca001d7bedca7c1b5fcc110d4998a63913979ba8 + checksum: 10c0/87e72ddc4b0b7a7b65939f2ddbf270faa99c0e925ce010dd85d54455062f1510eb6a89caee2a4d90b6f2a4c48d747281cd0969186631880e962806b69949fe44 languageName: node linkType: hard