From d4db4b0187b157f8ee15711a7b193e5a796b2440 Mon Sep 17 00:00:00 2001 From: Adam Lessey Date: Mon, 21 Oct 2024 23:33:57 -0400 Subject: [PATCH] fix: transaction promises --- .../components/demo/Transaction.tsx | 28 ++++++++++++------- .../components/TransactionProvider.test.tsx | 2 +- .../components/TransactionProvider.tsx | 4 ++- src/transaction/types.ts | 24 ++++++++-------- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/playground/nextjs-app-router/components/demo/Transaction.tsx b/playground/nextjs-app-router/components/demo/Transaction.tsx index aabe18989cd..b6ca937aa4a 100644 --- a/playground/nextjs-app-router/components/demo/Transaction.tsx +++ b/playground/nextjs-app-router/components/demo/Transaction.tsx @@ -23,16 +23,24 @@ function TransactionDemo() { const capabilities = useCapabilities(); const contracts = clickContracts as ContractFunctionParameters[]; const calls = clickCalls as Call[]; - const promiseCalls = new Promise((resolve) => { - setTimeout(() => { - resolve(calls); - }, 4000); - }) as Promise; - const promiseContracts = new Promise((resolve) => { - setTimeout(() => { - resolve(contracts); - }, 4000); - }) as Promise; + const promiseCalls = useCallback( + () => + new Promise((resolve) => { + setTimeout(() => { + resolve(calls); + }, 4000); + }) as Promise, + [calls], + ); + const promiseContracts = useCallback( + () => + new Promise((resolve) => { + setTimeout(() => { + resolve(contracts); + }, 4000); + }) as Promise, + [contracts], + ); useEffect(() => { console.log('Playground.Transaction.chainId:', chainId); }, [chainId]); diff --git a/src/transaction/components/TransactionProvider.test.tsx b/src/transaction/components/TransactionProvider.test.tsx index b96a7e0063e..6bbb48df07a 100644 --- a/src/transaction/components/TransactionProvider.test.tsx +++ b/src/transaction/components/TransactionProvider.test.tsx @@ -263,7 +263,7 @@ describe('TransactionProvider', () => { sendWalletTransactionsMock, ); const onErrorMock = vi.fn(); - const contracts = Promise.reject(new Error('error')); + const contracts = () => Promise.reject(new Error('error')); render( diff --git a/src/transaction/components/TransactionProvider.tsx b/src/transaction/components/TransactionProvider.tsx index 60869d18844..17987a5f970 100644 --- a/src/transaction/components/TransactionProvider.tsx +++ b/src/transaction/components/TransactionProvider.tsx @@ -286,7 +286,9 @@ export function TransactionProvider({ statusData: null, }); try { - const resolvedTransactions = await Promise.resolve(transactions); + const resolvedTransactions = await (typeof transactions === 'function' + ? transactions() + : Promise.resolve(transactions)); setTransactionCount(resolvedTransactions?.length); return resolvedTransactions; } catch (err) { diff --git a/src/transaction/types.ts b/src/transaction/types.ts index 93cd0ad3cae..8bd5547aa8e 100644 --- a/src/transaction/types.ts +++ b/src/transaction/types.ts @@ -86,11 +86,7 @@ export type TransactionContextType = { setIsToastVisible: (isVisible: boolean) => void; // A function to set the visibility of the transaction toast. setLifecycleStatus: (state: LifecycleStatus) => void; // A function to set the lifecycle status of the component setTransactionId: (id: string) => void; // A function to set the transaction ID. - transactions?: - | Call[] - | ContractFunctionParameters[] - | Promise - | Promise; // An array of transactions for the component or a promise that resolves to an array of transactions. + transactions?: Calls | Contracts; // An array of transactions for the component or a promise that resolves to an array of transactions. transactionId?: string; // An optional string representing the ID of the transaction. transactionHash?: string; // An optional string representing the hash of the transaction. }; @@ -133,14 +129,18 @@ export type TransactionError = { message: string; // The error message providing details about the transaction error. }; +type Calls = Call[] | Promise | (() => Promise); +type Contracts = + | ContractFunctionParameters[] + | Promise + | (() => Promise); + export type TransactionProviderReact = { - calls?: Call[] | Promise; // An array of calls for the transaction. Mutually exclusive with the `contracts` prop. + calls?: Calls; // An array of calls to be made in the transaction. Mutually exclusive with the `contracts` prop. capabilities?: WalletCapabilities; // Capabilities that a wallet supports (e.g. paymasters, session keys, etc). chainId: number; // The chainId for the transaction. children: ReactNode; // The child components to be rendered within the provider component. - contracts?: - | ContractFunctionParameters[] - | Promise; // An array of contract function parameters provided to the child components. Mutually exclusive with the `calls` prop. + contracts?: Contracts; // An array of contract function parameters provided to the child components. Mutually exclusive with the `calls` prop. onError?: (e: TransactionError) => void; // An optional callback function that handles errors within the provider. onStatus?: (lifecycleStatus: LifecycleStatus) => void; // An optional callback function that exposes the component lifecycle state onSuccess?: (response: TransactionResponse) => void; // An optional callback function that exposes the transaction receipts @@ -150,14 +150,12 @@ export type TransactionProviderReact = { * Note: exported as public Type */ export type TransactionReact = { - calls?: Call[] | Promise; // An array of calls to be made in the transaction. Mutually exclusive with the `contracts` prop. + calls?: Calls; // An array of calls to be made in the transaction. Mutually exclusive with the `contracts` prop. capabilities?: WalletCapabilities; // Capabilities that a wallet supports (e.g. paymasters, session keys, etc). chainId?: number; // The chainId for the transaction. children: ReactNode; // The child components to be rendered within the transaction component. className?: string; // An optional CSS class name for styling the component. - contracts?: - | ContractFunctionParameters[] - | Promise; // An array of contract function parameters for the transaction. Mutually exclusive with the `calls` prop. + contracts?: Contracts; // An array of contract function parameters provided to the child components. Mutually exclusive with the `calls` prop. onError?: (e: TransactionError) => void; // An optional callback function that handles transaction errors. onStatus?: (lifecycleStatus: LifecycleStatus) => void; // An optional callback function that exposes the component lifecycle state onSuccess?: (response: TransactionResponse) => void; // An optional callback function that exposes the transaction receipts