Skip to main content

Try it Live

Run Denomination examples in the interactive playground

Conversions

Type-safe conversions between Wei, Gwei, and Ether denominations.

Overview

Each denomination type provides conversion methods to other units. All conversions use integer arithmetic - fractional values truncate (round down).

Conversion Table

FromToFunctionFormulaExample
WeiGweiWei.toGwei(wei)wei / 10^91_000_000_000n Wei → 1n Gwei
WeiEtherWei.toEther(wei)wei / 10^181_000_000_000_000_000_000n Wei → 1n Ether
GweiWeiGwei.toWei(gwei)gwei * 10^91n Gwei → 1_000_000_000n Wei
GweiEtherGwei.toEther(gwei)gwei / 10^91_000_000_000n Gwei → 1n Ether
EtherWeiEther.toWei(ether)ether * 10^181n Ether → 1_000_000_000_000_000_000n Wei
EtherGweiEther.toGwei(ether)ether * 10^91n Ether → 1_000_000_000n Gwei

Wei Conversions

import * as Wei from 'tevm/Wei'

const wei = Wei(50_000_000_000n)
const gwei = Wei.toGwei(wei)  // 50n

// Fractional Gwei truncates
const wei2 = Wei(50_000_000_001n)
const gwei2 = Wei.toGwei(wei2)  // 50n (not 50.000000001)
Formula: gwei = wei / 1_000_000_000 (integer division)

Gwei Conversions

import * as Gwei from 'tevm/Gwei'

const gwei = Gwei(50n)
const wei = Gwei.toWei(gwei)  // 50_000_000_000n

// No truncation (multiplication)
const gwei2 = Gwei(1n)
const wei2 = Gwei.toWei(gwei2)  // 1_000_000_000n
Formula: wei = gwei * 1_000_000_000

Ether Conversions

import * as Ether from 'tevm/Ether'

const ether = Ether(1n)
const wei = Ether.toWei(ether)  // 1_000_000_000_000_000_000n

// No truncation (multiplication)
const ether2 = Ether(5n)
const wei2 = Ether.toWei(ether2)  // 5_000_000_000_000_000_000n
Formula: wei = ether * 1_000_000_000_000_000_000

Conversion Patterns

Gas Price Calculation

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

// Gas price in Gwei (user-friendly)
const gasPriceGwei = Gwei(50n)

// Convert to Wei for calculation
const gasPriceWei = Gwei.toWei(gasPriceGwei)

// Calculate total: gasPrice * gasUsed
const gasUsed = Uint(21_000n)
const txCostWei = Uint.times(gasPriceWei, gasUsed)

// Convert to Ether for display
const txCostEther = Wei.toEther(Wei(txCostWei))

Balance Display

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

// Balance from RPC (Wei)
const balanceWei = Wei(1_234_567_890_123_456_789n)

// Convert to Ether for display (with fractional part)
const balanceU256 = Wei.toU256(balanceWei)
const weiPerEther = Uint(1_000_000_000_000_000_000n)

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

const display = `${wholePart}.${fractionalPart.toString().padStart(18, '0')} ETH`
console.log(display)  // "1.234567890123456789 ETH"

Multi-Step Conversion

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

// Start with Ether
const ether = Ether(1n)

// Convert through Gwei to Wei
const gwei = Ether.toGwei(ether)      // 1_000_000_000n
const wei = Gwei.toWei(gwei)           // 1_000_000_000_000_000_000n

// Direct conversion (more efficient)
const weiDirect = Ether.toWei(ether)   // Same result

Comparing Different Units

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

const balance = Wei(100_000_000_000n)  // 100 Gwei in Wei
const threshold = Gwei(50n)             // 50 Gwei

// Convert to same unit for comparison
const thresholdWei = Gwei.toWei(threshold)
const balanceU256 = Wei.toU256(balance)
const thresholdU256 = Wei.toU256(thresholdWei)

if (balanceU256 > thresholdU256) {
  console.log("Balance exceeds threshold")
}

Integer Division Behavior

Division operations truncate fractional results. Always convert to smaller units before calculations requiring precision.

Truncation Examples

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

// Example 1: Wei → Gwei truncation
const wei1 = Wei(1_500_000_000n)  // 1.5 Gwei
const gwei1 = Wei.toGwei(wei1)          // 1n (truncates to 1)

const wei2 = Wei(1_999_999_999n)  // 1.999... Gwei
const gwei2 = Wei.toGwei(wei2)          // 1n (truncates to 1)

// Example 2: Gwei → Ether truncation
const gwei3 = Gwei(500_000_000n)  // 0.5 Ether
const ether1 = Gwei.toEther(gwei3)      // 0n (truncates to 0)

const gwei4 = Gwei(999_999_999n)  // 0.999... Ether
const ether2 = Gwei.toEther(gwei4)      // 0n (truncates to 0)

Avoiding Truncation

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

// ✗ Loses precision
const gwei = Gwei(50n)
const ether = Gwei.toEther(gwei)  // 0n
const wei = Ether.toWei(ether)     // 0n (lost data)

// ✓ Preserves precision - work in smallest unit
const gwei = Gwei(50n)
const wei = Gwei.toWei(gwei)  // 50_000_000_000n

// Perform calculations in Wei
const doubled = Uint.times(wei, Uint(2n))  // 100_000_000_000n

// Convert to display unit only at the end
const result = Wei.toGwei(Wei(doubled))  // 100n

Round-Trip Safety

Safe Round Trips (No Loss)

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

// Gwei → Wei → Gwei
const gwei1 = Gwei(50n)
const wei1 = Gwei.toWei(gwei1)
const gwei1Back = Wei.toGwei(wei1)  // 50n ✓

// Ether → Wei → Ether
const ether1 = Ether(1n)
const wei2 = Ether.toWei(ether1)
const ether1Back = Wei.toEther(wei2)  // 1n ✓

Unsafe Round Trips (Loss)

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

// Wei → Gwei → Wei (loses fractional Gwei)
const wei1 = Wei(1_500_000_000n)  // 1.5 Gwei
const gwei1 = Wei.toGwei(wei1)          // 1n (truncates)
const wei1Back = Gwei.toWei(gwei1)      // 1_000_000_000n ✗ (lost 0.5 Gwei)

// Gwei → Ether → Gwei (loses fractional Ether)
const gwei2 = Gwei(500_000_000n)  // 0.5 Ether
const ether1 = Gwei.toEther(gwei2)      // 0n (truncates)
const gwei2Back = Ether.toGwei(ether1)  // 0n ✗ (lost all)

Best Practices

1. Convert to Smallest Unit Early

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

// ✓ Good - convert to Wei first
const value = Ether(1n)
const valueWei = Ether.toWei(value)
const fee = Wei(21_000_000_000_000_000n)

const total = Uint.plus(valueWei, fee)

// ✗ Bad - mixing units
const value = Ether(1n)
const fee = Wei(21_000_000_000_000_000n)
// Cannot add different types

2. Use Type System for Safety

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

// Function signatures enforce correct units
function calculateGasCost(
  gasPrice: Gwei.Type,
  gasUsed: bigint
): Wei.Type {
  const gasPriceWei = Gwei.toWei(gasPrice)
  const cost = Uint.times(gasPriceWei, Uint(gasUsed))
  return Wei(cost)
}

// Compiler prevents passing wrong unit
const price = Gwei(50n)
const cost = calculateGasCost(price, 21_000n)  // ✓

const wei = Wei(50_000_000_000n)
// calculateGasCost(wei, 21_000n)  // ✗ Type error

3. Display in Appropriate Unit

import * as Wei from 'tevm/Wei'

// Gas prices in Gwei (more readable)
const gasPrice = Wei(50_000_000_000n)
console.log(`Gas: ${Wei.toGwei(gasPrice)} Gwei`)  // "Gas: 50 Gwei"
// Better than "Gas: 50000000000 Wei"

// Balances in Ether (user-friendly)
const balance = Wei(1_000_000_000_000_000_000n)
console.log(`Balance: ${Wei.toEther(balance)} ETH`)  // "Balance: 1 ETH"
// Better than "Balance: 1000000000000000000 Wei"

Conversion Constants

All conversions based on these constants:
const WEI_PER_GWEI = 1_000_000_000n              // 10^9
const GWEI_PER_ETHER = 1_000_000_000n            // 10^9
const WEI_PER_ETHER = 1_000_000_000_000_000_000n // 10^18

WASM Acceleration

All conversions available in WebAssembly:
import * as WeiWasm from 'tevm/Wei.wasm'
import * as GweiWasm from 'tevm/Gwei.wasm'
import * as EtherWasm from 'tevm/Ether.wasm'

const gwei = GweiWasm(50n)
const wei = GweiWasm.toWei(gwei)
const ether = WeiWasm.toEther(wei)
See WASM for details.