Skip to main content

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.

Try it Live

Run Denomination examples in the interactive playground

Usage Patterns

Common patterns for working with Wei, Gwei, and Ether in real-world applications.

Gas Calculations

Basic Gas Cost

import * as Gwei from 'tevm/Gwei'
import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function calculateGasCost(
  gasPriceGwei: Gwei.Type,
  gasUsed: bigint
): Wei.Type {
  // Convert to Wei for calculation
  const gasPriceWei = Gwei.toWei(gasPriceGwei)

  // Calculate: gasPrice * gasUsed
  const cost = Uint.times(gasPriceWei, Uint(gasUsed))

  return Wei(cost)
}

// Example usage
const gasPrice = Gwei(50n)  // 50 Gwei
const gasUsed = 21_000n           // Standard transfer
const cost = calculateGasCost(gasPrice, gasUsed)

console.log(`Cost: ${cost} Wei`)  // 1_050_000_000_000_000 Wei
console.log(`Cost: ${Wei.toGwei(cost)} Gwei`)  // 1_050_000 Gwei

EIP-1559 Gas Calculation

import * as Gwei from 'tevm/Gwei'
import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

interface EIP1559Params {
  baseFeePerGas: Gwei.Type
  maxPriorityFeePerGas: Gwei.Type
  maxFeePerGas: Gwei.Type
  gasLimit: bigint
}

function calculateEIP1559Cost(params: EIP1559Params): {
  maxCost: Wei.Type
  estimatedCost: Wei.Type
} {
  // Max possible cost
  const maxFeeWei = Gwei.toWei(params.maxFeePerGas)
  const maxCostU256 = Uint.times(maxFeeWei, Uint(params.gasLimit))

  // Estimated actual cost: baseFee + priorityFee
  const baseFeeU256 = Gwei.toU256(params.baseFeePerGas)
  const priorityFeeU256 = Gwei.toU256(params.maxPriorityFeePerGas)
  const effectiveFee = Uint.plus(baseFeeU256, priorityFeeU256)
  const effectiveFeeWei = Gwei.toWei(Gwei(effectiveFee))
  const estimatedCostU256 = Uint.times(effectiveFeeWei, Uint(params.gasLimit))

  return {
    maxCost: Wei(maxCostU256),
    estimatedCost: Wei(estimatedCostU256)
  }
}

// Example usage
const params: EIP1559Params = {
  baseFeePerGas: Gwei(30n),
  maxPriorityFeePerGas: Gwei(2n),
  maxFeePerGas: Gwei(50n),
  gasLimit: 21_000n
}

const { maxCost, estimatedCost } = calculateEIP1559Cost(params)
console.log(`Max: ${Wei.toEther(maxCost)} ETH`)
console.log(`Estimated: ${Wei.toEther(estimatedCost)} ETH`)

Gas Price Comparison

import * as Gwei from 'tevm/Gwei'
import * as Uint from 'tevm/Uint'

interface GasPrices {
  fast: Gwei.Type
  standard: Gwei.Type
  slow: Gwei.Type
}

function selectGasPrice(
  prices: GasPrices,
  maxPrice: Gwei.Type
): Gwei.Type | null {
  const maxU256 = Gwei.toU256(maxPrice)

  // Try fast first
  if (Gwei.toU256(prices.fast) <= maxU256) {
    return prices.fast
  }

  // Fall back to standard
  if (Gwei.toU256(prices.standard) <= maxU256) {
    return prices.standard
  }

  // Fall back to slow
  if (Gwei.toU256(prices.slow) <= maxU256) {
    return prices.slow
  }

  // All prices too high
  return null
}

// Example usage
const prices: GasPrices = {
  fast: Gwei(100n),
  standard: Gwei(50n),
  slow: Gwei(20n)
}

const maxPrice = Gwei(60n)
const selected = selectGasPrice(prices, maxPrice)

if (selected) {
  console.log(`Selected: ${selected} Gwei`)
} else {
  console.log('All prices exceed maximum')
}

Transaction Values

User Input to Transaction

import * as Ether from 'tevm/Ether'
import * as Wei from 'tevm/Wei'

function parseEtherInput(input: string): Wei.Type {
  // Parse user input (e.g., "1.5" ETH)
  const [whole, fractional = '0'] = input.split('.')

  // Convert to Wei manually to preserve fractional part
  const wholeBigInt = BigInt(whole)
  const fractionalPadded = fractional.padEnd(18, '0').slice(0, 18)
  const fractionalBigInt = BigInt(fractionalPadded)

  const wholeWei = Ether.toWei(Ether(wholeBigInt))
  const totalWei = Wei(Wei.toU256(wholeWei) + fractionalBigInt)

  return totalWei
}

// Example usage
const input = "1.5"  // User wants to send 1.5 ETH
const value = parseEtherInput(input)

const tx = {
  to: "0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e",
  value: value,  // 1_500_000_000_000_000_000n Wei
}

console.log(`Sending ${value} Wei`)
console.log(`(${input} ETH)`)

Balance Checking

import * as Wei from 'tevm/Wei'
import * as Ether from 'tevm/Ether'
import * as Uint from 'tevm/Uint'

function hasSufficientBalance(
  balance: Wei.Type,
  value: Wei.Type,
  gasCost: Wei.Type
): boolean {
  const balanceU256 = Wei.toU256(balance)
  const valueU256 = Wei.toU256(value)
  const gasCostU256 = Wei.toU256(gasCost)

  // Total needed = value + gas
  const required = Uint.plus(valueU256, gasCostU256)

  return balanceU`256 >= required`
}

// Example usage
const balance = Wei(2_000_000_000_000_000_000n)  // 2 ETH
const value = Ether.toWei(Ether(1n))              // 1 ETH
const gasCost = Wei(50_000_000_000_000n)         // 0.00005 ETH

if (hasSufficientBalance(balance, value, gasCost)) {
  console.log('Sufficient balance')
} else {
  console.log('Insufficient balance')
}

Balance Display

Format Wei as Ether

import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function formatWeiAsEther(wei: Wei.Type, decimals: number = 18): string {
  const weiU256 = Wei.toU256(wei)
  const weiPerEther = Uint(1_000_000_000_000_000_000n)

  // Split into whole and fractional parts
  const wholePart = Uint.dividedBy(weiU256, weiPerEther)
  const fractionalPart = Uint.modulo(weiU256, weiPerEther)

  // Format fractional part with desired decimals
  const fractionalStr = fractionalPart.toString().padStart(18, '0')
  const truncated = fractionalStr.slice(0, decimals)

  // Remove trailing zeros
  const trimmed = truncated.replace(/0+$/, '') || '0'

  return `${wholePart}.${trimmed}`
}

// Example usage
const balance = Wei(1_234_567_890_123_456_789n)

console.log(formatWeiAsEther(balance, 18))  // "1.234567890123456789"
console.log(formatWeiAsEther(balance, 6))   // "1.234567"
console.log(formatWeiAsEther(balance, 2))   // "1.23"

Format with Units

import * as Wei from 'tevm/Wei'

function formatBalance(wei: Wei.Type): string {
  const weiU256 = Wei.toU256(wei)

  // `If >= 0`.01 ETH, show in ETH
  if (`weiU256 >= 10`_000_000_000_000_000n) {
    const ether = Wei.toEther(wei)
    return `${ether} ETH`
  }

  // `If >= 0`.00001 Gwei, show in Gwei
  if (`weiU256 >= 10`_000n) {
    const gwei = Wei.toGwei(wei)
    return `${gwei} Gwei`
  }

  // Otherwise show in Wei
  return `${wei} Wei`
}

// Example usage
console.log(formatBalance(Wei(1_000_000_000_000_000_000n)))  // "1 ETH"
console.log(formatBalance(Wei(50_000_000_000n)))             // "50 Gwei"
console.log(formatBalance(Wei(1_000n)))                      // "1000 Wei"

Compact Display

import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function formatCompact(wei: Wei.Type): string {
  const weiU256 = Wei.toU256(wei)
  const weiPerEther = Uint(1_000_000_000_000_000_000n)

  const wholePart = Uint.dividedBy(weiU256, weiPerEther)
  const fractionalPart = Uint.modulo(weiU256, weiPerEther)

  if (fractionalPart === 0n) {
    return `${wholePart} ETH`
  }

  // Show only significant decimals
  const fractionalStr = fractionalPart.toString().padStart(18, '0')
  const significant = fractionalStr.slice(0, 4)

  return `${wholePart}.${significant} ETH`
}

// Example usage
console.log(formatCompact(Wei(1_000_000_000_000_000_000n)))  // "1 ETH"
console.log(formatCompact(Wei(1_234_000_000_000_000_000n)))  // "1.2340 ETH"
console.log(formatCompact(Wei(500_000_000_000_000_000n)))    // "0.5000 ETH"

Arithmetic Operations

Adding Values

import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function addWei(a: Wei.Type, b: Wei.Type): Wei.Type {
  const aU256 = Wei.toU256(a)
  const bU256 = Wei.toU256(b)
  const sum = Uint.plus(aU256, bU256)
  return Wei(sum)
}

// Example usage
const balance1 = Wei(1_000_000_000_000_000_000n)  // 1 ETH
const balance2 = Wei(500_000_000_000_000_000n)     // 0.5 ETH
const total = addWei(balance1, balance2)                 // 1.5 ETH

console.log(`Total: ${total} Wei`)

Calculating Percentages

import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function calculatePercentage(
  amount: Wei.Type,
  percentage: bigint  // Basis points (100 = 1%)
): Wei.Type {
  const amountU256 = Wei.toU256(amount)
  const percentageU256 = Uint(percentage)
  const basis = Uint(10_000n)  // 100% = 10,000 basis points

  const result = Uint.dividedBy(
    Uint.times(amountU256, percentageU256),
    basis
  )

  return Wei(result)
}

// Example usage
const amount = Wei(1_000_000_000_000_000_000n)  // 1 ETH
const fee = calculatePercentage(amount, 250n)         // 2.5% fee
const remaining = Wei(
  Uint.minus(Wei.toU256(amount), Wei.toU256(fee))
)

console.log(`Original: ${amount} Wei`)
console.log(`Fee (2.5%): ${fee} Wei`)
console.log(`Remaining: ${remaining} Wei`)

Splitting Values

import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function splitEqually(
  total: Wei.Type,
  parts: number
): Wei.Type[] {
  const totalU256 = Wei.toU256(total)
  const partsU256 = Uint(BigInt(parts))

  const share = Uint.dividedBy(totalU256, partsU256)
  const remainder = Uint.modulo(totalU256, partsU256)

  // Create array of equal shares
  const shares = Array(parts).fill(Wei(share))

  // Add remainder to first share
  if (remainder > 0n) {
    shares[0] = Wei(Uint.plus(share, remainder))
  }

  return shares
}

// Example usage
const total = Wei(1_000_000_000_000_000_000n)  // 1 ETH
const shares = splitEqually(total, 3)

shares.forEach((share, i) => {
  console.log(`Share ${i + 1}: ${share} Wei`)
})

Price Calculations

ETH/USD Conversion

import * as Ether from 'tevm/Ether'
import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function weiToUSD(
  wei: Wei.Type,
  ethPriceUsd: number  // ETH price in USD (e.g., 2000.50)
): number {
  const weiU256 = Wei.toU256(wei)
  const weiPerEther = Uint(1_000_000_000_000_000_000n)

  // Convert to Ether (as number for USD calculation)
  const ether = Number(Uint.dividedBy(weiU256, weiPerEther))
  const fractionalWei = Number(Uint.modulo(weiU256, weiPerEther))
  const fractionalEther = fractionalWei / Number(weiPerEther)

  const totalEther = ether + fractionalEther
  return totalEther * ethPriceUsd
}

// Example usage
const balance = Wei(1_500_000_000_000_000_000n)  // 1.5 ETH
const ethPrice = 2000.50  // $2000.50 per ETH

const usdValue = weiToUSD(balance, ethPrice)
console.log(`Balance: $${usdValue.toFixed(2)} USD`)  // "$3000.75 USD"

Gas Cost in USD

import * as Gwei from 'tevm/Gwei'
import * as Wei from 'tevm/Wei'
import * as Uint from 'tevm/Uint'

function gasCostUSD(
  gasPriceGwei: Gwei.Type,
  gasUsed: bigint,
  ethPriceUsd: number
): number {
  // Calculate gas cost in Wei
  const gasPriceWei = Gwei.toWei(gasPriceGwei)
  const costWei = Uint.times(gasPriceWei, Uint(gasUsed))

  // Convert to USD
  const weiPerEther = Uint(1_000_000_000_000_000_000n)
  const costEther = Number(costWei) / Number(weiPerEther)

  return costEther * ethPriceUsd
}

// Example usage
const gasPrice = Gwei(50n)  // 50 Gwei
const gasUsed = 21_000n
const ethPrice = 2000.50

const costUsd = gasCostUSD(gasPrice, gasUsed, ethPrice)
console.log(`Gas cost: $${costUsd.toFixed(2)} USD`)

Validation

Range Checking

import * as Wei from 'tevm/Wei'
import * as Ether from 'tevm/Ether'
import * as Uint from 'tevm/Uint'

function isWithinRange(
  value: Wei.Type,
  min: Ether.Type,
  max: Ether.Type
): boolean {
  const valueU256 = Wei.toU256(value)
  const minWei = Ether.toWei(min)
  const maxWei = Ether.toWei(max)

  return valueU`256 >= Wei`.toU256(minWei) &&
         valueU`256 <= Wei`.toU256(maxWei)
}

// Example usage
const value = Wei(500_000_000_000_000_000n)  // 0.5 ETH
const min = Ether(0n)
const max = Ether(1n)

if (isWithinRange(value, min, max)) {
  console.log('Value within range')
}

Dust Amount Detection

import * as Wei from 'tevm/Wei'

const DUST_THRESHOLD = Wei(1_000_000_000_000n)  // 0.000001 ETH

function isDust(amount: Wei.Type): boolean {
  const amountU256 = Wei.toU256(amount)
  const thresholdU256 = Wei.toU256(DUST_THRESHOLD)
  return amountU256 < thresholdU256 && amountU256 > 0n
}

// Example usage
const amount = Wei(100n)
if (isDust(amount)) {
  console.log('Amount is dust - may not be worth sending')
}

Best Practices

  1. Store in Wei - Keep all values in Wei internally
  2. Convert at boundaries - Convert to Gwei/Ether only for display
  3. Use type safety - Let branded types prevent unit mixing
  4. Handle precision - Be aware of integer division truncation
  5. Validate inputs - Check ranges before conversions