Skip to main content

Try it Live

Run Address examples in the interactive playground

Usage Patterns

Practical patterns for address validation, conversion, and contract address calculation.

Address Validation

Input Validation

import * as Address from 'tevm/Address';

function validateUserInput(input: string): AddressType {
  // Check format
  if (!Address.isValid(input)) {
    throw new Error(`Invalid address format: ${input}`);
  }

  // Parse and return
  return Address(input);
}

// Safe construction
function safeFromAddress(input: unknown): AddressType | null {
  try {
    if (typeof input === 'string') {
      return Address(input);
    }
    if (input instanceof Uint8Array && input.length === 20) {
      return Address(input);
    }
    return null;
  } catch {
    return null;
  }
}

Checksum Verification

// Verify checksum before use
function requireChecksummed(addr: string): AddressType {
  if (!Address.isValidChecksum(addr)) {
    throw new Error(
      `Address checksum invalid. Expected: ${Address.toChecksummed(Address(addr))}`
    );
  }
  return Address(addr);
}

// Auto-correct checksum
function normalizeAddress(addr: string): string {
  const parsed = Address(addr);
  return Address.toChecksummed(parsed);
}

Contract Deployment

CREATE Address Prediction

// Predict next contract address
function predictNextContract(
  deployer: AddressType,
  currentNonce: bigint
): AddressType {
  return Address.calculateCreateAddress(deployer, currentNonce);
}

// Batch prediction
function predictMultipleDeployments(
  deployer: AddressType,
  startNonce: bigint,
  count: number
): AddressType[] {
  const addresses: AddressType[] = [];

  for (let i = 0; i < count; i++) {
    addresses.push(
      Address.calculateCreateAddress(deployer, startNonce + BigInt(i))
    );
  }

  return addresses;
}

CREATE2 Deterministic Deployment

import * as Hash from 'tevm/Hash';

// Calculate CREATE2 address
function calculateCreate2(
  deployer: AddressType,
  salt: HashType,
  initCode: Uint8Array
): AddressType {
  return Address.calculateCreate2Address(deployer, salt, initCode);
}

// Find vanity address
function findVanityCreate2(
  deployer: AddressType,
  initCode: Uint8Array,
  prefix: string,
  maxAttempts = 1000000
): { salt: HashType; address: AddressType } | null {
  for (let i = 0; i < maxAttempts; i++) {
    const salt = Hash.keccak256(new TextEncoder().encode(`salt${i}`));
    const addr = Address.calculateCreate2Address(deployer, salt, initCode);
    const hex = Address.toHex(addr);

    if (hex.startsWith(prefix)) {
      return { salt, address: addr };
    }
  }

  return null;
}

Key Derivation

From Private Key

import * as Secp256k1 from 'tevm/Secp256k1';

// Derive address from private key
function deriveAddress(privateKey: Uint8Array): AddressType {
  const publicKey = Secp256k1.derivePublicKey(privateKey, false);
  return Address.fromPublicKey(publicKey);
}

// Generate random address
function generateRandomAddress(): {
  privateKey: Uint8Array;
  address: AddressType;
} {
  const privateKey = Secp256k1.randomPrivateKey();
  const address = deriveAddress(privateKey);
  return { privateKey, address };
}

From Public Key

// Uncompressed public key (65 bytes)
function fromUncompressedPublicKey(pubkey: Uint8Array): AddressType {
  if (pubkey.length !== 65) {
    throw new Error("Expected 65-byte uncompressed public key");
  }
  return Address.fromPublicKey(pubkey);
}

// Compressed public key (33 bytes) - decompress first
function fromCompressedPublicKey(pubkey: Uint8Array): AddressType {
  if (pubkey.length !== 33) {
    throw new Error("Expected 33-byte compressed public key");
  }
  // Decompress using secp256k1
  const uncompressed = Secp256k1.decompressPublicKey(pubkey);
  return Address.fromPublicKey(uncompressed);
}

Comparison and Deduplication

Address Sets

// Deduplicate addresses
function deduplicateAddresses(addresses: AddressType[]): AddressType[] {
  const seen = new Set<string>();
  const unique: AddressType[] = [];

  for (const addr of addresses) {
    const hex = Address.toHex(addr);
    if (!seen.has(hex)) {
      seen.add(hex);
      unique.push(addr);
    }
  }

  return unique;
}

// Check membership
function containsAddress(
  addresses: AddressType[],
  target: AddressType
): boolean {
  return addresses.some(addr => Address.equals(addr, target));
}

Sorting

// Sort addresses lexicographically
function sortAddresses(addresses: AddressType[]): AddressType[] {
  return [...addresses].sort((a, b) => Address.compare(a, b));
}

// Find min/max address
function getAddressRange(addresses: AddressType[]) {
  if (addresses.length === 0) return null;

  let min = addresses[0];
  let max = addresses[0];

  for (const addr of addresses) {
    if (Address.compare(addr, min) < 0) min = addr;
    if (Address.compare(addr, max) > 0) max = addr;
  }

  return { min, max };
}

Display Formatting

Truncation

// Short format for UI
function formatAddressShort(addr: AddressType): string {
  return Address.toShortHex(addr);  // "0x742d…1e3e"
}

// Custom truncation
function formatAddressCustom(
  addr: AddressType,
  prefixLen: number,
  suffixLen: number
): string {
  const hex = Address.toHex(addr);
  const prefix = hex.slice(0, 2 + prefixLen);
  const suffix = hex.slice(-suffixLen);
  return `${prefix}${suffix}`;
}

Checksummed Display

// Always display checksummed
function displayAddress(addr: AddressType): string {
  return Address.toChecksummed(addr);
}

// With ENS fallback
async function displayAddressWithENS(
  addr: AddressType,
  provider: Provider
): Promise<string> {
  try {
    const name = await provider.lookupAddress(Address.toHex(addr));
    return name ?? Address.toChecksummed(addr);
  } catch {
    return Address.toChecksummed(addr);
  }
}

Special Addresses

Zero Address

// Check for zero address (burn address)
function isBurnAddress(addr: AddressType): boolean {
  return Address.equals(addr, Address.zero());
}

// Filter out zero addresses
function removeZeroAddresses(addresses: AddressType[]): AddressType[] {
  return addresses.filter(addr => !Address.equals(addr, Address.zero()));
}

Known Addresses

// Common addresses
const KNOWN_ADDRESSES = {
  zero: Address.zero(),
  weth: Address("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
  usdc: Address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
  dai: Address("0x6B175474E89094C44Da98b954EedeAC495271d0F")
};

function isKnownAddress(addr: AddressType): string | null {
  for (const [name, known] of Object.entries(KNOWN_ADDRESSES)) {
    if (Address.equals(addr, known)) {
      return name;
    }
  }
  return null;
}

Testing Patterns

Test Fixtures

const TEST_ADDRESSES = {
  alice: Address("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e"),
  bob: Address("0x1234567890123456789012345678901234567890"),
  carol: Address("0xabcdefabcdefabcdefabcdefabcdefabcdefabcd")
};

// Generate test address from seed
function testAddress(seed: number): AddressType {
  const bytes = new Uint8Array(20);
  bytes[0] = seed & 0xff;
  bytes[1] = (seed >> 8) & 0xff;
  return Address(bytes);
}

Mock Addresses

// Generate sequential test addresses
function generateTestAddresses(count: number): AddressType[] {
  return Array({ length: count }, (_, i) => testAddress(i));
}

// Random test address
function randomTestAddress(): AddressType {
  const bytes = new Uint8Array(20);
  crypto.getRandomValues(bytes);
  return Address(bytes);
}