nac-presale/contracts/usePresale_old.ts.bak

111 lines
3.5 KiB
TypeScript

// NAC XIC Presale — Purchase Logic Hook
// Handles BSC USDT, ETH USDT purchase flows
import { useState, useCallback } from "react";
import { Contract, parseUnits, formatUnits } from "ethers";
import { CONTRACTS, PRESALE_ABI, ERC20_ABI, PRESALE_CONFIG } from "@/lib/contracts";
import { WalletState } from "./useWallet";
export type PurchaseStep =
| "idle"
| "approving"
| "approved"
| "purchasing"
| "success"
| "error";
// All 6 steps are valid
export interface PurchaseState {
step: PurchaseStep;
txHash: string | null;
error: string | null;
tokenAmount: number;
}
export function usePresale(wallet: WalletState, network: "BSC" | "ETH") {
const [purchaseState, setPurchaseState] = useState<PurchaseState>({
step: "idle",
txHash: null,
error: null,
tokenAmount: 0,
});
const networkConfig = CONTRACTS[network];
const buyWithUSDT = useCallback(
async (usdtAmount: number) => {
if (!wallet.signer || !wallet.address) {
setPurchaseState(s => ({ ...s, step: "error", error: "Please connect your wallet first." }));
return;
}
const tokenAmount = usdtAmount / PRESALE_CONFIG.tokenPrice;
setPurchaseState({ step: "approving", txHash: null, error: null, tokenAmount });
try {
// USDT on BSC has 18 decimals, on ETH has 6 decimals
const usdtDecimals = network === "ETH" ? 6 : 18;
const usdtAmountWei = parseUnits(usdtAmount.toString(), usdtDecimals);
// Step 1: Approve USDT spending
const usdtContract = new Contract(networkConfig.usdt, ERC20_ABI, wallet.signer);
const presaleAddress = networkConfig.presale;
// Check current allowance
const currentAllowance = await usdtContract.allowance(wallet.address, presaleAddress);
if (currentAllowance < usdtAmountWei) {
const approveTx = await usdtContract.approve(presaleAddress, usdtAmountWei);
await approveTx.wait();
}
setPurchaseState(s => ({ ...s, step: "approved" }));
// Step 2: Buy tokens
const presaleContract = new Contract(presaleAddress, PRESALE_ABI, wallet.signer);
const buyTx = await presaleContract.buyTokensWithUSDT(usdtAmountWei);
setPurchaseState(s => ({ ...s, step: "purchasing", txHash: buyTx.hash }));
await buyTx.wait();
setPurchaseState(s => ({ ...s, step: "success" }));
} catch (err: unknown) {
const errMsg = (err as { reason?: string; message?: string }).reason
|| (err as Error).message
|| "Transaction failed";
setPurchaseState(s => ({ ...s, step: "error", error: errMsg }));
}
},
[wallet, network, networkConfig]
);
const reset = useCallback(() => {
setPurchaseState({ step: "idle", txHash: null, error: null, tokenAmount: 0 });
}, []);
// Calculate token amount from USDT input
const calcTokens = (usdtAmount: number): number => {
return usdtAmount / PRESALE_CONFIG.tokenPrice;
};
// Get user's USDT balance
const getUsdtBalance = useCallback(async (): Promise<number> => {
if (!wallet.provider || !wallet.address) return 0;
try {
const usdtDecimals = network === "ETH" ? 6 : 18;
const usdtContract = new Contract(networkConfig.usdt, ERC20_ABI, wallet.provider);
const balance = await usdtContract.balanceOf(wallet.address);
return parseFloat(formatUnits(balance, usdtDecimals));
} catch {
return 0;
}
}, [wallet, network, networkConfig]);
return {
purchaseState,
buyWithUSDT,
reset,
calcTokens,
getUsdtBalance,
};
}