diff --git a/playground/nextjs-app-router/components/demo/Earn.tsx b/playground/nextjs-app-router/components/demo/Earn.tsx index d30287de4f..c11ec7f249 100644 --- a/playground/nextjs-app-router/components/demo/Earn.tsx +++ b/playground/nextjs-app-router/components/demo/Earn.tsx @@ -1,13 +1,37 @@ import { AppContext } from '@/components/AppProvider'; -import { Earn } from '@coinbase/onchainkit/earn'; -import { useContext } from 'react'; +import { Earn, LifecycleStatus } from '@coinbase/onchainkit/earn'; +import { TransactionError } from '@coinbase/onchainkit/transaction'; +import { useCallback, useContext } from 'react'; +import { TransactionReceipt } from 'viem'; export function EarnDemo() { const { vaultAddress } = useContext(AppContext); + const handleOnSuccess = useCallback( + (transactionReceipt?: TransactionReceipt) => { + console.log('Success: ', transactionReceipt); + }, + [], + ); + + const handleOnError = useCallback((earnError: TransactionError) => { + console.log('Error:', earnError); + }, []); + + const handleOnStatus = useCallback((lifecycleStatus: LifecycleStatus) => { + console.log('Status:', lifecycleStatus); + }, []); + if (!vaultAddress) { return
Please set a vault address
; } - return ; + return ( + + ); } diff --git a/src/earn/components/Earn.tsx b/src/earn/components/Earn.tsx index 34922bde40..81e2c2eb13 100644 --- a/src/earn/components/Earn.tsx +++ b/src/earn/components/Earn.tsx @@ -54,10 +54,19 @@ export function Earn({ className, vaultAddress, isSponsored, + onError, + onStatus, + onSuccess, }: EarnReact) { const componentTheme = useTheme(); return ( - +
{ + if (lifecycleStatus.statusName === 'error') { + onError?.(lifecycleStatus.statusData); + } + if (lifecycleStatus?.statusName === 'success') { + onSuccess?.(lifecycleStatus?.statusData?.transactionReceipts?.[0]); + } + onStatus?.(lifecycleStatus); + }, [lifecycleStatus]); + const { asset, balance: depositedBalance, diff --git a/src/earn/types.ts b/src/earn/types.ts index a7d224840d..a9b11b0847 100644 --- a/src/earn/types.ts +++ b/src/earn/types.ts @@ -1,10 +1,11 @@ +import type { TransactionError } from '@/api/types'; import type { UseMorphoVaultReturnType } from '@/earn/hooks/useMorphoVault'; import type { LifecycleStatusUpdate } from '@/internal/types'; import type { Token } from '@/token'; import type { Call } from '@/transaction/types'; import type { LifecycleStatus as TransactionLifecycleStatus } from '@/transaction/types'; import type React from 'react'; -import type { Address } from 'viem'; +import type { Address, TransactionReceipt } from 'viem'; /** * Note: exported as public Type @@ -14,6 +15,9 @@ export type EarnReact = { className?: string; vaultAddress: Address; isSponsored?: boolean; + onError?: (error: 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?: (transactionReceipt?: TransactionReceipt) => void; // An optional callback function that exposes the transaction receipt }; /** @@ -23,6 +27,9 @@ export type EarnProviderReact = { children: React.ReactNode; vaultAddress: Address; isSponsored?: boolean; + onError?: (error: 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?: (transactionReceipt?: TransactionReceipt) => void; // An optional callback function that exposes the transaction receipt }; /**