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
};
/**