Documentation Index
Fetch the complete documentation index at: https://seilabs-docs-bridge-seictl-pr-184.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
viem Quickstart
This example shows how to use viem with Sei outside of a React context — in a Node.js script, CLI tool, or backend service. For React apps, see wagmi and the frontend guide.
Install
npm install viem @sei-js/precompiles
Public Client
A public client handles all read-only operations.
import { createPublicClient, http } from 'viem';
import { sei } from '@sei-js/precompiles/viem';
const client = createPublicClient({
chain: sei,
transport: http(),
});
To use a custom RPC endpoint, pass the URL to http():
const client = createPublicClient({
chain: sei,
transport: http('https://evm-rpc.sei-apis.com'),
});
Reading Chain Data
This is the first milestone — it needs no private key.
import { formatEther } from 'viem';
const blockNumber = await client.getBlockNumber(); // bigint
console.log('Block number:', blockNumber);
const balance = await client.getBalance({ address: '0xYourAddress' }); // bigint, wei
console.log('Balance (SEI):', formatEther(balance));
const nonce = await client.getTransactionCount({ address: '0xYourAddress' }); // number
console.log('Nonce:', nonce);
You’re done when you see:
Block number: 148203117n
Balance (SEI): 12.5
Nonce: 7
The exact numbers are illustrative — your block number and balance will differ. Note the trailing n: getBlockNumber() and getBalance() return bigint, while getTransactionCount() returns a number.
Wallet Client
A wallet client handles signing and broadcasting transactions.
import { createWalletClient, http } 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(),
});
For browser use, replace http() with custom(window.ethereum) and call walletClient.getAddresses() to get the connected account.
Sending a Transaction
Next step — this requires a funded account; get testnet SEI from the faucet.
import { parseEther } from 'viem';
const hash = await walletClient.sendTransaction({
to: '0xRecipient',
value: parseEther('1'),
});
const receipt = await client.waitForTransactionReceipt({ hash });
// receipt is final immediately — Sei has instant finality
Reading a Contract
import { parseAbi } from 'viem';
const abi = parseAbi(['function balanceOf(address owner) view returns (uint256)']);
const balance = await client.readContract({
address: '0xTokenAddress',
abi,
functionName: 'balanceOf',
args: ['0xYourAddress'],
});
Writing to a Contract
const hash = await walletClient.writeContract({
address: '0xTokenAddress',
abi,
functionName: 'transfer',
args: ['0xRecipient', 1_000_000n],
});
const receipt = await client.waitForTransactionReceipt({ hash });
Simulating Before Writing
const { result } = await client.simulateContract({
address: '0xTokenAddress',
abi,
functionName: 'transfer',
args: ['0xRecipient', 1_000_000n],
account,
});
// If simulation succeeds, execute it
const hash = await walletClient.writeContract(result);
Estimating Gas
Always use estimateGas rather than hard-coding values. SSTORE costs on Sei are governance-adjustable.
const gas = await client.estimateGas({
account,
to: '0xContractAddress',
data: '0xCalldata',
});
Using Python (web3.py)
Sei is fully EVM-compatible, so any standard Ethereum client works — including Python’s web3.py.
from web3 import Web3
w3 = Web3(Web3.HTTPProvider("https://evm-rpc.sei-apis.com"))
print("Connected:", w3.is_connected())
print("Latest block:", w3.eth.block_number)
print("Chain ID:", w3.eth.chain_id) # 1329
You’re done when you see:
Connected: True
Latest block: 148203117
Chain ID: 1329
The block number is illustrative; the chain ID is always 1329 on mainnet.
Next Steps