TransactionButton
A button that handles the full transaction lifecycle — from wallet confirmation through on-chain mining to success or failure. Provides visual state feedback, automatic reset, and success/error callbacks.
import { TransactionButton } from '@web3marketlabs/react'
<TransactionButton
onClick={async () => {
return writeContract({ ... })
}}
label="Transfer Tokens"
onSuccess={(hash) => console.log('Tx:', hash)}
/>Props
TransactionButtonProps
Transaction States
The button transitions through five states during the transaction lifecycle:
| # | State | Label | Color | Description |
|---|---|---|---|---|
| 1 | Idle | label | Blue (#3182ce) | Ready to click. The button is enabled and waiting for user interaction. |
| 2 | Confirming | confirmingLabel | Yellow (#d69e2e) | The onClick function has been called. Waiting for the user to confirm the transaction in their wallet. Shows a spinner. |
| 3 | Pending | pendingLabel | Yellow (#d69e2e) | The wallet returned a transaction hash. Waiting for the transaction to be mined and confirmed on-chain. Shows a spinner. |
| 4 | Success | successLabel | Green (#38a169) | The transaction receipt was received and confirmed. Auto-resets to idle after resetTimeout milliseconds. |
| 5 | Error | errorLabel | Red (#e53e3e) | The transaction was rejected by the wallet, the onClick function threw an error, or the transaction failed on-chain. Shows the error message below the button. Auto-resets to idle after resetTimeout milliseconds. |
The button is disabled in all non-idle states. It also shows reduced opacity (0.5) and a not-allowed cursor when disabled.
Lifecycle
- User clicks the button in idle state.
- State moves to confirming. The
onClickfunction is called. - If
onClickresolves with a transaction hash, state moves to pending. The component uses Wagmi’suseWaitForTransactionReceiptto watch for confirmation. - When the receipt arrives:
- If successful, state moves to success and
onSuccess(hash)is called. - If the receipt indicates failure, state moves to error and
onError(error)is called with"Transaction failed on-chain".
- If successful, state moves to success and
- If
onClickthrows (e.g., user rejected in wallet), state moves directly to error andonError(error)is called. - After
resetTimeoutmilliseconds in success or error state, the button resets to idle.
Examples
Basic transfer
import { useWriteContract } from 'wagmi'
import { TransactionButton } from '@web3marketlabs/react'
import { parseEther } from 'viem'
function SendEth() {
const { writeContractAsync } = useWriteContract()
return (
<TransactionButton
label="Send 0.1 ETH"
onClick={() =>
writeContractAsync({
address: '0x...',
abi: tokenAbi,
functionName: 'transfer',
args: ['0x...', parseEther('0.1')],
})
}
onSuccess={(hash) => {
console.log('Transaction confirmed:', hash)
}}
onError={(error) => {
console.error('Transaction failed:', error.message)
}}
/>
)
}Custom labels
<TransactionButton
onClick={handleMint}
label="Mint NFT"
pendingLabel="Minting..."
confirmingLabel="Approve in Wallet..."
successLabel="Minted!"
errorLabel="Mint Failed"
resetTimeout={5000}
/>Disabled state
<TransactionButton
onClick={handleTransfer}
label="Transfer"
disabled={!isFormValid}
/>Source
export interface TransactionButtonProps {
onClick: () => Promise<Hash>
label?: string
pendingLabel?: string
confirmingLabel?: string
successLabel?: string
errorLabel?: string
disabled?: boolean
className?: string
style?: CSSProperties
resetTimeout?: number
onSuccess?: (hash: Hash) => void
onError?: (error: Error) => void
}Defined in @web3marketlabs/react — src/components/TransactionButton.tsx.