diff --git a/.changeset/many-ravens-cry.md b/.changeset/many-ravens-cry.md index 980b1b4bde..60717a08be 100644 --- a/.changeset/many-ravens-cry.md +++ b/.changeset/many-ravens-cry.md @@ -2,6 +2,5 @@ "@coinbase/onchainkit": patch --- --**chore**: Add testing to Transaction Toast. By @cpcramer #1023 --**chore**: Add Connect Wallet tests and refactor to use Vitest. By @cpcramer #1036 --**chore**: Increase Wallet dropdown png size to 18x18. By @cpcramer #1041 +- **feat**: introduced `onStatus` listener, to help expose the internal `Transaction`'s component lifecycle. By @zizzamia #1034 +- **chore**: increased `Wallet` dropdown png size to 18x18. By @cpcramer #1041 diff --git a/src/transaction/components/Transaction.test.tsx b/src/transaction/components/Transaction.test.tsx index 9306283fac..9d4b48cbab 100644 --- a/src/transaction/components/Transaction.test.tsx +++ b/src/transaction/components/Transaction.test.tsx @@ -1,15 +1,20 @@ import { render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import { Transaction } from './Transaction'; +import { TransactionProvider } from './TransactionProvider'; vi.mock('./TransactionProvider', () => ({ - TransactionProvider: ({ children }: { children: React.ReactNode }) => ( + TransactionProvider: vi.fn(({ children }: { children: React.ReactNode }) => (
{children}
- ), + )), })); describe('Transaction', () => { - it('renders the children inside the TransactionProvider', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('should renders the children inside the TransactionProvider', () => { render( {
Test Child
, ); - expect(screen.getByText('Test Child')).toBeInTheDocument(); }); - it('applies the correct className', () => { + it('should applies the correct className', () => { render( {
Test Child
, ); - // Checking if the div has the correct classes applied const container = screen.getByText('Test Child').parentElement; expect(container).toHaveClass('test-class'); }); + + it('should call TransactionProvider', () => { + const onError = vi.fn(); + const onStatus = vi.fn(); + const onSuccess = vi.fn(); + render( + +
Test Child
+
, + ); + // Checking if the TransactionProvider is called + expect(TransactionProvider).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/transaction/components/Transaction.tsx b/src/transaction/components/Transaction.tsx index 97e002c88d..d2cac1cb0f 100644 --- a/src/transaction/components/Transaction.tsx +++ b/src/transaction/components/Transaction.tsx @@ -10,6 +10,7 @@ export function Transaction({ children, contracts, onError, + onStatus, onSuccess, }: TransactionReact) { return ( @@ -19,6 +20,7 @@ export function Transaction({ chainId={chainId} contracts={contracts} onError={onError} + onStatus={onStatus} onSuccess={onSuccess} >
diff --git a/src/transaction/components/TransactionProvider.test.tsx b/src/transaction/components/TransactionProvider.test.tsx index d4d5ae3fe0..7e0fc9e370 100644 --- a/src/transaction/components/TransactionProvider.test.tsx +++ b/src/transaction/components/TransactionProvider.test.tsx @@ -36,6 +36,12 @@ vi.mock('../hooks/useWriteContracts', () => ({ const TestComponent = () => { const context = useTransactionContext(); + const handleSetLifeCycleStatus = async () => { + context.setLifeCycleStatus({ + statusName: 'error', + statusData: { code: 'code', error: 'error_long_messages' }, + }); + }; return (
); }; @@ -76,6 +85,34 @@ describe('TransactionProvider', () => { }); }); + it('should emit onError when setLifeCycleStatus is called with error', async () => { + const onErrorMock = vi.fn(); + render( + + + , + ); + const button = screen.getByText('setLifeCycleStatus.error'); + fireEvent.click(button); + expect(onErrorMock).toHaveBeenCalled(); + }); + + it('should emit onStatus when setLifeCycleStatus is called', async () => { + const onStatusMock = vi.fn(); + render( + + + , + ); + const button = screen.getByText('setLifeCycleStatus.error'); + fireEvent.click(button); + expect(onStatusMock).toHaveBeenCalled(); + }); + it('should update context on handleSubmit', async () => { const writeContractsAsyncMock = vi.fn(); (useWriteContracts as ReturnType).mockReturnValue({ diff --git a/src/transaction/components/TransactionProvider.tsx b/src/transaction/components/TransactionProvider.tsx index 521b7da937..acb3003308 100644 --- a/src/transaction/components/TransactionProvider.tsx +++ b/src/transaction/components/TransactionProvider.tsx @@ -26,6 +26,7 @@ import { useCallsStatus } from '../hooks/useCallsStatus'; import { useWriteContract } from '../hooks/useWriteContract'; import { useWriteContracts } from '../hooks/useWriteContracts'; import type { + LifeCycleStatus, TransactionContextType, TransactionProviderReact, } from '../types'; @@ -51,22 +52,30 @@ export function TransactionProvider({ children, contracts, onError, + onStatus, onSuccess, }: TransactionProviderReact) { + // Core Hooks + const account = useAccount(); + const config = useConfig(); const [errorMessage, setErrorMessage] = useState(''); - const [transactionId, setTransactionId] = useState(''); const [isToastVisible, setIsToastVisible] = useState(false); + const [lifeCycleStatus, setLifeCycleStatus] = useState({ + statusName: 'init', + statusData: null, + }); // Component lifecycle + const [receiptArray, setReceiptArray] = useState([]); + const [transactionId, setTransactionId] = useState(''); const [transactionHashArray, setTransactionHashArray] = useState( [], ); - const [receiptArray, setReceiptArray] = useState([]); - const account = useAccount(); - const config = useConfig(); const { switchChainAsync } = useSwitchChain(); + + // Hooks that depend from Core Hooks const { status: statusWriteContracts, writeContractsAsync } = useWriteContracts({ - onError, setErrorMessage, + setLifeCycleStatus, setTransactionId, }); const { @@ -74,20 +83,35 @@ export function TransactionProvider({ writeContractAsync, data: writeContractTransactionHash, } = useWriteContract({ - onError, setErrorMessage, + setLifeCycleStatus, setTransactionHashArray, transactionHashArray, }); const { transactionHash, status: callStatus } = useCallsStatus({ - onError, + setLifeCycleStatus, transactionId, }); - const { data: receipt } = useWaitForTransactionReceipt({ hash: writeContractTransactionHash || transactionHash, }); + // Component lifecycle emitters + useEffect(() => { + // Emit Error + if (lifeCycleStatus.statusName === 'error') { + onError?.(lifeCycleStatus.statusData); + } + // Emit State + onStatus?.(lifeCycleStatus); + }, [ + onError, + onStatus, + lifeCycleStatus, + lifeCycleStatus.statusData, // Keep statusData, so that the effect runs when it changes + lifeCycleStatus.statusName, // Keep statusName, so that the effect runs when it changes + ]); + const getTransactionReceipts = useCallback(async () => { const receipts = []; for (const hash of transactionHashArray) { @@ -208,6 +232,7 @@ export function TransactionProvider({ receipt, setErrorMessage, setIsToastVisible, + setLifeCycleStatus, setTransactionId, statusWriteContracts, statusWriteContract, diff --git a/src/transaction/hooks/useCallsStatus.test.ts b/src/transaction/hooks/useCallsStatus.test.ts index 035c0ddd6d..b1674958d9 100644 --- a/src/transaction/hooks/useCallsStatus.test.ts +++ b/src/transaction/hooks/useCallsStatus.test.ts @@ -15,34 +15,34 @@ describe('useCallsStatus', () => { status: 'CONFIRMED', receipts: [{ transactionHash: '0x123' }], }; - (useCallsStatusWagmi as ReturnType).mockReturnValue({ data: mockData, }); - const { result } = renderHook(() => useCallsStatus({ transactionId })); - expect(result.current.status).toBe('CONFIRMED'); expect(result.current.transactionHash).toBe('0x123'); }); it('should handle errors and call onError callback', () => { - const mockOnError = vi.fn(); + const mockSetLifeCycleStatus = vi.fn(); const mockError = new Error('Test error'); - (useCallsStatusWagmi as ReturnType).mockImplementation(() => { throw mockError; }); - const { result } = renderHook(() => - useCallsStatus({ transactionId, onError: mockOnError }), + useCallsStatus({ + setLifeCycleStatus: mockSetLifeCycleStatus, + transactionId, + }), ); - expect(result.current.status).toBe('error'); expect(result.current.transactionHash).toBeUndefined(); - expect(mockOnError).toHaveBeenCalledWith({ - code: 'UNCAUGHT_CALL_STATUS_ERROR', - error: JSON.stringify(mockError), + expect(mockSetLifeCycleStatus).toHaveBeenCalledWith({ + statusName: 'error', + statusData: { + code: 'UNCAUGHT_CALL_STATUS_ERROR', + error: JSON.stringify(mockError), + }, }); }); }); diff --git a/src/transaction/hooks/useCallsStatus.ts b/src/transaction/hooks/useCallsStatus.ts index 80f62cc3b4..705566befa 100644 --- a/src/transaction/hooks/useCallsStatus.ts +++ b/src/transaction/hooks/useCallsStatus.ts @@ -4,25 +4,26 @@ import type { UseCallsStatusParams } from '../types'; const uncaughtErrorCode = 'UNCAUGHT_CALL_STATUS_ERROR'; export function useCallsStatus({ - onError, + setLifeCycleStatus, transactionId, }: UseCallsStatusParams) { try { const { data } = useCallsStatusWagmi({ id: transactionId, query: { - refetchInterval: (data) => { - return data.state.data?.status === 'CONFIRMED' ? false : 1000; + refetchInterval: (query) => { + return query.state.data?.status === 'CONFIRMED' ? false : 1000; }, enabled: !!transactionId, }, }); - const transactionHash = data?.receipts?.[0]?.transactionHash; - return { status: data?.status, transactionHash }; } catch (err) { - onError?.({ code: uncaughtErrorCode, error: JSON.stringify(err) }); + setLifeCycleStatus({ + statusName: 'error', + statusData: { code: uncaughtErrorCode, error: JSON.stringify(err) }, + }); return { status: 'error', transactionHash: undefined }; } } diff --git a/src/transaction/hooks/useGetTransactionStatus.test.tsx b/src/transaction/hooks/useGetTransactionStatus.test.tsx index 2c72faad7e..ea5abf9b82 100644 --- a/src/transaction/hooks/useGetTransactionStatus.test.tsx +++ b/src/transaction/hooks/useGetTransactionStatus.test.tsx @@ -20,9 +20,7 @@ describe('useGetTransactionStatus', () => { (useTransactionContext as vi.Mock).mockReturnValue({ statusWriteContract: 'pending', }); - const { result } = renderHook(() => useGetTransactionStatus()); - expect(result.current.label).toBe('Confirm in wallet.'); }); @@ -30,9 +28,7 @@ describe('useGetTransactionStatus', () => { (useTransactionContext as vi.Mock).mockReturnValue({ transactionHash: 'ab123', }); - const { result } = renderHook(() => useGetTransactionStatus()); - expect(result.current.label).toBe('Transaction in progress...'); expect(result.current.actionElement).not.toBeNull(); }); @@ -42,9 +38,7 @@ describe('useGetTransactionStatus', () => { receipt: 'receipt', transactionHash: '123', }); - const { result } = renderHook(() => useGetTransactionStatus()); - expect(result.current.label).toBe('Successful!'); expect(result.current.actionElement).not.toBeNull(); }); @@ -53,9 +47,7 @@ describe('useGetTransactionStatus', () => { (useTransactionContext as vi.Mock).mockReturnValue({ errorMessage: 'error', }); - const { result } = renderHook(() => useGetTransactionStatus()); - expect(result.current.label).toBe('error'); expect(result.current.labelClassName).toBe('text-ock-error'); }); @@ -64,9 +56,7 @@ describe('useGetTransactionStatus', () => { (useTransactionContext as vi.Mock).mockReturnValue({ errorMessage: '', }); - const { result } = renderHook(() => useGetTransactionStatus()); - expect(result.current.label).toBe(''); expect(result.current.actionElement).toBeNull(); }); diff --git a/src/transaction/hooks/useWriteContract.test.ts b/src/transaction/hooks/useWriteContract.test.ts index bfb4c35cef..4d1f549bbf 100644 --- a/src/transaction/hooks/useWriteContract.test.ts +++ b/src/transaction/hooks/useWriteContract.test.ts @@ -22,8 +22,8 @@ type MockUseWriteContractReturn = { describe('useWriteContract', () => { const mockSetErrorMessage = vi.fn(); + const mockSetLifeCycleStatus = vi.fn(); const mockSetTransactionHashArray = vi.fn(); - const mockOnError = vi.fn(); beforeEach(() => { vi.resetAllMocks(); @@ -37,15 +37,13 @@ describe('useWriteContract', () => { writeContractAsync: mockWriteContract, data: mockData, } as MockUseWriteContractReturn); - const { result } = renderHook(() => useWriteContract({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionHashArray: mockSetTransactionHashArray, - onError: mockOnError, }), ); - expect(result.current.status).toBe('idle'); expect(result.current.writeContractAsync).toBe(mockWriteContract); expect(result.current.data).toBe(mockData); @@ -53,9 +51,7 @@ describe('useWriteContract', () => { it('should handle generic error', () => { const genericError = new Error('Something went wrong. Please try again.'); - let onErrorCallback: ((error: Error) => void) | undefined; - (useWriteContractWagmi as ReturnType).mockImplementation( ({ mutation }: UseWriteContractConfig) => { onErrorCallback = mutation.onError; @@ -66,12 +62,11 @@ describe('useWriteContract', () => { } as MockUseWriteContractReturn; }, ); - renderHook(() => useWriteContract({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionHashArray: mockSetTransactionHashArray, - onError: mockOnError, }), ); @@ -81,17 +76,18 @@ describe('useWriteContract', () => { expect(mockSetErrorMessage).toHaveBeenCalledWith( 'Something went wrong. Please try again.', ); - expect(mockOnError).toHaveBeenCalledWith({ - code: 'WRITE_CONTRACT_ERROR', - error: 'Something went wrong. Please try again.', + expect(mockSetLifeCycleStatus).toHaveBeenCalledWith({ + statusName: 'error', + statusData: { + code: 'WRITE_CONTRACT_ERROR', + error: 'Something went wrong. Please try again.', + }, }); }); it('should handle successful transaction', () => { const transactionId = '0x123'; - let onSuccessCallback: ((id: string) => void) | undefined; - (useWriteContractWagmi as ReturnType).mockImplementation( ({ mutation }: UseWriteContractConfig) => { onSuccessCallback = mutation.onSuccess; @@ -102,46 +98,43 @@ describe('useWriteContract', () => { } as MockUseWriteContractReturn; }, ); - renderHook(() => useWriteContract({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionHashArray: mockSetTransactionHashArray, - onError: mockOnError, }), ); - expect(onSuccessCallback).toBeDefined(); onSuccessCallback?.(transactionId); - expect(mockSetTransactionHashArray).toHaveBeenCalledWith([transactionId]); }); it('should handle uncaught errors', () => { const uncaughtError = new Error('Uncaught error'); - (useWriteContractWagmi as ReturnType).mockImplementation( () => { throw uncaughtError; }, ); - const { result } = renderHook(() => useWriteContract({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionHashArray: mockSetTransactionHashArray, - onError: mockOnError, }), ); - expect(result.current.status).toBe('error'); expect(result.current.writeContractAsync).toBeInstanceOf(Function); expect(mockSetErrorMessage).toHaveBeenCalledWith( 'Something went wrong. Please try again.', ); - expect(mockOnError).toHaveBeenCalledWith({ - code: 'UNCAUGHT_WRITE_CONTRACT_ERROR', - error: JSON.stringify(uncaughtError), + expect(mockSetLifeCycleStatus).toHaveBeenCalledWith({ + statusName: 'error', + statusData: { + code: 'UNCAUGHT_WRITE_CONTRACT_ERROR', + error: JSON.stringify(uncaughtError), + }, }); }); }); diff --git a/src/transaction/hooks/useWriteContract.ts b/src/transaction/hooks/useWriteContract.ts index 6d2b38e1a5..3bb051f6d6 100644 --- a/src/transaction/hooks/useWriteContract.ts +++ b/src/transaction/hooks/useWriteContract.ts @@ -13,8 +13,8 @@ import type { UseWriteContractParams } from '../types'; * Does not support transaction batching or paymasters. */ export function useWriteContract({ - onError, setErrorMessage, + setLifeCycleStatus, setTransactionHashArray, transactionHashArray, }: UseWriteContractParams) { @@ -30,7 +30,10 @@ export function useWriteContract({ } else { setErrorMessage(GENERIC_ERROR_MESSAGE); } - onError?.({ code: WRITE_CONTRACT_ERROR_CODE, error: e.message }); + setLifeCycleStatus({ + statusName: 'error', + statusData: { code: WRITE_CONTRACT_ERROR_CODE, error: e.message }, + }); }, onSuccess: (hash: Address) => { setTransactionHashArray( @@ -41,9 +44,12 @@ export function useWriteContract({ }); return { status, writeContractAsync, data }; } catch (err) { - onError?.({ - code: UNCAUGHT_WRITE_CONTRACT_ERROR_CODE, - error: JSON.stringify(err), + setLifeCycleStatus({ + statusName: 'error', + statusData: { + code: UNCAUGHT_WRITE_CONTRACT_ERROR_CODE, + error: JSON.stringify(err), + }, }); setErrorMessage(GENERIC_ERROR_MESSAGE); return { status: 'error', writeContractAsync: () => {} }; diff --git a/src/transaction/hooks/useWriteContracts.test.ts b/src/transaction/hooks/useWriteContracts.test.ts index 32a6da059a..d441f379c5 100644 --- a/src/transaction/hooks/useWriteContracts.test.ts +++ b/src/transaction/hooks/useWriteContracts.test.ts @@ -9,8 +9,8 @@ vi.mock('wagmi/experimental', () => ({ describe('useWriteContracts', () => { const mockSetErrorMessage = vi.fn(); + const mockSetLifeCycleStatus = vi.fn(); const mockSetTransactionId = vi.fn(); - const mockOnError = vi.fn(); beforeEach(() => { vi.resetAllMocks(); @@ -18,9 +18,7 @@ describe('useWriteContracts', () => { it('should handle generic error', () => { const genericError = new Error('Something went wrong. Please try again.'); - let onErrorCallback: ((error: Error) => void) | undefined; - (useWriteContractsWagmi as ReturnType).mockImplementation( ({ mutation }: UseWriteContractsConfig) => { onErrorCallback = mutation.onError; @@ -30,32 +28,30 @@ describe('useWriteContracts', () => { }; }, ); - renderHook(() => useWriteContracts({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionId: mockSetTransactionId, - onError: mockOnError, }), ); - expect(onErrorCallback).toBeDefined(); onErrorCallback?.(genericError); - expect(mockSetErrorMessage).toHaveBeenCalledWith( 'Something went wrong. Please try again.', ); - expect(mockOnError).toHaveBeenCalledWith({ - code: 'WRITE_CONTRACTS_ERROR', - error: 'Something went wrong. Please try again.', + expect(mockSetLifeCycleStatus).toHaveBeenCalledWith({ + statusName: 'error', + statusData: { + code: 'WRITE_CONTRACTS_ERROR', + error: 'Something went wrong. Please try again.', + }, }); }); it('should handle successful transaction', () => { const transactionId = '0x123'; - let onSuccessCallback: ((id: string) => void) | undefined; - (useWriteContractsWagmi as ReturnType).mockImplementation( ({ mutation }: UseWriteContractsConfig) => { onSuccessCallback = mutation.onSuccess; @@ -65,46 +61,43 @@ describe('useWriteContracts', () => { }; }, ); - renderHook(() => useWriteContracts({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionId: mockSetTransactionId, - onError: mockOnError, }), ); - expect(onSuccessCallback).toBeDefined(); onSuccessCallback?.(transactionId); - expect(mockSetTransactionId).toHaveBeenCalledWith(transactionId); }); it('should handle uncaught errors', () => { const uncaughtError = new Error('Uncaught error'); - (useWriteContractsWagmi as ReturnType).mockImplementation( () => { throw uncaughtError; }, ); - const { result } = renderHook(() => useWriteContracts({ setErrorMessage: mockSetErrorMessage, + setLifeCycleStatus: mockSetLifeCycleStatus, setTransactionId: mockSetTransactionId, - onError: mockOnError, }), ); - expect(result.current.status).toBe('error'); expect(result.current.writeContracts).toBeInstanceOf(Function); expect(mockSetErrorMessage).toHaveBeenCalledWith( 'Something went wrong. Please try again.', ); - expect(mockOnError).toHaveBeenCalledWith({ - code: 'UNCAUGHT_WRITE_WRITE_CONTRACTS_ERROR', - error: JSON.stringify(uncaughtError), + expect(mockSetLifeCycleStatus).toHaveBeenCalledWith({ + statusName: 'error', + statusData: { + code: 'UNCAUGHT_WRITE_WRITE_CONTRACTS_ERROR', + error: JSON.stringify(uncaughtError), + }, }); }); }); diff --git a/src/transaction/hooks/useWriteContracts.ts b/src/transaction/hooks/useWriteContracts.ts index 0abeb93c4c..ac256a1ab5 100644 --- a/src/transaction/hooks/useWriteContracts.ts +++ b/src/transaction/hooks/useWriteContracts.ts @@ -15,8 +15,8 @@ import type { UseWriteContractsParams } from '../types'; * Does not support EOAs. */ export function useWriteContracts({ - onError, setErrorMessage, + setLifeCycleStatus, setTransactionId, }: UseWriteContractsParams) { try { @@ -39,7 +39,10 @@ export function useWriteContracts({ } else { setErrorMessage(GENERIC_ERROR_MESSAGE); } - onError?.({ code: WRITE_CONTRACTS_ERROR_CODE, error: e.message }); + setLifeCycleStatus({ + statusName: 'error', + statusData: { code: WRITE_CONTRACTS_ERROR_CODE, error: e.message }, + }); }, onSuccess: (id) => { setTransactionId(id); @@ -48,9 +51,12 @@ export function useWriteContracts({ }); return { status, writeContractsAsync }; } catch (err) { - onError?.({ - code: UNCAUGHT_WRITE_CONTRACTS_ERROR_CODE, - error: JSON.stringify(err), + setLifeCycleStatus({ + statusName: 'error', + statusData: { + code: UNCAUGHT_WRITE_CONTRACTS_ERROR_CODE, + error: JSON.stringify(err), + }, }); setErrorMessage(GENERIC_ERROR_MESSAGE); return { diff --git a/src/transaction/index.ts b/src/transaction/index.ts index 3bbebb27e4..84a31c0e4a 100644 --- a/src/transaction/index.ts +++ b/src/transaction/index.ts @@ -10,6 +10,7 @@ export { TransactionToastIcon } from './components/TransactionToastIcon'; export { TransactionToastAction } from './components/TransactionToastAction'; export { TransactionToastLabel } from './components/TransactionToastLabel'; export type { + LifeCycleStatus, TransactionButtonReact, TransactionError, TransactionReact, diff --git a/src/transaction/types.ts b/src/transaction/types.ts index 29b1ffada2..84f281f7d9 100644 --- a/src/transaction/types.ts +++ b/src/transaction/types.ts @@ -6,6 +6,19 @@ import type { TransactionReceipt, } from 'viem'; +/** + * Note: exported as public Type + */ +export type LifeCycleStatus = + | { + statusName: 'init'; + statusData: null; + } + | { + statusName: 'error'; + statusData: TransactionError; + }; + export type IsSpinnerDisplayedProps = { errorMessage?: string; hasReceipt?: boolean; @@ -37,6 +50,7 @@ export type TransactionContextType = { receipt?: TransactionReceipt; // The receipt of the transaction setErrorMessage: (error: string) => void; // A function to set the error message for the transaction. 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. statusWriteContract?: string; // An optional string indicating the current status of the transaction. statusWriteContracts?: string; // An optional string indicating the current status of the transaction. @@ -66,6 +80,7 @@ export type TransactionProviderReact = { children: ReactNode; // The child components to be rendered within the provider component. contracts: ContractFunctionParameters[]; // An array of contract function parameters provided to the child components. 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 }; @@ -80,6 +95,7 @@ export type TransactionReact = { className?: string; // An optional CSS class name for styling the component. contracts: ContractFunctionParameters[]; // An array of contract function parameters for the transaction. 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 }; @@ -151,20 +167,20 @@ export type TransactionToastLabelReact = { }; export type UseCallsStatusParams = { - onError?: (e: TransactionError) => void; + setLifeCycleStatus: (state: LifeCycleStatus) => void; transactionId: string; }; export type UseWriteContractParams = { - onError?: (e: TransactionError) => void; setErrorMessage: (error: string) => void; + setLifeCycleStatus: (state: LifeCycleStatus) => void; setTransactionHashArray: (ids: Address[]) => void; transactionHashArray?: Address[]; }; export type UseWriteContractsParams = { - onError?: (e: TransactionError) => void; setErrorMessage: (error: string) => void; + setLifeCycleStatus: (state: LifeCycleStatus) => void; setTransactionId: (id: string) => void; }; diff --git a/vitest.config.ts b/vitest.config.ts index 32a29fcbbe..03347a424a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -22,10 +22,10 @@ export default defineConfig({ ], reportOnFailure: true, thresholds: { - statements: 99.42, - branches: 98.62, - functions: 96.71, - lines: 99.42, + statements: 99.43, + branches: 98.63, + functions: 96.72, + lines: 99.43, }, }, environment: 'jsdom',