Contract Write
The following example teaches you how to implement a simple "Mint NFT" component using wagmi. The example below builds on the Connect Wallet Example and uses the usePrepareContractWrite
, useContractWrite
& 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 NFT mint logic.
import * as React from 'react'
export function MintNFT() {
return (
<div>
<button>Mint</button>
</div>
)
}
Step 3: Add the usePrepareContractWrite
hook
Add the usePrepareContractWrite
hook. This hook eagerly fetches the parameters required for sending a contract write transaction such as the gas estimate.
You will need to:
- Add the hook
- Pass in your contract configuration (address, contract interface, and function name)
import * as React from 'react'
import { usePrepareContractWrite } from 'wagmi'
export function MintNFT() {
const { config } = usePrepareContractWrite({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: [
{
name: 'mint',
type: 'function',
stateMutability: 'nonpayable',
inputs: [],
outputs: [],
},
],
functionName: 'mint',
})
return (
<div>
<button>Mint</button>
</div>
)
}
Step 4: Add the useContractWrite
hook
Now add the useContractWrite
hook. This hook performs the actual contract write 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 button element via an
onClick
prop. - Disable the button when the
write
function is not ready (still preparing).
import * as React from 'react'
import { usePrepareContractWrite, useContractWrite } from 'wagmi'
export function MintNFT() {
const { config } = usePrepareContractWrite({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: [
{
name: 'mint',
type: 'function',
stateMutability: 'nonpayable',
inputs: [],
outputs: [],
},
],
functionName: 'mint',
})
const { write } = useContractWrite(config)
return (
<div>
<button disabled={!write} onClick={() => write?.()}>
Mint
</button>
</div>
)
}
Clicking the "Mint" button will invoke the mint
function on the contract and mint the NFT for the user.
However, there is currently no feedback to show when the mint
transaction is successful. We will add some feedback in the next step.
Step 5: 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 {
usePrepareContractWrite,
useContractWrite,
useWaitForTransaction,
} from 'wagmi'
export function MintNFT() {
const { config } = usePrepareContractWrite({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: [
{
name: 'mint',
type: 'function',
stateMutability: 'nonpayable',
inputs: [],
outputs: [],
},
],
functionName: 'mint',
})
const { data, write } = useContractWrite(config)
const { isLoading, isSuccess } = useWaitForTransaction({
hash: data?.hash,
})
return (
<div>
<button disabled={!write || isLoading} onClick={() => write()}>
{isLoading ? 'Minting...' : 'Mint'}
</button>
{isSuccess && (
<div>
Successfully minted your NFT!
<div>
<a href={`https://etherscan.io/tx/${data?.hash}`}>Etherscan</a>
</div>
</div>
)}
</div>
)
}
Step 6: Add To App
Import the MintNFT
component and display it when the account is connected.
import { useAccount, useConnect, useDisconnect } from 'wagmi'
import { MintNFT } from './MintNFT'
export function App() {
const { isConnected } = useAccount()
if (isConnected) {
return (
<div>
{/* Account content goes here */}
<MintNFT />
</div>
)
}
return <div>{/* Connect wallet content goes here */}</div>
}
Bonus Point: Add some error handling
Now let's provide some feedback to the user if the prepare hook fails, or if the write hook fails.
import * as React from 'react'
import {
usePrepareContractWrite,
useContractWrite,
useWaitForTransaction,
} from 'wagmi'
export function MintNFT() {
const {
config,
error: prepareError,
isError: isPrepareError,
} = usePrepareContractWrite({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: [
{
name: 'mint',
type: 'function',
stateMutability: 'nonpayable',
inputs: [],
outputs: [],
},
],
functionName: 'mint',
})
const { data, error, isError, write } = useContractWrite(config)
const { isLoading, isSuccess } = useWaitForTransaction({
hash: data?.hash,
})
return (
<div>
<button disabled={!write || isLoading} onClick={() => write()}>
{isLoading ? 'Minting...' : 'Mint'}
</button>
{isSuccess && (
<div>
Successfully minted your NFT!
<div>
<a href={`https://etherscan.io/tx/${data?.hash}`}>Etherscan</a>
</div>
</div>
)}
{(isPrepareError || isError) && (
<div>Error: {(prepareError || error)?.message}</div>
)}
</div>
)
}
Wrap Up
That's it! You have now added a basic "Mint NFT" component to your app.