Track 6 · dApps & frontend · lesson 4
Writing transactions from the UI
12 min
Reading is free and instant. Writing costs gas, needs a signature, and takes time to settle. The UI has to account for all three.
The write
import { useWriteContract } from "wagmi";
function MintButton() {
const { writeContract, isPending } = useWriteContract();
return (
<button
disabled={isPending}
onClick={() =>
writeContract({
address: token,
abi: erc20Abi,
functionName: "mint",
args: [recipient, parseEther("100")],
})
}
>
{isPending ? "Confirm in your wallet…" : "Mint"}
</button>
);
}
writeContract opens the wallet. isPending is true while the user is deciding
— which is the moment to disable the button and tell them to look at their
wallet, or they will click it three more times.
Simulate before you send
The single most useful habit in dApp writing: simulate the call first. It runs the transaction against current state without sending it, so a call that would revert fails before the user pays gas for it.
const { data } = useSimulateContract({
address: token, abi: erc20Abi, functionName: "mint",
args: [recipient, parseEther("100")],
});
// data.request is a pre-flighted call that is known to succeed right now.
writeContract(data!.request);
Predict
Why simulate a transaction before asking the user to sign it?
The signature is not the end
writeContract returns once the user signs and the transaction is broadcast.
That is not the same as done — it is now pending in the mempool, exactly the
lifecycle from track 1. The next lesson is about waiting for it properly.
Check
`writeContract` has returned a transaction hash. What is the transaction's status?
Worth remembering
- `useWriteContract` opens the wallet; `isPending` covers the user deciding — disable the button then.
- Simulate first with `useSimulateContract` to catch reverts before the user pays gas.
- A reverted transaction still costs gas, so pre-flighting is a real kindness.
- A returned hash means broadcast, not confirmed — the lifecycle from track 1 applies.
- Consent is still required for every write; simulation never replaces the signature.