• Examples
  • Send Transaction

Send Transaction

The following example teaches you how to send transactions in wagmi. The example below builds on the Connect Wallet Example and uses the usePrepareSendTransaction, useSendTransaction & useWaitForTransaction hooks. Try it out before moving on.

Step 1: Connect Wallet

Follow the Connect Wallet guide to get this set up.

Step 2: Create a new component

Create a new component that will contain the send transaction logic.

import * as React from 'react'
 
export function SendTransaction() {
  return (
    <form>
      <input aria-label="Recipient" placeholder="0xA0Cf…251e" />
      <input aria-label="Amount (ether)" placeholder="0.05" />
      <button>Send</button>
    </form>
  )
}

Step 3: Set up some form state

Hook up your form to some simple state.

import * as React from 'react'
 
export function SendTransaction() {
  const [to, setTo] = React.useState('')
 
  const [amount, setAmount] = React.useState('')
 
  return (
    <form>
      <input
        aria-label="Recipient"
        onChange={(e) => setTo(e.target.value)}
        placeholder="0xA0Cf…251e"
        value={to}
      />
      <input
        aria-label="Amount (ether)"
        onChange={(e) => setAmount(e.target.value)}
        placeholder="0.05"
        value={amount}
      />
      <button disabled={!to || !amount}>Send</button>
    </form>
  )
}

Step 4: Add the usePrepareSendTransaction hook

Create a new component and add the usePrepareSendTransaction hook. This hook eagerly fetches the parameters required for sending a transaction such as the gas estimate.

You will need to:

  1. Add the hook
  2. Add a debounce to your input values (we don't want to call the RPC on every keystroke – we are using the use-debounce package in this example)
  3. Pass these values to usePrepareSendTransaction
import * as React from 'react'
import { useDebounce } from 'use-debounce'
import { usePrepareSendTransaction } from 'wagmi'
import { parseEther } from 'viem'
 
export function SendTransaction() {
  const [to, setTo] = React.useState('')
  const [debouncedTo] = useDebounce(to, 500)
 
  const [amount, setAmount] = React.useState('')
  const [debouncedAmount] = useDebounce(amount, 500)
 
  const { config } = usePrepareSendTransaction({
    to: debouncedTo,
    value: debouncedAmount ? parseEther(debouncedAmount) : undefined,
  })
 
  return (
    <form>
      <input
        aria-label="Recipient"
        onChange={(e) => setTo(e.target.value)}
        placeholder="0xA0Cf…251e"
        value={to}
      />
      <input
        aria-label="Amount (ether)"
        onChange={(e) => setAmount(e.target.value)}
        placeholder="0.05"
        value={amount}
      />
      <button type="submit">Send</button>
    </form>
  )
}

Step 5: Add the useSendTransaction hook

Now add the useSendTransaction hook. This hook performs the actual transaction.

We will need to:

  1. Add the hook.
  2. Pass in the configuration (config) that we created in the previous step.
  3. Hook it up to our form element via an onSubmit prop.
  4. Disable the "Send" button when the sendTransaction function is not ready (still preparing).
import * as React from 'react'
import { useDebounce } from 'use-debounce'
import { usePrepareSendTransaction, useSendTransaction } from 'wagmi'
import { parseEther } from 'viem'
 
export function SendTransaction() {
  const [to, setTo] = React.useState('')
  const [debouncedTo] = useDebounce(to, 500)
 
  const [amount, setAmount] = React.useState('')
  const [debouncedAmount] = useDebounce(amount, 500)
 
  const { config } = usePrepareSendTransaction({
    to: debouncedTo,
    value: debouncedAmount ? parseEther(debouncedAmount) : undefined,
  })
  const { sendTransaction } = useSendTransaction(config)
 
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault()
        sendTransaction?.()
      }}
    >
      <input
        aria-label="Recipient"
        onChange={(e) => setTo(e.target.value)}
        placeholder="0xA0Cf…251e"
        value={to}
      />
      <input
        aria-label="Amount (ether)"
        onChange={(e) => setAmount(e.target.value)}
        placeholder="0.05"
        value={amount}
      />
      <button type="submit" disabled={!sendTransaction || !to || !amount}>Send</button>
    </form>
  )
}

Clicking the "Send" button will trigger the sendTransaction function and instantiate the transaction.

However, there is currently no feedback on the status of the transaction. We will add some feedback in the next step.

Step 6: Add the useWaitForTransaction hook

Using the useWaitForTransaction hook provides you with the ability to show feedback on the status of the transaction to the user.

We will need to:

  1. Add the hook
  2. Add loading state to the button when the transaction is pending.
  3. Add a success state for when the transaction is successful.
import * as React from 'react'
import { useDebounce } from 'use-debounce'
import {
  usePrepareSendTransaction,
  useSendTransaction,
  useWaitForTransaction,
} from 'wagmi'
import { parseEther } from 'viem'
 
export function SendTransaction() {
  const [to, setTo] = React.useState('')
  const [debouncedTo] = useDebounce(to, 500)
 
  const [amount, setAmount] = React.useState('')
  const [debouncedAmount] = useDebounce(amount, 500)
 
  const { config } = usePrepareSendTransaction({
    to: debouncedTo,
    value: debouncedAmount ? parseEther(debouncedAmount) : undefined,
  })
  const { data, sendTransaction } = useSendTransaction(config)
 
  const { isLoading, isSuccess } = useWaitForTransaction({
    hash: data?.hash,
  })
 
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault()
        sendTransaction?.()
      }}
    >
      <input
        aria-label="Recipient"
        onChange={(e) => setTo(e.target.value)}
        placeholder="0xA0Cf…251e"
        value={to}
      />
      <input
        aria-label="Amount (ether)"
        onChange={(e) => setAmount(e.target.value)}
        placeholder="0.05"
        value={amount}
      />
      <button type="submit" disabled={isLoading || !sendTransaction || !to || !amount}>
        {isLoading ? 'Sending...' : 'Send'}
      </button>
      {isSuccess && (
        <div>
          Successfully sent {amount} ether to {to}
          <div>
            <a href={`https://etherscan.io/tx/${data?.hash}`}>Etherscan</a>
          </div>
        </div>
      )}
    </form>
  )
}

Step 7: Add To App

Import the SendTransaction component and display it when the account is connected.

import { useAccount, useConnect, useDisconnect } from 'wagmi'
 
import { SendTransaction } from './SendTransaction'
 
export function App() {
  const { isConnected } = useAccount()
 
  if (isConnected) {
    return (
      <div>
        {/* Account content goes here */}
        <SendTransaction />
      </div>
    )
  }
 
  return <div>{/* Connect wallet content goes here */}</div>
}

Wrap Up

That's it! You have now added a basic send transaction component to your app.