Initial commit with 🏗️ create-eth @ 2.0.4
This commit is contained in:
74
packages/nextjs/components/oracle/BuyOraWidget.tsx
Normal file
74
packages/nextjs/components/oracle/BuyOraWidget.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user