diff --git a/src/SafeProvider.ts b/src/SafeProvider.ts index 14ab7f1..f01e5fd 100644 --- a/src/SafeProvider.ts +++ b/src/SafeProvider.ts @@ -24,6 +24,7 @@ export const SafeContext = createContext({ publicClient: undefined, signerClient: undefined }) + export type SafeProviderProps = { config: SafeConfig } diff --git a/src/hooks/helpers/useAsyncMemo.ts b/src/hooks/helpers/useAsyncMemo.ts new file mode 100644 index 0000000..2f0642d --- /dev/null +++ b/src/hooks/helpers/useAsyncMemo.ts @@ -0,0 +1,21 @@ +import { DependencyList, useEffect, useState } from 'react' + +/** + * Hook that memoizes the result of an async function. + * @param factory Async function of which the result should be memoized. + * @param deps Dependency list + * @returns Current result or `undefined` if not available. + */ +export function useAsyncMemo(factory: () => Promise, deps: DependencyList): T | undefined { + const [result, setResult] = useState(undefined) + + useEffect(() => { + factory().then((newResult) => { + if (newResult !== result) { + setResult(newResult) + } + }) + }, [...deps, factory, result]) + + return result +} diff --git a/src/hooks/useSignerAddress.ts b/src/hooks/useSignerAddress.ts index b24bedf..fb5d264 100644 --- a/src/hooks/useSignerAddress.ts +++ b/src/hooks/useSignerAddress.ts @@ -1,7 +1,7 @@ -import { useEffect, useState } from 'react' import type { Address } from 'viem' import { ConfigParam, SafeConfigWithSigner } from '@/types/index.js' import { useSignerClient } from '@/hooks/useSignerClient.js' +import { useAsyncMemo } from '@/hooks/helpers/useAsyncMemo.js' export type UseSignerAddressParams = ConfigParam export type UseSignerAddressReturnType = Address | undefined @@ -14,15 +14,12 @@ export type UseSignerAddressReturnType = Address | undefined */ export function useSignerAddress(params: UseSignerAddressParams = {}): UseSignerAddressReturnType { const signerClient = useSignerClient({ config: params.config }) - const [signerAddress, setSignerAddress] = useState() - useEffect(() => { - if (signerClient) { - signerClient?.protocolKit.getSafeProvider().getSignerAddress().then(setSignerAddress) - } else { - setSignerAddress(undefined) - } - }, [signerClient]) + const signerAddress = useAsyncMemo( + async () => + signerClient ? signerClient.protocolKit.getSafeProvider().getSignerAddress() : undefined, + [signerClient] + ) return signerAddress }