// src/hooks/usePrivySmartWalletDeposit.ts
import { useState, useCallback } from "react";
import { useSmartWallets } from "@privy-io/react-auth/smart-wallets";
import { encodeFunctionData, formatUnits } from "viem";
import {
prepareDepositAuthorization,
prepareDeposit,
isApprovalAuth,
isAlreadyApprovedAuth,
YieldType,
} from "@paxoslabs/amplify-sdk";
interface DepositParams {
depositAsset: `0x${string}`;
amount: bigint;
signerAddress: `0x${string}`;
yieldType: YieldType;
}
export function usePrivySmartWalletDeposit() {
const { client: smartWalletClient } = useSmartWallets();
const [status, setStatus] = useState<string>("");
const [isLoading, setIsLoading] = useState(false);
const deposit = useCallback(
async ({ depositAsset, amount, signerAddress, yieldType }: DepositParams) => {
if (!smartWalletClient) {
throw new Error("Smart wallet not connected");
}
setIsLoading(true);
try {
const params = {
yieldType,
depositAsset,
depositAmount: formatUnits(amount, 6),
to: signerAddress,
chainId: 1,
forceMethod: "approval" as const, // Smart wallets can't sign permits
};
// Step 1: Get authorization (forces approval method)
setStatus("Preparing transaction...");
const auth = await prepareDepositAuthorization(params);
// Step 2: Prepare deposit tx
const prepared = await prepareDeposit(params);
// Step 3: Batch approve + deposit in ONE transaction
if (isApprovalAuth(auth)) {
const calls = [
{
to: auth.txData.address, // Token contract
data: encodeFunctionData({
abi: auth.txData.abi,
functionName: auth.txData.functionName,
args: auth.txData.args,
}),
},
{
to: prepared.txData.address, // Depositor contract
data: encodeFunctionData({
abi: prepared.txData.abi,
functionName: prepared.txData.functionName,
args: prepared.txData.args,
}),
},
];
setStatus("Please confirm in your wallet...");
// Single batched transaction with gas sponsorship
const hash = await smartWalletClient.sendTransaction(
{ calls },
{
sponsor: true, // Gas is sponsored
uiOptions: {
description: `Depositing ${formatUnits(amount, 6)} tokens`,
},
}
);
setStatus("Deposit successful!");
return hash;
} else if (isAlreadyApprovedAuth(auth)) {
// No approval needed, just deposit
setStatus("Please confirm in your wallet...");
const hash = await smartWalletClient.sendTransaction(
{
calls: [
{
to: prepared.txData.address,
data: encodeFunctionData({
abi: prepared.txData.abi,
functionName: prepared.txData.functionName,
args: prepared.txData.args,
}),
},
],
},
{
sponsor: true,
uiOptions: {
description: `Depositing ${formatUnits(amount, 6)} tokens`,
},
}
);
setStatus("Deposit successful!");
return hash;
}
} catch (error) {
setStatus(`Error: ${error instanceof Error ? error.message : "Unknown"}`);
throw error;
} finally {
setIsLoading(false);
}
},
[smartWalletClient]
);
return { deposit, status, isLoading };
}