Skip to main content
Voltaire provides two API styles: a convenient constructor API with methods, and a functional API for tree-shaking. Both use identical function signatures. This documentation covers the constructor API, which is recommended for most use cases—the functional API follows identical signatures with the object as the first parameter.

The Two APIs

The Address() constructor returns instances with prototype methods:
import { Address } from '@tevm/voltaire'

const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')

// Instance methods
addr.toHex()              // "0x742d35cc..."
addr.toChecksummed()      // "0x742d35Cc..."
addr.isZero()             // false
addr.equals(other)        // boolean

// Static methods (also available)
Address.toHex(addr)
Address.isValid('0x...')
Tradeoff: Importing Address brings in all methods (~18 KB). Use this API for applications where developer experience matters more than bundle size.

Functional API (Tree-Shakeable)

Import individual functions from the Branded* namespace exports:
import { BrandedAddress } from '@tevm/voltaire'

const addr = BrandedAddress.from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')

// Same functions, data-first signature
BrandedAddress.toHex(addr)           // "0x742d35cc..."
BrandedAddress.toChecksummed(addr)   // "0x742d35Cc..."
BrandedAddress.isZero(addr)          // false
BrandedAddress.equals(addr, other)   // boolean
For maximum tree-shaking, import only the functions you need:
import { from, toHex, equals } from '@tevm/voltaire/Address'

const addr = from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
toHex(addr)          // Only these 3 functions in bundle
equals(addr, other)

How Methods are Written

All Voltaire methods are written as standalone functions first, then attached to constructors:
// toHex.js - Standalone function (tree-shakeable)
export function toHex(address) {
  return `0x${Array.from(address, b => b.toString(16).padStart(2, '0')).join('')}`
}

// index.ts - Attached to constructor
Address.toHex = BrandedAddress.toHex
Address.prototype.toHex = function() {
  return BrandedAddress.toHex(this)
}
This means:
  • Instance method: addr.toHex()
  • Static method: Address.toHex(addr)
  • Standalone function: toHex(addr)
All three call the same underlying implementation.

Available Namespace Exports

Each primitive has a Branded* namespace export:
import {
  BrandedAddress,
  BrandedHash,
  BrandedHex,
  BrandedUint,
  BrandedRlp,
  BrandedBytecode,
  // ... etc
} from '@tevm/voltaire'

Comparison

Import StyleBundle ImpactUsage
import { Address }~18 KBFull API with methods
import { BrandedAddress }~18 KBFunctional namespace
import { toHex } from '@tevm/voltaire/Address'~500 bytesOnly specific functions

Converting Between APIs

Converting from constructor API to functional API is mechanical - just move the object to the first parameter:
// Constructor API
const addr = Address('0x...')
addr.toHex()
addr.equals(other)
Address.isValid(input)

// Functional API (same logic)
const addr = from('0x...')
toHex(addr)
equals(addr, other)
isValid(input)
An LLM can convert between these trivially since the signatures are identical.

When to Use Each

Use Constructor API when:
  • Building applications (DX matters)
  • Bundle size is not critical
  • You want autocomplete on instances
Use Functional API when:
  • Building libraries (minimize impact on users)
  • Every KB matters (mobile, embedded)
  • You only need a few functions

Crypto Dependencies

Some functions require crypto dependencies. The functional API exposes factory functions for these:
import { ToChecksummed, CalculateCreateAddress } from '@tevm/voltaire/Address'
import { hash as keccak256 } from '@tevm/voltaire/Keccak256'
import { encode as rlpEncode } from '@tevm/voltaire/Rlp'

// Create functions with injected dependencies
const toChecksummed = ToChecksummed({ keccak256 })
const calculateCreateAddress = CalculateCreateAddress({ keccak256, rlpEncode })

// Now use them
toChecksummed(addr)  // Only pulls in the crypto you actually use
The default exports (toChecksummed, calculateCreateAddress) have crypto pre-injected for convenience.

Learn More