Initial commit with 🏗️ create-eth @ 2.0.4

This commit is contained in:
han
2026-01-23 20:20:58 +07:00
commit b330aba2b4
185 changed files with 36981 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
"use client";
import { useMemo, useState } from "react";
import { erc20Abi, formatEther, parseEther } from "viem";
import { useAccount, useReadContract } from "wagmi";
import { useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";
const ETH_IN = "0.5";
const ORA_OUT = "100";
export const BuyOraWidget = () => {
const { address: connectedAddress } = useAccount();
const [isBuying, setIsBuying] = useState(false);
// NOTE: `deployedContracts.ts` is autogenerated from deployments. If ORA isn't listed yet,
// the hook will show a "Target Contract is not deployed" notification until you run `yarn deploy`.
// We keep TS compiling while deployments/ABIs are catching up.
const { writeContractAsync: writeOraUnsafe } = useScaffoldWriteContract({ contractName: "ORA" as any });
const writeOra = writeOraUnsafe as any;
// Read ORA balance using the token address wired into StakingOracle
const { data: oracleTokenAddress } = useScaffoldReadContract({
contractName: "StakingOracle",
functionName: "oracleToken",
});
const { data: oraBalance, refetch: refetchOraBalance } = useReadContract({
address: oracleTokenAddress as `0x${string}` | undefined,
abi: erc20Abi,
functionName: "balanceOf",
args: connectedAddress ? [connectedAddress] : undefined,
query: { enabled: !!oracleTokenAddress && !!connectedAddress, refetchInterval: 5000 },
});
const oraBalanceFormatted = useMemo(() => {
if (oraBalance === undefined) return "—";
return Number(formatEther(oraBalance as bigint)).toLocaleString(undefined, { maximumFractionDigits: 2 });
}, [oraBalance]);
const handleBuy = async () => {
setIsBuying(true);
try {
await writeOra({
functionName: "buy",
value: parseEther(ETH_IN),
});
// Ensure the widget updates immediately after the tx confirms (instead of waiting for polling).
await refetchOraBalance();
} catch (e: any) {
console.error(e);
} finally {
setIsBuying(false);
}
};
return (
<div className="bg-base-100 rounded-lg p-4 border border-base-300 shadow-sm w-full md:w-auto">
<div className="flex items-start justify-between gap-4">
<div className="min-w-0">
<div className="text-sm font-semibold">Buy ORA</div>
<div className="text-xs text-gray-500 mt-1">
<span className="font-mono">{ETH_IN} ETH</span> <span className="font-mono">{ORA_OUT} ORA</span>
</div>
<div className="text-xs text-gray-500 mt-2">
Your ORA balance: <span className="font-mono">{oraBalanceFormatted}</span>
</div>
</div>
<button className="btn btn-primary btn-sm" onClick={handleBuy} disabled={!connectedAddress || isBuying}>
{isBuying ? "Buying..." : "Buy ORA"}
</button>
</div>
</div>
);
};