Files
solace-bg-dubai/frontend/app/send/page.tsx
defiQUG c94eb595f8
Some checks failed
CI / lint-and-test (push) Has been cancelled
Initial commit: add .gitignore and README
2026-02-09 21:51:53 -08:00

133 lines
4.1 KiB
TypeScript

"use client";
import { useState } from "react";
import { useAccount, useBalance, useWriteContract } from "wagmi";
import { parseEther, isAddress } from "viem";
import { WalletConnect } from "@/components/web3/WalletConnect";
import { TREASURY_WALLET_ABI, CONTRACT_ADDRESSES } from "@/lib/web3/contracts";
export default function SendPage() {
const { address, isConnected } = useAccount();
const { data: balance } = useBalance({ address });
const { writeContract } = useWriteContract();
const [recipient, setRecipient] = useState("");
const [amount, setAmount] = useState("");
const [memo, setMemo] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
if (!isConnected) {
return (
<div className="min-h-screen p-8">
<div className="max-w-2xl mx-auto">
<WalletConnect />
</div>
</div>
);
}
const handleSend = async () => {
setError("");
setLoading(true);
try {
if (!isAddress(recipient)) {
throw new Error("Invalid recipient address");
}
if (!amount || parseFloat(amount) <= 0) {
throw new Error("Invalid amount");
}
if (!CONTRACT_ADDRESSES.TreasuryWallet) {
throw new Error("Treasury wallet not configured");
}
const value = parseEther(amount);
// Propose transaction on treasury wallet
await writeContract({
address: CONTRACT_ADDRESSES.TreasuryWallet as `0x${string}`,
abi: TREASURY_WALLET_ABI,
functionName: "proposeTransaction",
args: [recipient as `0x${string}`, value, "0x"],
});
} catch (err: unknown) {
const error = err instanceof Error ? err : new Error(String(err));
setError(error.message || "Transaction failed");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen p-8">
<div className="max-w-2xl mx-auto">
<header className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold">Send Payment</h1>
<WalletConnect />
</header>
<div className="bg-gray-900 rounded-xl p-8 space-y-6">
<div>
<label className="block text-sm font-medium mb-2">Recipient Address</label>
<input
type="text"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
placeholder="0x..."
className="w-full bg-gray-800 rounded-lg p-3 font-mono text-sm"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">
Amount ({balance?.symbol || "ETH"})
</label>
<input
type="number"
step="any"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="0.0"
className="w-full bg-gray-800 rounded-lg p-3"
/>
{balance && (
<p className="text-sm text-gray-400 mt-1">
Available: {balance.formatted} {balance.symbol}
</p>
)}
</div>
<div>
<label className="block text-sm font-medium mb-2">Memo (Optional)</label>
<input
type="text"
value={memo}
onChange={(e) => setMemo(e.target.value)}
placeholder="Payment reference..."
className="w-full bg-gray-800 rounded-lg p-3"
/>
</div>
{error && (
<div className="bg-red-900/20 border border-red-600 rounded-lg p-4">
<p className="text-red-400">{error}</p>
</div>
)}
<button
onClick={handleSend}
disabled={loading || !recipient || !amount}
className="w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-700 disabled:cursor-not-allowed rounded-lg transition-colors font-semibold"
>
{loading ? "Processing..." : "Send Payment"}
</button>
</div>
</div>
</div>
);
}