# Wagmi `useWriteContract` with transaction status

This recipe demonstrates how to create a button for contract interaction using the "useTransactor" and "useWriteContract" hooks from the "wagmi" library. The interaction includes the capability to provide feedback on the transaction status when using wagmi `useWriteContract`.

<details open>
  <summary>Here is the full code, which we will be implementing in the guide below:</summary>

  ```tsx title="components/ContractInteraction.tsx"
  import * as React from "react";
  import { parseEther } from "viem";
  import { useWriteContract } from "wagmi";
  import DeployedContracts from "~~/contracts/deployedContracts";
  import { useTransactor } from "~~/hooks/scaffold-eth";

  export const ContractInteraction = () => {
    const { writeContractAsync, isPending } = useWriteContract();

    const writeContractAsyncWithParams = () =>
      writeContractAsync({
        address: DeployedContracts[31337].YourContract.address,
        abi: DeployedContracts[31337].YourContract.abi,
        functionName: "setGreeting",
        value: parseEther("0.01"),
        args: ["Hello world!"],
      });

    const writeTx = useTransactor();

    const handleSetGreeting = async () => {
      try {
        await writeTx(writeContractAsyncWithParams, { blockConfirmations: 1 });
      } catch (e) {
        console.log("Unexpected error in writeTx", e);
      }
    };

    return (
      <button
        className="btn btn-primary"
        onClick={handleSetGreeting}
        disabled={isPending}
      >
        {isPending ? <span className="loading loading-spinner loading-sm"></span> : "Send"}
      </button>
    );
  };
  ```
</details>

## Implementation

### Step 1: Set Up Your Component

Create a new component in the "components" folder. The component will show a button that will allow users to interact with your smart contract.

```tsx title="components/ContractInteraction.tsx"
import * as React from "react";

export const ContractInteraction = () => {
  return <button>Send</button>;
};
```

### Step 2: Configure wagmi's `useWriteContract` hook

Add wagmi's `useWriteContract` hook and configure `writeContractAsync` with the parameters: `abi`, `address`, `functionName`, `value` and `args`. Get the ABI and address of your smart contract from the DeployedContracts or you can grab it from ExternalContracts object, those will be used to set up the contract interaction.

```tsx
import * as React from "react";
import { parseEther } from "viem"; // [!code hl]
import { useWriteContract } from "wagmi"; // [!code hl]
import DeployedContracts from "~~/contracts/deployedContracts"; // [!code hl]

export const ContractInteraction = () => {
  const { writeContractAsync } = useWriteContract(); // [!code hl]

  const writeContractAsyncWithParams = () => // [!code hl]
    writeContractAsync({ // [!code hl]
      address: DeployedContracts[31337].YourContract.address, // [!code hl]
      abi: DeployedContracts[31337].YourContract.abi, // [!code hl]
      functionName: "setGreeting", // [!code hl]
      value: parseEther("0.01"), // [!code hl]
      args: ["Hello world!"], // [!code hl]
    }); // [!code hl]
  return <button>Send</button>;
};
```

### Step 3: Initialize `useTransactor` hook and send transaction

Initialize the `useTransactor` hook, and use it to wrap `writeContractAsyncWithParams` function which we got from `useWriteContract` to show feedback transaction status to user.

```tsx
import * as React from "react";
import { parseEther } from "viem";
import { useWriteContract } from "wagmi";
import DeployedContracts from "~~/contracts/deployedContracts";
import { useTransactor } from "~~/hooks/scaffold-eth"; // [!code hl]

export const ContractInteraction = () => {
  const { writeContractAsync } = useWriteContract();

  const writeContractAsyncWithParams = () =>
    writeContractAsync({
      address: DeployedContracts[31337].YourContract.address,
      abi: DeployedContracts[31337].YourContract.abi,
      functionName: "setGreeting",
      value: parseEther("0.01"),
      args: ["Hello world!"],
    });

  const writeTx = useTransactor(); // [!code hl]

  return <button onClick={() => writeTx(writeContractAsyncWithParams, { blockConfirmations: 1 })}>Send</button>{/* // [!code hl] */};
};
```

### Step 4: Wrap `useTransactor` in a handler async function

Wrap the `writeTx` function in a handler function to start the transaction when the user clicks the button.

```tsx
import * as React from "react";
import { parseEther } from "viem";
import { useWriteContract } from "wagmi";
import DeployedContracts from "~~/contracts/deployedContracts";
import { useTransactor } from "~~/hooks/scaffold-eth";

export const ContractInteraction = () => {
  const { writeContractAsync } = useWriteContract();

  const writeContractAsyncWithParams = () =>
    writeContractAsync({
      address: DeployedContracts[31337].YourContract.address,
      abi: DeployedContracts[31337].YourContract.abi,
      functionName: "setGreeting",
      value: parseEther("0.01"),
      args: ["Hello world!"],
    });

  const writeTx = useTransactor();

  const handleSetGreeting = async () => { // [!code hl]
    try { // [!code hl]
      await writeTx(writeContractAsyncWithParams, { blockConfirmations: 1 }); // [!code hl]
    } catch (e) { // [!code hl]
      console.log("Unexpected error in writeTx", e); // [!code hl]
    } // [!code hl]
  }; // [!code hl]

  return (
    <button className="btn btn-primary" onClick={handleSetGreeting}>{/* // [!code hl] */}
      Send
    </button>
  );
};
```

### Step 5: Bonus adding loading state

We can use `isPending` returned from `useWriteContract` while the transaction is being mined and also `disable` the button.

```tsx
import * as React from "react";
import { parseEther } from "viem";
import { useWriteContract } from "wagmi";
import DeployedContracts from "~~/contracts/deployedContracts";
import { useTransactor } from "~~/hooks/scaffold-eth";

export const ContractInteraction = () => {
  const { writeContractAsync, isPending } = useWriteContract(); // [!code hl]

  const writeContractAsyncWithParams = () =>
    writeContractAsync({
      address: DeployedContracts[31337].YourContract.address,
      abi: DeployedContracts[31337].YourContract.abi,
      functionName: "setGreeting",
      value: parseEther("0.01"),
      args: ["Hello world!"],
    });

  const writeTx = useTransactor();

  const handleSetGreeting = async () => {
    try {
      await writeTx(writeContractAsyncWithParams, { blockConfirmations: 1 });
    } catch (e) {
      console.log("Unexpected error in writeTx", e);
    }
  };

  return (
    <button
      className="btn btn-primary"
      onClick={handleSetGreeting}
      disabled={isPending} // [!code hl]
    >
      {isPending ? <span className="loading loading-spinner loading-sm"></span> : "Send"}{/* // [!code hl] */}
    </button>
  );
};
```
