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:
- Add the hook
- 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) - Pass these values to
usePrepareSendTransaction
import * as React from 'react'
import { useDebounce } from 'use-debounce'
import { usePrepareSendTransaction } from 'wagmi'
import { utils } from 'ethers';
export function SendTransaction() {
const [to, setTo] = React.useState('')
const [debouncedTo] = useDebounce(to, 500)
const [amount, setAmount] = React.useState('')
const [debouncedValue] = useDebounce(amount, 500)
const { config } = usePrepareSendTransaction({
request: {
to: debouncedTo,
value: debouncedValue ? utils.parseEther(debouncedValue) : 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>Send</button>
</form>
)
}
Step 5: Add the useSendTransaction
hook
Now add the useSendTransaction
hook. This hook performs the actual transaction.
We will need to:
- Add the hook.
- Pass in the configuration (
config
) that we created in the previous step. - Hook it up to our form element via an
onSubmit
prop. - 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'
export function SendTransaction() {
const [to, setTo] = React.useState('')
const [debouncedTo] = useDebounce(to, 500)
const [amount, setAmount] = React.useState('')
const [debouncedValue] = useDebounce(value, 500)
const { config } = usePrepareSendTransaction({
request: {
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 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:
- Add the hook
- Add loading state to the button when the transaction is pending.
- 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'
export function SendTransaction() {
const [to, setTo] = React.useState('')
const [debouncedTo] = useDebounce(to, 500)
const [amount, setAmount] = React.useState('')
const [debouncedValue] = useDebounce(value, 500)
const { config } = usePrepareSendTransaction({
request: {
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 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.