Skip to main content

Documentation Index

Fetch the complete documentation index at: https://seilabs-docs-evm-reference-and-sei-js-examples.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Transaction Lifecycle

This page covers the full round-trip of a transaction: building and sending it, waiting for the receipt, and reading the event logs it emitted.

Sending a Transaction

import { createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { sei } from '@sei-js/precompiles/viem';

const account = privateKeyToAccount('0xYourPrivateKey');
const walletClient = createWalletClient({ account, chain: sei, transport: http() });

const hash = await walletClient.sendTransaction({
  to: '0xRecipient',
  value: parseEther('1'),
});

Waiting for the Receipt

import { createPublicClient, http } from 'viem';

const client = createPublicClient({ chain: sei, transport: http() });

const receipt = await client.waitForTransactionReceipt({ hash });

console.log('Status:', receipt.status);           // 'success' | 'reverted'
console.log('Block:', receipt.blockNumber);
console.log('Gas used:', receipt.gasUsed);
Sei has instant finality — the receipt is final as soon as it arrives. One confirmation is sufficient. See Finality.

Decoding Event Logs from a Receipt

After a contract interaction, decode the events the transaction emitted:
import { parseAbi, decodeEventLog } from 'viem';

const ERC20_ABI = parseAbi([
  'function transfer(address to, uint256 amount) returns (bool)',
  'event Transfer(address indexed from, address indexed to, uint256 value)',
]);

const hash = await walletClient.writeContract({
  address: TOKEN,
  abi: ERC20_ABI,
  functionName: 'transfer',
  args: ['0xRecipient', 1_000_000n],
});

const receipt = await client.waitForTransactionReceipt({ hash });

// viem returns typed logs automatically when you pass the ABI to getTransactionReceipt
const typedReceipt = await client.getTransactionReceipt({ hash });

// Or decode manually from raw logs
for (const log of receipt.logs) {
  try {
    const event = decodeEventLog({ abi: ERC20_ABI, ...log });
    console.log('Event:', event.eventName, event.args);
  } catch {
    // Log from a different contract or unknown ABI
  }
}

Checking for Revert

A receipt with status: 'reverted' (viem) or status: 0 (ethers) means the transaction was included but the execution failed. The gas was still consumed.
viem
const receipt = await client.waitForTransactionReceipt({ hash });

if (receipt.status === 'reverted') {
  // Transaction was mined but execution failed.
  // Simulate the call to get the revert reason.
  console.error('Transaction reverted at block', receipt.blockNumber);
}

Fetching a Past Transaction

viem
const tx = await client.getTransaction({ hash: '0xTxHash' });
console.log('From:', tx.from);
console.log('To:', tx.to);
console.log('Value:', tx.value);
console.log('Input data:', tx.input);
ethers
const tx = await provider.getTransaction('0xTxHash');
const receipt = await provider.getTransactionReceipt('0xTxHash');

Getting Logs for a Specific Transaction

To fetch only the events emitted by a specific transaction (rather than decoding from the receipt):
viem
const logs = await client.getContractEvents({
  address: TOKEN,
  abi: ERC20_ABI,
  eventName: 'Transfer',
  blockHash: receipt.blockHash,
});

const txLogs = logs.filter((log) => log.transactionHash === hash);