Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
TokenBalance
TokenBalance is a branded bigint type representing ERC-20 token balances with decimal handling utilities.
Overview
ERC-20 tokens are fungible tokens where each token is identical and interchangeable. Balances are stored as unsigned 256-bit integers (uint256) on-chain, with decimals used for display formatting.
Key Features
- Type-safe: Branded bigint prevents mixing with raw numbers
- Decimal handling: Convert between raw values and human-readable amounts
- Range validation: 0 to 2^256-1
- ERC-20 interface selectors: Built-in function selectors
Installation
Basic Usage
import * as TokenBalance from '@tevm/voltaire/primitives/TokenBalance';
// Create from raw balance (wei-like units)
const balance = TokenBalance.from(1000000000000000000n); // 1 token with 18 decimals
// Format for display
console.log(TokenBalance.format(balance, 18)); // "1.0"
// Convert from human-readable amount
const amount = TokenBalance.fromBaseUnit("100.5", 6); // USDC (6 decimals)
console.log(amount); // 100500000n
// Compare balances
const a = TokenBalance.from(100n);
const b = TokenBalance.from(200n);
console.log(TokenBalance.compare(a, b)); // -1
API Reference
Constructor
from(value: bigint | number | string): TokenBalance
Create TokenBalance from bigint, number, or hex/decimal string.
const balance1 = TokenBalance.from(1000000000000000000n);
const balance2 = TokenBalance.from(100);
const balance3 = TokenBalance.from("0xff");
const balance4 = TokenBalance.from("1000000");
Throws:
InvalidTokenBalanceError if value is negative, exceeds max, or invalid
Conversions
toNumber(balance: TokenBalance): number
Convert to number (unsafe for large values).
const balance = TokenBalance.from(100n);
const num = TokenBalance.toNumber(balance); // 100
Throws:
RangeError if value exceeds Number.MAX_SAFE_INTEGER
toBigInt(balance: TokenBalance): bigint
Convert to bigint.
const balance = TokenBalance.from(1000000n);
const bigint = TokenBalance.toBigInt(balance); // 1000000n
toHex(balance: TokenBalance): string
Convert to hex string with 0x prefix.
const balance = TokenBalance.from(255n);
const hex = TokenBalance.toHex(balance); // "0xff"
Decimal Handling
Format balance for display with decimal places.
const balance = TokenBalance.from(1234567890123456789n);
// Full precision
TokenBalance.format(balance, 18); // "1.234567890123456789"
// Rounded to 6 decimals
TokenBalance.format(balance, 18, 6); // "1.234568"
// USDC (6 decimals)
const usdc = TokenBalance.from(100500000n);
TokenBalance.format(usdc, 6); // "100.5"
fromBaseUnit(amount: string, decimals: number): TokenBalance
Convert from human-readable amount to raw balance.
// ETH (18 decimals)
const eth = TokenBalance.fromBaseUnit("1.5", 18); // 1500000000000000000n
// USDC (6 decimals)
const usdc = TokenBalance.fromBaseUnit("100.5", 6); // 100500000n
// Integer amounts
const whole = TokenBalance.fromBaseUnit("100", 18); // 100000000000000000000n
// Fractional only
const fraction = TokenBalance.fromBaseUnit(".5", 18); // 500000000000000000n
Throws:
Error if amount format is invalid (e.g., “1.2.3”)
toBaseUnit(balance: TokenBalance): bigint
Get raw bigint value.
const balance = TokenBalance.from(1500000000000000000n);
const raw = TokenBalance.toBaseUnit(balance); // 1500000000000000000n
Comparison
equals(a: TokenBalance, b: TokenBalance): boolean
Check if two balances are equal.
const a = TokenBalance.from(100n);
const b = TokenBalance.from(100n);
TokenBalance.equals(a, b); // true
compare(a: TokenBalance, b: TokenBalance): number
Compare two balances. Returns -1 if a < b, 0 if equal, 1 if a > b.
const a = TokenBalance.from(100n);
const b = TokenBalance.from(200n);
TokenBalance.compare(a, b); // -1
Constants
constants.MAX
Maximum TokenBalance value (2^256 - 1).
TokenBalance.constants.MAX; // 115792089237316195423570985008687907853269984665640564039457584007913129639935n
constants.MIN
Minimum TokenBalance value (0).
TokenBalance.constants.MIN; // 0n
constants.DECIMALS
Common decimal counts for popular tokens.
TokenBalance.constants.DECIMALS.ETH; // 18
TokenBalance.constants.DECIMALS.WETH; // 18
TokenBalance.constants.DECIMALS.USDC; // 6
TokenBalance.constants.DECIMALS.USDT; // 6
TokenBalance.constants.DECIMALS.DAI; // 18
TokenBalance.constants.DECIMALS.WBTC; // 8
ERC-20 Interface
ERC20_SELECTORS
ERC-20 function selectors for ABI encoding.
TokenBalance.ERC20_SELECTORS.balanceOf; // "0x70a08231"
TokenBalance.ERC20_SELECTORS.transfer; // "0xa9059cbb"
TokenBalance.ERC20_SELECTORS.approve; // "0x095ea7b3"
TokenBalance.ERC20_SELECTORS.transferFrom; // "0x23b872dd"
TokenBalance.ERC20_SELECTORS.totalSupply; // "0x18160ddd"
TokenBalance.ERC20_SELECTORS.allowance; // "0xdd62ed3e"
ERC-20 Standard
ERC-20 defines a standard API for fungible tokens. Key functions:
balanceOf(address): Returns token balance
transfer(address, uint256): Transfers tokens
approve(address, uint256): Approves spending allowance
transferFrom(address, address, uint256): Transfers from approved account
totalSupply(): Returns total supply
allowance(address, address): Returns approved allowance
Specification: EIP-20
Common Decimal Counts
Different tokens use different decimal counts:
- 18 decimals: ETH, WETH, DAI, most ERC-20 tokens
- 6 decimals: USDC, USDT (stablecoins)
- 8 decimals: WBTC (Bitcoin-based)
Always check the token’s decimals() function before formatting.
Examples
Query Balance
import * as TokenBalance from '@tevm/voltaire/primitives/TokenBalance';
import * as Address from '@tevm/voltaire/Address';
// Encode balanceOf call
const account = Address.from("0x742d35Cc6634C0532925a3b844Bc9e7595f251e3");
const data = encodeBalanceOf(account);
// Decode response
const balance = TokenBalance.from(response); // Raw balance from chain
const formatted = TokenBalance.format(balance, 18); // Format for display
console.log(`Balance: ${formatted} tokens`);
Transfer Tokens
import * as TokenBalance from '@tevm/voltaire/primitives/TokenBalance';
import * as Address from '@tevm/voltaire/Address';
// Convert user input to raw amount
const amount = TokenBalance.fromBaseUnit("10.5", 18); // 10.5 tokens
const to = Address.from("0x...");
const data = encodeTransfer(to, amount);
Check Sufficient Balance
const balance = TokenBalance.from(userBalance);
const required = TokenBalance.fromBaseUnit("5.0", 18);
if (TokenBalance.compare(balance, required) >= 0) {
console.log("Sufficient balance");
} else {
console.log("Insufficient balance");
}
Error Handling
import { InvalidTokenBalanceError } from '@tevm/voltaire/primitives/TokenBalance';
try {
const balance = TokenBalance.from(-100n);
} catch (error) {
if (error instanceof InvalidTokenBalanceError) {
console.error("Invalid balance:", error.message);
}
}
Type Safety
TokenBalance is a branded type that prevents accidental mixing with raw bigints:
const balance: TokenBalance = 100n; // ❌ Type error
const balance = TokenBalance.from(100n); // ✅ Correct
function transfer(amount: TokenBalance) {
// Type-safe: only TokenBalance accepted
}
transfer(100n); // ❌ Type error
transfer(TokenBalance.from(100n)); // ✅ Correct
See Also