ReactTransactionButton

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

ParameterTypeDescription
onClick*() => Promise<Hash>Async function that initiates the transaction. Must return the transaction hash (0x-prefixed hex string).
labelstringButton label in idle state. Default: "Submit Transaction".
pendingLabelstringLabel while the transaction is being mined. Default: "Transaction Pending...".
confirmingLabelstringLabel while waiting for wallet confirmation. Default: "Confirm in Wallet...".
successLabelstringLabel after a successful transaction. Default: "Transaction Successful".
errorLabelstringLabel after a failed transaction. Default: "Transaction Failed".
disabledbooleanDisable the button. Default: false.
classNamestringCSS class name applied to the button element.
styleCSSPropertiesInline styles merged with the default button styles.
resetTimeoutnumberMilliseconds before resetting to idle state after success or error. Default: 3000.
onSuccess(hash: Hash) => voidCallback invoked when the transaction is confirmed on-chain. Receives the transaction hash.
onError(error: Error) => voidCallback invoked when the transaction fails (either rejected by wallet or failed on-chain).

Transaction States

The button transitions through five states during the transaction lifecycle:

#StateLabelColorDescription
1IdlelabelBlue (#3182ce)Ready to click. The button is enabled and waiting for user interaction.
2ConfirmingconfirmingLabelYellow (#d69e2e)The onClick function has been called. Waiting for the user to confirm the transaction in their wallet. Shows a spinner.
3PendingpendingLabelYellow (#d69e2e)The wallet returned a transaction hash. Waiting for the transaction to be mined and confirmed on-chain. Shows a spinner.
4SuccesssuccessLabelGreen (#38a169)The transaction receipt was received and confirmed. Auto-resets to idle after resetTimeout milliseconds.
5ErrorerrorLabelRed (#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

  1. User clicks the button in idle state.
  2. State moves to confirming. The onClick function is called.
  3. If onClick resolves with a transaction hash, state moves to pending. The component uses Wagmi’s useWaitForTransactionReceipt to watch for confirmation.
  4. 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".
  5. If onClick throws (e.g., user rejected in wallet), state moves directly to error and onError(error) is called.
  6. After resetTimeout milliseconds 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/reactsrc/components/TransactionButton.tsx.