import { useCallback, useEffect, useState } from "react";
import { useWaitForTransactionReceipt, useWriteContract } from "wagmi";
import { prepareWithdrawTxData, type YieldType } from "@paxoslabs/amplify-sdk";
import type { Address } from "viem";
interface BulkWithdrawParams {
yieldType: YieldType;
shareAmount: string;
wantAssetAddress: Address;
chainId: number;
userAddress: Address;
slippage?: number;
}
export function useWithdraw() {
const [error, setError] = useState<Error | null>(null);
const [status, setStatus] = useState<
"idle" | "preparing" | "submitting" | "confirming" | "success"
>("idle");
// Wagmi hooks for writing contracts
const {
writeContractAsync: writeApproval,
data: approvalHash,
isPending: isApprovingToken,
} = useWriteContract();
const {
writeContractAsync,
data: hash,
isPending: isSubmitting,
} = useWriteContract();
// Wait for transaction confirmations
const { isLoading: isWaitingForApproval } = useWaitForTransactionReceipt({
hash: approvalHash,
});
const { isLoading: isConfirming } = useWaitForTransactionReceipt({
hash,
confirmations: 1,
query: { enabled: Boolean(hash) },
});
/**
* Approve deposit tokens
*/
const approve = useCallback(
async (params: ApproveParams) => {
setError(null);
try {
// Prepare approval transaction
const approvalTx = await prepareApproveWithdrawTxData({
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 withdraw transaction
*/
const withdraw = useCallback(
async ({
yieldType,
shareAmount,
wantAssetAddress,
chainId,
userAddress,
slippage = 75,
}: BulkWithdrawParams) => {
setError(null);
setStatus("preparing");
try {
const tx = await prepareWithdrawTxData({
yieldType,
shareAmount,
wantAssetAddress,
chainId,
userAddress,
slippage,
});
setStatus("submitting");
const transactionHash = await writeContractAsync({
...tx,
account: userAddress,
});
setStatus("confirming");
return transactionHash;
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
setError(error);
setStatus("idle");
throw error;
}
},
[writeContractAsync]
);
useEffect(() => {
if (hash && !isSubmitting && !isConfirming) {
setStatus("success");
}
}, [hash, isSubmitting, isConfirming]);
return {
bulkWithdraw,
status,
hash,
error,
isIdle: status === "idle",
isSubmitting,
isConfirming,
isSuccess: status === "success",
};
}