Overview
Understanding transaction statuses helps you build reliable applications on Paxeer Network. This guide explains the lifecycle and finality of transactions.
Transaction Lifecycle
Pending
Transaction is in the mempool, waiting to be included in a block. const tx = await signer . sendTransaction ( txData );
console . log ( 'Transaction hash:' , tx . hash );
// Status: Pending
Mined
Transaction has been included in a block. const receipt = await tx . wait ( 1 ); // Wait for 1 confirmation
console . log ( 'Block number:' , receipt . blockNumber );
// Status: Mined (1 confirmation)
Confirmed
Transaction has received multiple block confirmations. const receipt = await tx . wait ( 3 ); // Wait for 3 confirmations
// Status: Confirmed (3 confirmations)
Finalized
Transaction is considered final and irreversible. const receipt = await tx . wait ( 12 ); // Wait for 12 confirmations
// Status: Finalized
Checking Transaction Status
Using Transaction Hash
import { ethers } from 'ethers' ;
const provider = new ethers . JsonRpcProvider ( 'https://public-rpc.paxeer.app/rpc' );
async function getTransactionStatus ( txHash ) {
// Get transaction data
const tx = await provider . getTransaction ( txHash );
if ( ! tx ) {
return { status: 'not_found' };
}
// Get transaction receipt
const receipt = await provider . getTransactionReceipt ( txHash );
if ( ! receipt ) {
return {
status: 'pending' ,
nonce: tx . nonce ,
};
}
// Get current block number
const currentBlock = await provider . getBlockNumber ();
const confirmations = currentBlock - receipt . blockNumber + 1 ;
return {
status: receipt . status === 1 ? 'success' : 'failed' ,
blockNumber: receipt . blockNumber ,
confirmations: confirmations ,
gasUsed: receipt . gasUsed . toString (),
effectiveGasPrice: receipt . gasPrice . toString (),
};
}
// Usage
const status = await getTransactionStatus ( '0x...' );
console . log ( 'Transaction status:' , status );
Finality Levels
Paxeer Network has different finality levels based on block confirmations:
Level Confirmations Time Use Case
Unsafe 0 Immediate UI updates only Safe 1-2 ~4 seconds Most dApps Confirmed 3-11 ~6-22 seconds Important operations Finalized 12+ ~24+ seconds Critical/irreversible actions
For high-value or critical operations, wait for at least 12 confirmations before considering the transaction finalized.
Monitoring Transactions
Real-time Status Updates
import { useState , useEffect } from 'react' ;
import { usePublicClient , useWaitForTransactionReceipt } from 'wagmi' ;
export function useTransactionStatus ( hash ?: `0x ${ string } ` ) {
const [ status , setStatus ] = useState < 'pending' | 'success' | 'failed' >( 'pending' );
const [ confirmations , setConfirmations ] = useState ( 0 );
const { data : receipt , isLoading } = useWaitForTransactionReceipt ({
hash ,
});
const client = usePublicClient ();
useEffect (() => {
if ( ! receipt || ! client ) return ;
setStatus ( receipt . status === 'success' ? 'success' : 'failed' );
// Update confirmations periodically
const interval = setInterval ( async () => {
const currentBlock = await client . getBlockNumber ();
const confs = currentBlock - receipt . blockNumber + 1 n ;
setConfirmations ( Number ( confs ));
}, 2000 );
return () => clearInterval ( interval );
}, [ receipt , client ]);
return { status , confirmations , receipt , isLoading };
}
Usage in React Component
function TransactionTracker ({ txHash }) {
const { status , confirmations , receipt } = useTransactionStatus ( txHash );
return (
< div >
< p > Status : { status }</ p >
< p > Confirmations : { confirmations }</ p >
{ status === ' success ' && confirmations > = 12 && (
< p className = "text-green-600" > ✓ Transaction Finalized </ p >
)}
{ status === ' failed ' && (
< p className = "text-red-600" > ✗ Transaction Failed </ p >
)}
</ div >
);
}
Transaction Receipt Details
async function getDetailedReceipt ( txHash ) {
const receipt = await provider . getTransactionReceipt ( txHash );
return {
// Status
status: receipt . status , // 1 = success, 0 = failed
// Block information
blockNumber: receipt . blockNumber ,
blockHash: receipt . blockHash ,
// Gas usage
gasUsed: receipt . gasUsed . toString (),
gasPrice: receipt . gasPrice . toString (),
effectiveGasPrice: receipt . gasPrice . toString (),
// Fee calculation
totalFee: ( receipt . gasUsed * receipt . gasPrice ). toString (),
// Addresses
from: receipt . from ,
to: receipt . to ,
contractAddress: receipt . contractAddress , // If contract creation
// Transaction details
transactionHash: receipt . hash ,
transactionIndex: receipt . index ,
// Logs (events)
logs: receipt . logs ,
};
}
Best Practices
Wait for Appropriate Confirmations
Different use cases need different confirmation levels: // UI update only - show immediately
const receipt = await tx . wait ( 0 );
// Standard dApp - wait for 1 confirmation
const receipt = await tx . wait ( 1 );
// Financial operation - wait for 3+ confirmations
const receipt = await tx . wait ( 3 );
// Critical operation - wait for finality
const receipt = await tx . wait ( 12 );
Although rare, block reorganizations can happen: async function waitForSafeConfirmation ( txHash ) {
let previousBlockHash = null ;
while ( true ) {
const receipt = await provider . getTransactionReceipt ( txHash );
if ( receipt && receipt . confirmations >= 3 ) {
const block = await provider . getBlock ( receipt . blockNumber );
if ( previousBlockHash && block . hash !== previousBlockHash ) {
console . warn ( 'Reorg detected! Waiting more...' );
previousBlockHash = block . hash ;
continue ;
}
if ( ! previousBlockHash ) {
previousBlockHash = block . hash ;
}
// No reorg detected
return receipt ;
}
await new Promise ( resolve => setTimeout ( resolve , 2000 ));
}
}
Don’t wait indefinitely: async function waitWithTimeout ( txPromise , timeoutMs = 60000 ) {
return Promise . race ([
txPromise ,
new Promise (( _ , reject ) =>
setTimeout (() => reject ( new Error ( 'Transaction timeout' )), timeoutMs )
),
]);
}
// Usage
try {
const receipt = await waitWithTimeout ( tx . wait ());
console . log ( 'Success:' , receipt . hash );
} catch ( error ) {
if ( error . message === 'Transaction timeout' ) {
console . log ( 'Transaction taking too long, check status manually' );
}
}
Event Monitoring
Watch for transaction events in real-time:
// Listen for pending transactions
provider . on ( 'pending' , ( txHash ) => {
console . log ( 'New pending transaction:' , txHash );
});
// Listen for mined blocks
provider . on ( 'block' , async ( blockNumber ) => {
console . log ( 'New block mined:' , blockNumber );
const block = await provider . getBlock ( blockNumber );
console . log ( 'Transactions in block:' , block . transactions . length );
});
// Clean up listeners
provider . removeAllListeners ( 'pending' );
provider . removeAllListeners ( 'block' );
Resources
Next Steps