import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { encodeFunctionData } from "viem";
import { mainnet } from "viem/chains";
import {
fetchVaults,
prepareApproveDepositTokenTxData,
prepareApproveWithdrawTxData,
prepareWithdrawTxData,
prepareDepositPermitSignature,
prepareDepositTxData,
prepareDepositWithPermitTxData,
YieldType,
} from "@paxoslabs/amplify-sdk";
import { usePrivy } from "@privy-io/react-auth";
import { useAmplify } from "../hooks/useAmplify";
import { useWalletSession } from "../hooks/useWalletSession";
export function App() {
useAmplify();
const { ready, authenticated, login, logout, wallet } = useWalletSession();
const { sendTransaction } = usePrivy();
const [status, setStatus] = useState<string | null>(null);
const { data: vaults } = useQuery({
queryKey: ["core-vaults", mainnet.id],
enabled: authenticated,
queryFn: () =>
fetchVaults({
chainId: mainnet.id,
yieldType: YieldType.CORE,
}),
});
const coreVault = vaults?.[0];
if (!ready) {
return <p>Loading Privy…</p>;
}
if (!authenticated || !wallet) {
return <button onClick={login}>Connect with Privy</button>;
}
if (!coreVault) {
return <p>Loading vault metadata…</p>;
}
const owner = wallet.address as `0x${string}`;
const depositToken = coreVault.depositTokenAddressId as `0x${string}`;
const chainId = coreVault.chainId;
async function approveAndDeposit() {
setStatus("Preparing approval…");
const approval = await prepareApproveDepositTokenTxData({
chainId,
depositAmount: "100",
depositToken,
yieldType: coreVault.yieldType,
});
setStatus("Sending approval…");
await sendTransaction({
chainId: approval.chainId,
to: approval.address,
data: encodeFunctionData({
abi: approval.abi,
functionName: approval.functionName,
args: approval.args,
}),
});
setStatus("Submitting deposit…");
const deposit = await prepareDepositTxData({
chainId,
depositAmount: "100",
depositToken,
recipientAddress: owner,
yieldType: coreVault.yieldType,
});
await sendTransaction({
chainId: deposit.chainId,
to: deposit.address,
data: encodeFunctionData({
abi: deposit.abi,
functionName: deposit.functionName,
args: deposit.args,
}),
});
setStatus("Deposit sent");
}
async function depositWithPermit() {
setStatus("Creating permit signature…");
const permit = await prepareDepositPermitSignature({
yieldType: coreVault.yieldType,
depositToken,
depositAmount: "100",
recipientAddress: owner,
chainId,
});
const provider = await wallet.getEthereumProvider();
const signature = (await provider.request({
method: "eth_signTypedData_v4",
params: [
owner,
JSON.stringify({
domain: permit.domain,
types: permit.types,
primaryType: permit.primaryType,
message: permit.message,
}),
],
})) as `0x${string}`;
setStatus("Submitting depositWithPermit…");
const tx = await prepareDepositWithPermitTxData({
yieldType: coreVault.yieldType,
recipientAddress: owner,
depositToken,
depositAmount: "100",
chainId,
signature,
deadline: permit.message.deadline,
});
await sendTransaction({
chainId: tx.chainId,
to: tx.address,
data: encodeFunctionData({
abi: tx.abi,
functionName: tx.functionName,
args: tx.args,
}),
});
setStatus("Permit deposit sent");
}
async function approveAndWithdraw() {
setStatus("Preparing withdrawal…");
const approval = await prepareApproveWithdrawTxData({
chainId,
depositAmount: "100",
depositToken,
yieldType: coreVault.yieldType,
});
setStatus("Sending approval…");
await sendTransaction({
chainId: approval.chainId,
to: approval.address,
data: encodeFunctionData({
abi: approval.abi,
functionName: approval.functionName,
args: approval.args,
}),
});
const bulk = await prepareWithdrawTxData({
yieldType: coreVault.yieldType,
shareAmount: "1.0",
wantAssetAddress: depositToken,
chainId,
userAddress: owner,
slippage: 75,
});
await sendTransaction({
chainId: bulk.chainId,
to: bulk.address,
data: encodeFunctionData({
abi: bulk.abi,
functionName: bulk.functionName,
args: bulk.args,
}),
});
setStatus("Withdrawal sent");
}
return (
<main>
<h1>Amplify Earn Starter</h1>
<p>{owner}</p>
{status && <p>{status}</p>}
<div>
<button onClick={approveAndDeposit}>Approve & Deposit</button>
<button onClick={depositWithPermit}>Deposit with Permit</button>
<button onClick={approveAndWithdraw}>Withdraw</button>
</div>
<button onClick={logout}>Disconnect</button>
</main>
);
}