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?

Choose one answer

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?

Choose one answer

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.