From e7f49209b7c01ad9431b50e2066225a87cd08f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Eren?= Date: Sat, 30 Mar 2024 22:21:20 +0300 Subject: [PATCH 1/3] useEstimateFees hook --- packages/core/src/hooks/index.ts | 1 + packages/core/src/hooks/useEstimateFees.ts | 92 ++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 packages/core/src/hooks/useEstimateFees.ts diff --git a/packages/core/src/hooks/index.ts b/packages/core/src/hooks/index.ts index 4e5529dc..2575c312 100644 --- a/packages/core/src/hooks/index.ts +++ b/packages/core/src/hooks/index.ts @@ -18,3 +18,4 @@ export * from "./useStarkAddress"; export * from "./useStarkName"; export * from "./useWaitForTransaction"; export * from "./useStarkProfile"; +export * from "./useEstimateFees"; diff --git a/packages/core/src/hooks/useEstimateFees.ts b/packages/core/src/hooks/useEstimateFees.ts new file mode 100644 index 00000000..83ef3198 --- /dev/null +++ b/packages/core/src/hooks/useEstimateFees.ts @@ -0,0 +1,92 @@ +import { useMemo } from "react"; +import { + AccountInterface, + Call, + EstimateFeeDetails, + EstimateFeeResponse, +} from "starknet"; + +import { UseQueryProps, UseQueryResult, useQuery } from "~/query"; + +import { useAccount } from "./useAccount"; +import { useInvalidateOnBlock } from "./useInvalidateOnBlock"; + +type EstimateFeesArgs = { + /** List of smart contract calls to estimate. */ + calls?: Call[]; + /** Estimate Fee options. */ + options?: EstimateFeeDetails; +}; + +/** Options for `useEstimateFees`. */ +export type UseEstimateFeesProps = EstimateFeesArgs & + UseQueryProps> & { + /** Refresh data at every block. */ + watch?: boolean; + }; + +/** Value returned from `useEstimateFees`. */ +export type UseEstimateFeesResult = UseQueryResult; + +/** + * Hook to estimate fees for smart contract calls. + * + * @remarks + * + * The hook only performs estimation if the `calls` is not undefined. + */ +export function useEstimateFees({ + calls, + options, + watch = false, + enabled: enabled_ = true, + ...props +}: UseEstimateFeesProps): UseEstimateFeesResult { + const { account } = useAccount(); + + const queryKey_ = useMemo( + () => queryKey({ calls, options }), + [calls, options] + ); + + const enabled = useMemo( + () => Boolean(enabled_ && calls), + [enabled_, calls], + ); + + useInvalidateOnBlock({ + enabled: Boolean(enabled && watch), + queryKey: queryKey_, + }); + + return useQuery({ + queryKey: queryKey_, + queryFn: queryFn({ + account, + calls, + options, + }), + ...props, + }); +} + +function queryKey({ + calls, + options, +}: EstimateFeesArgs) { + return [ + { + entity: "estimateInvokeFee", + calls, + options, + }, + ] as const; +} + +function queryFn({ account, calls, options }: { account?: AccountInterface } & EstimateFeesArgs) { + return async function () { + if (!account) throw new Error("account is required"); + if (!calls || calls.length === 0) throw new Error("calls are required"); + return account?.estimateInvokeFee(calls, options); + }; +} From be3af8622012ea8aab7d086849db2f7f4f8804df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Eren?= Date: Sat, 30 Mar 2024 22:39:00 +0300 Subject: [PATCH 2/3] useEstiamteFees hook docs --- .../content/hooks/query/useEstimateFees.mdx | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 website/content/hooks/query/useEstimateFees.mdx diff --git a/website/content/hooks/query/useEstimateFees.mdx b/website/content/hooks/query/useEstimateFees.mdx new file mode 100644 index 00000000..55ef6486 --- /dev/null +++ b/website/content/hooks/query/useEstimateFees.mdx @@ -0,0 +1,53 @@ +--- +title: useEstimateFees +priority: 194 +hookType: query +--- + +Perform fee estimation for smart contract calls. Estimation then later can be used to specify the `maxFee` for the actual contract call. + +## Usage + +```ts +import { useAccount, useContract, useEstimateFees } from "@starknet-react/core"; + +export default function Component() { + const { address } = useAccount(); + + const { contract } = useContract({ + abi: erc20ABI, + address: chain.nativeCurrency.address, + }); + + const calls = useMemo(() => { + if (!address || !contract) return []; + return contract.populateTransaction["transfer"]!(address, { low: 1, high: 0 }); + }, [contract, address]); + + const { data, isError, isLoading, error } = useEstimateFees({ + calls, + watch: true, + }); + + if (isLoading) return
Loading ...
; + if (isError || !data) return
{error?.message}
; + + return
Suggested Max Fee: {data.suggestedMaxFee}
; +} +``` + +## Options + +- **calls**`: string` + - The contract calls to estimate fees for. +- **options**`: string` + - Estimation options. + - EstimateFeeDetails from starknet.js +- **watch?**`: boolean` + - If true, refresh data at every block. + +## Returns + +- **data?**`: EstimateFeeResponse` + - Estimated fees for the contract calls. + - EstimateFeeResponse from starknet.js From 78b124deb4a21a23908b52c38a9dd60d86a1dd22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Eren?= Date: Mon, 1 Apr 2024 16:04:58 +0300 Subject: [PATCH 3/3] Add useEstimateFees changelog --- .changeset/six-crews-jog.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-crews-jog.md diff --git a/.changeset/six-crews-jog.md b/.changeset/six-crews-jog.md new file mode 100644 index 00000000..54d957c2 --- /dev/null +++ b/.changeset/six-crews-jog.md @@ -0,0 +1,5 @@ +--- +"@starknet-react/core": minor +--- + +Add useEstimateFees hook to estimate smart contract calls fees