Skip to main content

Try it Live

Run Address examples in the interactive playground
This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.

Factory API

For tree-shakeable, crypto-agnostic implementation, use the factory function:
import { FromPrivateKey } from '@tevm/voltaire/Address/AddressType'
import { hash as keccak256 } from '@tevm/voltaire/Keccak256'
import { derivePublicKey } from '@tevm/voltaire/Secp256k1'
import * as PrivateKey from '@tevm/voltaire/primitives/PrivateKey'

// Create factory instance with both crypto dependencies
const fromPrivateKey = FromPrivateKey({ keccak256, derivePublicKey })

// Use the factory
const privateKey = PrivateKey('0x...')
const address = fromPrivateKey(privateKey)
Note: This method requires TWO crypto dependencies:
  • keccak256 - For hashing the public key
  • derivePublicKey - For deriving public key from private key
This allows complete control over which crypto implementations to use (native, WASM, or custom).

Standard API

The standard API automatically injects crypto dependencies:
import { Address } from '@tevm/voltaire'

const privateKey = Bytes32()
// ... set private key bytes ...

const address = Address(privateKey)

C FFI

The C API does not currently expose fromPrivateKey directly. To derive addresses from private keys in C, use the crypto library’s secp256k1 functions to derive the public key first, then use primitives_address_from_public_key. Example workflow:
#include "tevm.h"

// 1. Derive public key from private key (using secp256k1)
uint8_t private_key[32] = { /* your private key */ };
uint8_t public_key[64];  // x, y coordinates

// Use secp256k1_pubkey_create or similar (not shown - requires crypto lib)
// secp256k1_derive_public_key(private_key, public_key);

// 2. Convert public key coordinates to address
// Note: This function may not exist yet in C API
// If not available, compute manually:
// - Hash public key with keccak256
// - Take last 20 bytes for address

// Future API (when available):
// PrimitivesAddress addr;
// int result = primitives_address_from_public_key(public_key, 64, &addr);
Note: For production use with C, consider:
  • Using the crypto library directly for secp256k1 operations
  • Computing keccak256 hash of the derived public key
  • Extracting the last 20 bytes for the address
Alternative: Use Zig or TypeScript APIs for key derivation, then pass addresses to C code as hex strings or byte arrays. Defined in: src/primitives.h

Algorithm

The address derivation follows this process:
  1. Derive public key - Multiply generator point G by private key scalar
  2. Extract coordinates - Get x and y coordinates from resulting point
  3. Hash public key - Compute keccak256(x || y)
  4. Extract address - Take last 20 bytes of hash
Pseudocode:
publicKey = secp256k1.multiply(G, privateKey)  // 64 bytes (x, y)
hash = keccak256(publicKey)                    // 32 bytes
address = hash[12:32]                          // Last 20 bytes

Private Key Requirements

Size: Exactly 32 bytes (256 bits) Valid range: 1 to n-1 where n is the secp256k1 curve order:
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
Invalid values:
  • All zeros (0x0000…0000)
  • Greater than or equal to curve order

Security Considerations

Never hardcode or log private keys. Store securely and transmit only over encrypted channels. Compromised private keys allow complete control of associated addresses.
Best practices:
  • Generate from cryptographically secure random source
  • Never reuse across different accounts/networks
  • Store encrypted at rest
  • Use hardware wallets for high-value keys
  • Implement key rotation policies

Complete Example

import { Address } from '@tevm/voltaire'
import { randomBytes } from 'crypto' // Node.js

// Generate secure random private key
const privateKey = randomBytes(32)

// Derive address
const addr = Address(privateKey)

console.log('Address:', addr.toChecksummed())
console.log('Private key:', Buffer(privateKey).toString('hex'))

// Store private key securely (encrypted)
// Store address publicly (for receiving funds)

Use Cases

Wallet Generation

Generate new Ethereum accounts:
import { Address } from '@tevm/voltaire'

function generateAccount() {
  const privateKey = Bytes32()
  crypto.getRandomValues(privateKey)

  const address = Address(privateKey)

  return {
    address: address.toChecksummed(),
    privateKey: Buffer(privateKey).toString('hex')
  }
}

const account = generateAccount()

Key Import

Import existing private keys:
import { Address } from '@tevm/voltaire'
import * as Hex from '@tevm/voltaire/Hex'

function importPrivateKey(keyHex: string) {
  // Remove 0x prefix if present
  const cleanHex = keyHex.startsWith('0x') ? keyHex.slice(2) : keyHex

  if (cleanHex.length !== 64) {
    throw new Error('Private key must be 32 bytes (64 hex chars)')
  }

  const privateKey = Hex.toBytes(`0x${cleanHex}`)
  const address = Address(privateKey)

  return address
}

HD Wallets

Derive addresses from HD wallet private keys:
import { Address } from '@tevm/voltaire'

// Assume deriveChildKey generates child keys from master seed
function deriveAddresses(masterSeed: Uint8Array, count: number) {
  const addresses = []

  for (let i = 0; i < count; i++) {
    const childKey = deriveChildKey(masterSeed, i) // BIP32/BIP44
    const address = Address(childKey)
    addresses.push(address.toChecksummed())
  }

  return addresses
}

Performance

Cryptographic operations:
  • secp256k1 scalar multiplication (public key derivation)
  • keccak256 hash function
Bundle size impact: When using tree-shakeable imports, including this method adds:
  • secp256k1 implementation (~15-20 KB)
  • keccak256 implementation (~5-10 KB)
Execution time: ~0.5-2ms depending on implementation and hardware.

Error Handling

import { Address } from '@tevm/voltaire'

// Wrong length
try {
  const shortKey = Bytes16()
  Address(shortKey)
} catch (e) {
  console.error(e) // InvalidAddressLengthError: must be 32 bytes
}

// Invalid value (all zeros)
try {
  const zeroKey = Bytes32()
  Address(zeroKey)
} catch (e) {
  console.error(e) // InvalidValueError: Invalid private key
}

// Out of range
try {
  const invalidKey = Bytes32().fill(0xFF)
  Address(invalidKey)
} catch (e) {
  console.error(e) // InvalidValueError: Invalid private key
}

See Also