// 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}`
vaultName: string
}
export function usePrivySmartWalletDeposit() {
const { client: smartWalletClient } = useSmartWallets()
const [status, setStatus] = useState<string>('')
const [isLoading, setIsLoading] = useState(false)
const deposit = useCallback(
async ({
depositAsset,
amount,
signerAddress,
vaultName,
}: DepositParams) => {
if (!smartWalletClient) {
throw new Error('Smart wallet not connected')
}
setIsLoading(true)
try {
const params = {
vaultName,
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 }
}