/**
* useVaultDeposit Hook
*
* Custom React hook that encapsulates the complete vault deposit flow:
* - Check approval status
* - Approve deposit tokens
* - Execute deposit transaction
*/
import {
isDepositSpendApproved,
prepareApproveDepositToken,
prepareDepositTransactionData,
} from "@paxoslabs/earn-sdk";
import { useCallback, useState } from "react";
import type { Address } from "viem";
import { useWaitForTransactionReceipt, useWriteContract } from "wagmi";
interface CheckApprovalParams {
yieldType: string;
depositToken: Address;
depositAmount: string;
recipientAddress: Address;
chainId: number;
}
interface ApproveParams {
yieldType: string;
depositToken: Address;
depositAmount: string;
chainId: number;
}
interface DepositParams {
yieldType: string;
recipientAddress: Address;
depositToken: Address;
depositAmount: string;
chainId: number;
slippage: number;
}
interface UseVaultDepositReturn {
// Actions
checkApproval: (params: CheckApprovalParams) => Promise<void>;
approve: (params: ApproveParams) => Promise<void>;
deposit: (params: DepositParams) => Promise<void>;
reset: () => void;
// State
isApproved: boolean | null;
isCheckingApproval: boolean;
isApprovingToken: boolean;
isDepositing: boolean;
error: Error | null;
approvalHash: Address | null;
depositHash: Address | null;
}
export function useDeposit(): UseVaultDepositReturn {
// State management
const [isApproved, setIsApproved] = useState<boolean | null>(null);
const [isCheckingApproval, setIsCheckingApproval] = useState(false);
const [error, setError] = useState<Error | null>(null);
// Wagmi hooks for writing contracts
const {
writeContractAsync: writeApproval,
data: approvalHash,
isPending: isApprovingToken,
} = useWriteContract();
const {
writeContractAsync: writeDeposit,
data: depositHash,
isPending: isDepositing,
} = useWriteContract();
// Wait for transaction confirmations
const { isLoading: isWaitingForApproval } = useWaitForTransactionReceipt({
hash: approvalHash,
});
const { isLoading: isWaitingForDeposit } = useWaitForTransactionReceipt({
hash: depositHash,
});
/**
* Check if deposit tokens are approved
*/
const checkApproval = useCallback(async (params: CheckApprovalParams) => {
setIsCheckingApproval(true);
setError(null);
try {
const approved = await isDepositSpendApproved({
yieldType: params.yieldType,
depositToken: params.depositToken,
depositAmount: params.depositAmount,
recipientAddress: params.recipientAddress,
chainId: params.chainId,
});
setIsApproved(approved);
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
setError(error);
setIsApproved(null);
} finally {
setIsCheckingApproval(false);
}
}, []);
/**
* Approve deposit tokens
*/
const approve = useCallback(
async (params: ApproveParams) => {
setError(null);
try {
// Prepare approval transaction
const approvalTx = await prepareApproveDepositTxData({
yieldType: params.yieldType,
depositToken: params.depositToken,
depositAmount: params.depositAmount,
chainId: params.chainId,
});
// Execute approval using wagmi
await writeApproval(approvalTx);
// Update approval state after successful transaction
setIsApproved(true);
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
setError(error);
throw error;
}
},
[writeApproval]
);
/**
* Execute deposit transaction
*/
const deposit = useCallback(
async (params: DepositParams) => {
setError(null);
try {
// Prepare deposit transaction
const depositTx = await prepareDepositTxData({
yieldType: params.yieldType,
recipientAddress: params.recipientAddress,
depositToken: params.depositToken,
depositAmount: params.depositAmount,
chainId: params.chainId,
slippage: params.slippage,
});
// Execute deposit using wagmi
await writeDeposit(depositTx);
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
setError(error);
throw error;
}
},
[writeDeposit]
);
/**
* Reset hook state
*/
const reset = useCallback(() => {
setIsApproved(null);
setError(null);
}, []);
return {
// Actions
checkApproval,
approve,
deposit,
reset,
// State
isApproved,
isCheckingApproval,
isApprovingToken:
isApprovingToken || isWaitingForApproval || Boolean(approvalHash),
isDepositing: isDepositing || isWaitingForDeposit || Boolean(depositHash),
error,
approvalHash: (approvalHash as Address) || null,
depositHash: (depositHash as Address) || null,
};
}