How to get the state of a transaction in React using Wagmi
Learn how to get the state of a transaction in your React application using Wagmi and the useTransaction hook and the getTransactionReceipt function from Ethers JS.
In this tutorial, we are going to learn how to get the state of a transaction in your React application using Wagmi and the useTransaction
hook and the getTransactionReceipt
function from Ethers JS.
Here is the code to do that:
import { useTransaction } from 'wagmi'
function MyComponent() {
const { data, error, isError, isLoading } = useTransaction({
hash: '0xce76905eccd581d556969158cf410318ff0282350e8258553e85f81fb9150277',
})
// isLoading is true while fetching the transaction
if (isLoading) return <span>Loading transaction...</span>
// isError is true if the transaction was not found.
// There might be an error with the transaction hash or the network
if (isError) return <p>Could not get the transaction: {error}</p>
// If the transaction was successfully fetched, the transaction information is in the data returned by the hook
return <p>The transaction data: {JSON.stringify(data)}</p>
}
In the code above, first we call the the useTransaction
hook and in the parameters of the hook we pass the hash of the transaction we want to get. If no hash
is passed or it's null
, it won't try to fetch anything.
The useTransaction
hook returns a few properties that you can find here but the ones that we use the most are these:
data
is an object that contains information about your transaction. The data object is a TransactionResponse object from EthersJSerror
will be null if the data was fetched successfully, otherwise it contains the error and a message telling why the transaction could not be fetchedisLoading
will betrue
while the transaction is being fetched andfalse
otherwise.isError
will betrue
if there was an error fetching the transaction andfalse
otherwise
The data contains a TransactionResponse
which will have the following properties:
blockNumber
: The number of the block this transaction will be mined in ornull
if the transaction is pendingblockHash
: The hash of the block this transaction will be mined in ornull
if the transaction is pendingtimestamp
: The timestamp of the block this transaction will be mined in ornull
if the transaction is pendingconfirmations
: The confirmations that the transaction has. It corresponds to the number of blocks that have been mined (including the initial block) since this transaction was first included in a block.raw
: A raw hexadecimal string containing information about the transactionwait
: A function that allows you to wait for the transaction to be completed. You can pass the number of confirmation you want to wait for in the parameters of that function and it will return a TransactionReceipt when the transaction is completed or an error if it fails.type
: The EIP-2718 type of this transaction.accessList
: The AccessList array included in the transaction
Getting the state of the transaction based on the returned data
When the transaction is pending or not
As you can see, when you get a transaction using the hook it can still be pending. If the transaction is pending, timestamp
, blockhash
and blockNumber
will be null
and confirmations
will be 0
.
Otherwise, the transaction was confirmed and is completed.
How to see if the transaction was successful or failed
Unfortunately, to get that information you need to get a TransactionReceipt. You don't have that information in the data returned by the useTransaction
hook.
To get the receipt, you can either wait for the transaction to be completed, or call the getTransactionReceipt
function that Ethers JS provides.
We'll see how to do both here.
In the TransactionReceipt object, if the status
property is 1
it means the transaction was successful and if it's 0
it means the transaction failed.
Check out the TransactionReceipt documentation to get more information about the error object and the properties that a transaction receipt contains.
How to wait for a transaction to be completed
If the transaction is still pending, and you want to wait for the transaction to be confirmed and completed, you can either use the wait
function in the data or use the useWaitForTransaction
hook.
Here is an example of how to use wait
and useWaitForTransaction
:
import { useEffect } from 'react';
import { useTransaction, useWaitForTransaction } from 'wagmi';
export const MyComponent = () => {
const { data } = useTransaction({
hash: "0xce76905eccd581d556969158cf410318ff0282350e8258553e85f81fb9150277"
})
// Wait for the transaction using the hook
const {
data: txReceipt,
error: txError,
isLoading: txLoading,
} = useWaitForTransaction({ confirmations: 1, hash: data?.hash });
useEffect(() => {
if (tx.receipt) {
console.log("The transaction was successful, the receipt:", txReceipt)
}
}, [txReceipt])
// Wait for the transaction using the wait function
useEffect(() => {
if (data?.wait) {
data
.wait(1)
.then((receipt) => {
console.log('The transaction was successful', receipt);
})
.catch((err) => {
console.log('The transaction failed:', err);
});
}
}, [data]);
// ... rest of the component
The wait
function will take in parameters the number of confirmations to wait for and will return a Promise
. When that Promise
is resolved, it means the transaction has the confirmations you wanted to wait for so it's not pending anymore and it returns a TransactionReceipt.
If the transaction fails, the Promise will reject and return an error.
The useWaitForTransaction
hook takes in parameter an object which has a hash
property in which you put the hash of the transaction to wait for. You can also pass the number of confirmations to wait for by passing a confirmations
property.
The default number of confirmations is 1 and is enough in most cases.
If you want to see all the options you can pass to the useWaitForTransaction
hook, check out this part of the documentation.
Get the transaction receipt using the getTransactionReceipt function
Now, if you know that the transaction is completed and you want the receipt directly, you can use the getTransactionReceipt
function from Ethers JS which is the library Wagmi is based on.
Here is how to use that function:
export function MyComponent() => {
// ... rest of the code
const provider = useProvider()
// get an Ethers provider using the Wagmi providers in your Wagmi client and use it to call getTransactionReceipt
useEffect(() => {
async function fetchTransaction() {
provider
.getTransactionReceipt(
'0xce76905eccd581d556969158cf410318ff0282350e8258553e85f81fb9150277'
)
.then((receipt) => {
console.log('the transaction receipt:', receipt)
})
.catch((error) => {
console.log('failed to get the transaction:', error)
});
}
fetchTransaction();
}, [provider]);
// ... rest of the code
}
To call that function, we need to access the provider that is in our Wagmi client. That provider is an Ethers JS provider so we can use it to call the getTransactionReceipt
function.
To get that provider, we can use the useProvider
hook from Wagmi.
As you can see, you just need to pass the hash of the transaction you want to get the receipt of and it returns a Promise
that returns the receipt when it resolves and an error when rejected.
And that's it 🎉
Thank you for reading this article