> ## 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.

# Address

> 20-byte Ethereum address with EIP-55 checksumming

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/address.ts">
  Run Address examples in the interactive playground
</Card>

# Address

Ethereum addresses are 20-byte identifiers for accounts (both externally-owned and contracts). They're derived from public keys (EOAs) or calculated deterministically during contract deployment.

<Tip title="Learn the fundamentals">
  New to Ethereum addresses? Start with [Fundamentals](/primitives/address/fundamentals) to learn address derivation, EIP-55 checksumming, and CREATE/CREATE2 contract deployment.
</Tip>

## Overview

Address is a specialized [branded](/getting-started/branded-types) [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) that extends the 20-byte (Bytes20) type with address-specific semantics, including EIP-55 mixed-case checksumming for error detection and validation.

<Tabs>
  <Tab title="Type Definition">
    ```typescript theme={null}
    import type { brand } from './brand.js'

    export type AddressType = Uint8Array & {
      readonly [brand]: "Address"
    }
    ```

    Address is a branded `Uint8Array` (20 bytes). TypeScript enforces type safety through a unique Symbol brand, preventing accidental mixing with other Uint8Arrays while maintaining zero runtime overhead.
  </Tab>
</Tabs>

Voltaire handles checksums automatically while storing addresses as raw bytes internally to avoid case-sensitivity bugs.

### Developer Experience

Despite being a `Uint8Array`, addresses display formatted in most environments:

```typescript theme={null}
const address = Address(0x742d35Cc6634C0532925a3b844Bc9e7595f51e3en);
console.log(address);
// Address("0x742d35cc6634c0532925a3b844bc9e7595f51e3e")
```

This makes debugging more readable than raw byte arrays while maintaining the performance and compatibility benefits of `Uint8Array`.

## API Styles

Voltaire offers two API styles for Address:

<Tabs>
  <Tab title="Class API">
    ```typescript theme={null}
    import { Address } from '@tevm/voltaire/Address'

    const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
    addr.toHex()
    addr.toChecksummed()
    addr.equals(otherAddr)
    ```

    OOP-style with instance methods. Good for method chaining.
  </Tab>

  <Tab title="Functional API">
    ```typescript theme={null}
    import { from, toHex, toChecksummed, equals } from '@tevm/voltaire/Address/functional'

    const addr = from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
    toHex(addr)
    toChecksummed(addr)
    equals(addr, otherAddr)
    ```

    Tree-shakeable - only imported functions bundled.
  </Tab>

  <Tab title="Namespace Import">
    ```typescript theme={null}
    import { Address } from '@tevm/voltaire/functional'

    const addr = Address.from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
    Address.toHex(addr)
    Address.toChecksummed(addr)
    ```

    Functional API with namespace grouping.
  </Tab>
</Tabs>

## Quick Start

<Tabs>
  <Tab title="Basic Usage">
    ```typescript theme={null}
    import { Address } from '@tevm/voltaire/Address';

    // Create from hex string
    const addr = Address.from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e');

    // Get checksummed representation
    console.log(Address.toChecksummed(addr));
    // "0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e"

    // Get lowercase hex
    console.log(Address.toHex(addr));
    // "0x742d35cc6634c0532925a3b844bc9e7595f51e3e"

    // Validate checksum
    console.log(Address.isValidChecksum('0x742d35Cc...'));
    // true
    ```
  </Tab>

  <Tab title="From Public Key">
    ```typescript theme={null}
    import { Address } from '@tevm/voltaire/Address';
    import { Secp256k1 } from '@tevm/voltaire/Secp256k1';

    // Derive address from private key
    const privateKey = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
    const addr = Address.fromPrivateKey(privateKey);

    // Or from public key coordinates
    const pubKey = Secp256k1.derivePublicKey(privateKey);
    const addr2 = Address.fromPublicKey(pubKey.x, pubKey.y);

    console.log(Address.toChecksummed(addr));
    // "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
    ```
  </Tab>

  <Tab title="Contract Addresses">
    ```typescript theme={null}
    import { Address } from '@tevm/voltaire/Address';
    import { Bytes32 } from '@tevm/voltaire/Bytes32';
    import { Bytecode } from '@tevm/voltaire/Bytecode';

    // Predict CREATE address
    const deployer = Address.from('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e');
    const nonce = 0n;
    const createAddr = Address.calculateCreateAddress(deployer, nonce);

    // Predict CREATE2 address
    const salt = Bytes32('0x1234...');
    const initCode = Bytecode.from('0x6080...');
    const create2Addr = Address.calculateCreate2Address(deployer, salt, initCode);

    console.log(Address.toHex(createAddr));
    console.log(Address.toHex(create2Addr));
    ```
  </Tab>
</Tabs>

## Practical Examples

See [Fundamentals](/primitives/address/fundamentals) for detailed explanations of address derivation, checksumming, and contract address calculation.

## API Methods

### Constructors

* [`from(value)`](./from) - Universal constructor from any input
* [`fromHex(hex)`](./from-hex) - Parse hex string (with or without 0x prefix)
* [`fromBytes(bytes)`](./from-bytes) - Create from Uint8Array (must be 20 bytes)
* [`fromNumber(value)`](./from-number) - Create from bigint or number
* [`fromPublicKey(x, y)`](./from-public-key) - Derive from secp256k1 public key
* [`fromPrivateKey(privateKey)`](./from-private-key) - Derive from private key
* [`zero()`](./zero) - Create zero address (0x0000...0000)

### Conversions

* [`toHex(address)`](./to-hex) - Convert to lowercase hex string with 0x prefix
* [`toChecksummed(address)`](./to-checksummed) - Convert to EIP-55 mixed-case checksummed hex
* [`toShortHex(address)`](./to-short-hex) - Format for display (0x742d…1e3e)
* [`toBytes(address)`](./to-bytes) - Return raw Uint8Array

### Validation

* [`isValid(value)`](./is-valid) - Check if value can be converted to address
* [`isValidChecksum(hex)`](./is-valid-checksum) - Verify EIP-55 checksum (case-sensitive)
* [`assert(value, options?)`](./assert) - Assert value is valid address, with optional strict checksum validation

### Comparisons

* [`equals(a, b)`](./equals) - Check equality
* [`compare(a, b)`](./compare) - Compare for sorting (-1, 0, 1)

### Contract Addresses

* [`calculateCreateAddress(address, nonce)`](./calculate-create-address) - Calculate CREATE deployment address
* [`calculateCreate2Address(address, salt, initCode)`](./calculate-create2-address) - Calculate CREATE2 deployment address

### Reference

* [Fundamentals](./fundamentals) - Address derivation, checksumming, and deployment
* [Usage Patterns](./usage-patterns) - Common patterns and best practices
* [AddressType](./branded-address) - Type definition and branded type pattern
* [Variants](./variants) - Additional utilities and variants
* [WASM](./wasm) - WebAssembly implementation details

### Complete API

<Tabs />

## Types

<Tabs>
  <Tab title="AddressType">
    ```typescript theme={null}
    import type { brand } from './brand.js'

    export type AddressType = Uint8Array & {
      readonly [brand]: "Address"
    }
    ```

    Main branded type. Runtime is `Uint8Array` (20 bytes), TypeScript enforces type safety through Symbol branding.
  </Tab>

  <Tab title="AddressLike">
    ```typescript theme={null}
    type AddressLike =
      | Uint8Array
      | AddressType
      | Address
      | string
      | number
      | bigint
    ```

    Union type accepting any input that can be coerced to address. Accepted by `Address.from()`.
  </Tab>

  <Tab title="Hex Variants">
    ```typescript theme={null}
    import type { Hex } from '@tevm/voltaire/Hex'

    export type Checksummed = Hex.Sized<20> & {
      readonly __variant: 'Address'
      readonly __checksummed: true
    }

    export type Lowercase = Hex.Sized<20> & {
      readonly __variant: 'Address'
      readonly __lowercase: true
    }

    export type Uppercase = Hex.Sized<20> & {
      readonly __variant: 'Address'
      readonly __uppercase: true
    }
    ```

    Branded hex string types for different address formats. See [variants](./variants) for details.
  </Tab>
</Tabs>

## Constants

```typescript theme={null}
Address.SIZE      // 20 - Address size in bytes
Address.HEX_SIZE  // 42 - Hex string length with "0x" prefix (2 + 40 characters)

// ERC-7528: Native asset address constant
Address.NATIVE_ASSET_ADDRESS  // "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
```

### NATIVE\_ASSET\_ADDRESS (ERC-7528)

```typescript theme={null}
const NATIVE_ASSET_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
```

Standard address representing native ETH in token-related operations, as defined in [ERC-7528](https://eips.ethereum.org/EIPS/eip-7528).

**Use cases:**

* Representing ETH in token lists alongside ERC-20 tokens
* Multicall operations mixing ETH and token transfers
* DEX interfaces treating ETH as a "token"

**Example:**

```typescript theme={null}
import { NATIVE_ASSET_ADDRESS } from '@tevm/voltaire/Address';

// Check if address is native ETH
function isNativeAsset(tokenAddress: string): boolean {
  return tokenAddress.toLowerCase() === NATIVE_ASSET_ADDRESS.toLowerCase();
}

// Handle token or ETH transfer
async function transfer(token: string, to: string, amount: bigint) {
  if (isNativeAsset(token)) {
    // Send ETH
    await sendTransaction({ to, value: amount });
  } else {
    // Send ERC-20
    await erc20.transfer(to, amount);
  }
}
```

## Usage Patterns

### Validating User Input

```typescript theme={null}
// Safe parsing with validation
function parseUserAddress(input: string): Address {
  if (!Address.isValid(input)) {
    throw new Error("Invalid address format");
  }

  const addr = Address(input);

  // Optionally verify checksum if provided
  if (Address.isValidChecksum(input) === false) {
    console.warn("Checksum mismatch - possible typo");
  }

  return addr;
}

// Usage
try {
  const addr = parseUserAddress("0x742d35Cc...");
  console.log(`Valid address: ${addr.toChecksummed()}`);
} catch (e) {
  console.error("Invalid address");
}
```

### Sorting and Deduplicating

```typescript theme={null}
// Sort addresses for consistent ordering
const addresses = [
  Address("0xCCCC..."),
  Address("0xAAAA..."),
  Address("0xBBBB..."),
];

const sorted = Address.sortAddresses(addresses);
console.log(sorted.map(a => a.toHex()));
// ["0xaaaa...", "0xbbbb...", "0xcccc..."]

// Remove duplicates
const unique = Address.deduplicateAddresses([addr1, addr2, addr1]);
console.log(unique.length); // 2
```

### Predicting Contract Addresses

```typescript theme={null}
// Predict CREATE2 address before deployment
const factory = Address("0x...");
const salt = Bytes32();
const initCode = compileContract(); // bytecode

// Calculate address deterministically
const predictedAddress = factory.calculateCreate2Address(salt, initCode);

// Deploy contract
await deployer.deploy(initCode, salt);

// Verify prediction
const deployedAddress = await getDeployedAddress();
console.log(predictedAddress.equals(deployedAddress)); // true
```

## Tree-Shaking

Import only what you need for optimal bundle size:

```typescript theme={null}
// Import specific functions (tree-shakeable)
import { fromHex, toChecksummed, equals } from '@tevm/voltaire/Address';

const addr = fromHex("0x742d35cc...");
const checksummed = toChecksummed(addr);
const isEqual = equals(addr, addr2);

// Only these 3 functions included in bundle
// Unused functions (calculateCreateAddress, fromPublicKey, etc.) excluded
```

<Tip title="Bundle Impact">
  Importing from `tevm/Address` instead of the main entry point enables tree-shaking. For example, if you only need `fromHex` and `toChecksummed`, contract address calculation and public key derivation are excluded from your bundle.
</Tip>

## Related

* [Address (Effect)](https://voltaire-effect.tevm.sh/primitives/address) - Effect.ts integration with Schema validation
* [Keccak256](/crypto/keccak256) - Keccak256 hashing for address derivation and verification
* [Bytes](/primitives/bytes) - Fixed-size byte types including Bytes32 for salts
* [Uint](/primitives/uint) - Unsigned integer types for address arithmetic

## Try It Yourself

<div style={{ textAlign: 'left' }}>
  <div id="address-editor-mount" />
</div>

<script
  dangerouslySetInnerHTML={{__html: `
if (typeof window !== 'undefined') {
window.addEventListener('load', function() {
  setTimeout(async () => {
    const mountPoint = document.getElementById('address-editor-mount');
    if (!mountPoint) return;

    mountPoint.innerHTML = \\\`
      <h2 style="font-size: clamp(2rem, 5vw, 2.5rem); font-weight: 700; text-align: center; margin-bottom: 1rem; background: linear-gradient(135deg, #E6A23C 0%, #A0522D 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">Interactive Address Demo</h2>
      <p style="font-size: 1.1rem; color: #999; text-align: center; margin-bottom: 2rem;">
        Try Address utilities in your browser
      </p>
      <div id="address-editor" style="width: 100%; height: 400px; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 12px 12px 0 0; overflow: hidden; position: relative;"></div>
      <div style="display: flex; gap: 0; border: 1px solid rgba(255, 255, 255, 0.1); border-top: none;">
        <button id="address-run-btn" style="flex: 1; padding: 0.75rem 1.5rem; background: linear-gradient(135deg, #E6A23C 0%, #A0522D 100%); color: white; border: none; font-weight: 600; cursor: pointer; transition: all 0.15s ease; font-size: 0.95rem;">
          ▶ Run Code
        </button>
        <button id="address-clear-btn" style="flex: 0 0 auto; padding: 0.75rem 1.5rem; background: transparent; color: #E6A23C; border: none; border-left: 1px solid rgba(255, 255, 255, 0.1); cursor: pointer; transition: all 0.15s ease; font-size: 0.95rem; font-weight: 600;">
          Clear
        </button>
      </div>
      <div id="address-console" style="min-height: 150px; max-height: 300px; overflow-y: auto; background: #1e1e1e; border: 1px solid rgba(255, 255, 255, 0.1); border-top: none; border-radius: 0 0 12px 12px; padding: 1rem; font-family: 'Menlo, Monaco, Courier New, monospace'; font-size: 0.875rem; line-height: 1.6; color: #d4d4d4; word-wrap: break-word; white-space: pre-wrap;">
        <div style="color: #858585; font-style: italic;">Console output will appear here...</div>
      </div>
    \\\`;

    try {
      const { init } = await import('https://esm.sh/modern-monaco@0.2.2');
      const monaco = await init();

      const code = \\\`// Address utilities demo\\\\n\\\` +
        \\\`// All Voltaire APIs are available globally\\\\n\\\` +
        \\\`\\\\n\\\` +
        \\\`// Create from hex string\\\\n\\\` +
        \\\`const addr = Address.from("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e");\\\\n\\\` +
        \\\`console.log("Address:", Address.toHex(addr));\\\\n\\\` +
        \\\`console.log("Checksummed:", Address.toChecksummed(addr));\\\\n\\\` +
        \\\`\\\\n\\\` +
        \\\`// Validate checksum\\\\n\\\` +
        \\\`const isValid = Address.isValidChecksum("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e");\\\\n\\\` +
        \\\`console.log("Valid checksum:", isValid);\\\\n\\\` +
        \\\`\\\\n\\\` +
        \\\`// Check if zero address\\\\n\\\` +
        \\\`const zero = Address.zero();\\\\n\\\` +
        \\\`console.log("Zero address:", Address.toHex(zero));\\\\n\\\` +
        \\\`console.log("Is zero:", Address.isZero(zero));\\\\n\\\` +
        \\\`\\\\n\\\` +
        \\\`// Compare addresses\\\\n\\\` +
        \\\`const addr2 = Address.from("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045");\\\\n\\\` +
        \\\`console.log("Addresses equal:", Address.equals(addr, addr2));\\\`;

      const model = monaco.editor.createModel(code, 'typescript');
      const editor = monaco.editor.create(document.getElementById('address-editor'), {
        model: model,
        theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
        fontSize: 14,
        lineHeight: 21,
        fontFamily: 'Menlo, Monaco, "Courier New", monospace',
        minimap: { enabled: false },
        scrollBeyondLastLine: false,
        padding: { top: 16, bottom: 16, left: 16 },
        automaticLayout: true,
        lineNumbers: 'on',
        glyphMargin: false,
        folding: false,
        lineDecorationsWidth: 0,
        lineNumbersMinChars: 3,
        renderLineHighlight: 'line',
        scrollbar: { vertical: 'visible', horizontal: 'visible', useShadows: false, verticalScrollbarSize: 10, horizontalScrollbarSize: 10 },
        tabSize: 2,
        insertSpaces: true
      });

      const style = document.createElement('style');
      style.textContent = \\\`.monaco-editor .margin-view-overlays .line-numbers { padding-right: 16px !important; }\\\`;
      document.head.appendChild(style);

      // Setup execution (simplified from homepage)
      let worker = null;
      const runBtn = document.getElementById('address-run-btn');
      const clearBtn = document.getElementById('address-clear-btn');
      const consoleOut = document.getElementById('address-console');

      runBtn.onclick = async () => {
        if (worker) worker.terminate();
        consoleOut.innerHTML = '';
        runBtn.textContent = '⏸ Running...';
        runBtn.disabled = true;

        const workerCode = 'let Tevm=null;self.onmessage=async function(e){const{code,loadTevm}=e.data;const console={log:(...a)=>self.postMessage({type:"log",args:a.map(x=>typeof x==="object"?JSON.stringify(x,null,2):String(x))}),error:(...a)=>self.postMessage({type:"error",args:a.map(String)}),warn:(...a)=>self.postMessage({type:"warn",args:a.map(String)})};if(loadTevm&&!Tevm){try{const m=await import("https://esm.sh/@tevm/index@1.0.0-next.100");Tevm=m;Object.assign(globalThis,m);self.postMessage({type:"log",args:["Tevm loaded!"]});}catch(err){self.postMessage({type:"error",args:["Load failed: "+err.message]});}}try{const fn=new Function("console","Tevm",code);fn(console,Tevm);self.postMessage({type:"complete"});}catch(err){self.postMessage({type:"error",args:[err.message]});}};';
        worker = new Worker(URL.createObjectURL(new Blob([workerCode], { type: 'application/javascript' })));

        const timeout = setTimeout(() => { worker.terminate(); addLog('error', ['Timeout (5s)']); resetBtn(); }, 5000);

        worker.onmessage = (e) => {
          const { type, args } = e.data;
          if (type === 'complete') { clearTimeout(timeout); resetBtn(); }
          else if (type === 'log' || type === 'error' || type === 'warn') addLog(type, args);
        };

        worker.postMessage({ code: editor.getValue(), loadTevm: true });
      };

      clearBtn.onclick = () => {
        consoleOut.innerHTML = '<div style="color: #858585; font-style: italic;">Console output will appear here...</div>';
      };

      function addLog(type, args) {
        const entry = document.createElement('div');
        entry.style.marginBottom = '0.5rem';
        entry.style.paddingLeft = '1rem';
        entry.style.borderLeft = '3px solid';
        if (type === 'log') { entry.style.borderLeftColor = '#4CAF50'; entry.style.color = '#d4d4d4'; }
        else if (type === 'error') { entry.style.borderLeftColor = '#f44336'; entry.style.color = '#f48771'; }
        else if (type === 'warn') { entry.style.borderLeftColor = '#ff9800'; entry.style.color = '#dcdcaa'; }
        entry.textContent = args.join(' ');
        entry.style.whiteSpace = 'pre-wrap';
        entry.style.wordWrap = 'break-word';
        const placeholder = consoleOut.querySelector('[style*="italic"]');
        if (placeholder) placeholder.remove();
        consoleOut.appendChild(entry);
        consoleOut.scrollTop = consoleOut.scrollHeight;
      }

      function resetBtn() {
        runBtn.textContent = '▶ Run Code';
        runBtn.disabled = false;
      }

      setTimeout(() => editor.getAction('editor.action.formatDocument')?.run(), 100);
    } catch (e) {
      console.error('Failed to load editor:', e);
    }
  }, 500);
});
}
`}}
/>

## Specification References

* [EIP-55](https://eips.ethereum.org/EIPS/eip-55) - Mixed-case checksum address encoding
* [EIP-1014](https://eips.ethereum.org/EIPS/eip-1014) - CREATE2 opcode and deterministic addresses
* [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) - Address derivation (Section 7)
* [Account Model](https://ethereum.org/en/developers/docs/accounts/) - EOA vs Contract accounts
