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

# Branded Types

> Zero-overhead type safety for Ethereum primitives

Voltaire uses branded types to prevent common bugs like passing a Hash where an Address is expected. The brand exists only at compile time - at runtime, it's just a `Uint8Array`.

## What is a Branded Type?

A branded type adds a compile-time tag to a base type:

```typescript theme={null}
// The brand symbol (shared across all primitives)
declare const brand: unique symbol

// AddressType is a Uint8Array with an invisible brand tag
type AddressType = Uint8Array & { readonly [brand]: 'Address' }

// HashType is also a Uint8Array, but with a different brand
type HashType = Uint8Array & { readonly [brand]: 'Hash' }
```

At runtime, both are plain `Uint8Array`. TypeScript prevents you from mixing them up:

```typescript theme={null}
import { Address, Hash } from '@tevm/voltaire'

function transfer(to: AddressType, txHash: HashType) { /* ... */ }

const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
const hash = Hash('0x1234567890abcdef...')

transfer(addr, hash)  // OK
transfer(hash, addr)  // Type error: HashType is not assignable to AddressType
```

## Zero Runtime Overhead

The brand is a phantom type - it exists only in TypeScript's type system:

```typescript theme={null}
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')

// At runtime, it's just a Uint8Array
console.log(addr instanceof Uint8Array)  // true
console.log(addr.length)                  // 20
console.log(addr[0])                      // First byte as number

// All Uint8Array methods work
addr.slice(0, 4)
addr.subarray(12, 20)
new DataView(addr.buffer)
```

## Validation at Construction

Branded types are validated when created. If you have an `AddressType`, it's valid:

```typescript theme={null}
// These throw on invalid input
Address('0xnot_valid')           // Error: Invalid hex
Address('0x123')                 // Error: Must be 20 bytes
Address(new Uint8Array(10))      // Error: Must be 20 bytes

// If construction succeeds, the value is valid
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
// addr is guaranteed to be exactly 20 bytes of valid data
```

## Console Formatting

Branded types display nicely when logged:

```typescript theme={null}
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
console.log(addr)
// Address("0x742d35cc6634c0532925a3b844bc9e7595f51e3e")
```

## Using Branded Types in Function Signatures

Use branded types in your function parameters:

```typescript theme={null}
import type { AddressType } from '@tevm/voltaire/Address'
import type { HashType } from '@tevm/voltaire/Hash'

// Type-safe function - cannot swap arguments by accident
function verifyTransaction(from: AddressType, to: AddressType, txHash: HashType) {
  // No runtime validation needed - types guarantee validity
}
```

## API Documentation Note

All Voltaire documentation shows the **recommended API** using constructors like `Address()`, `Hash()`, etc. These return instances with prototype methods.

For bundle-size optimization, Voltaire also provides a [tree-shakeable functional API](/concepts/tree-shakeable-api) with the same method signatures but imported as standalone functions.

## All Branded Types

| Type                                                | Size        | Description                |
| --------------------------------------------------- | ----------- | -------------------------- |
| [AddressType](/primitives/address)                  | 20 bytes    | Ethereum address           |
| [HashType](/primitives/hash)                        | 32 bytes    | Keccak256 hash             |
| [BytecodeType](/primitives/bytecode)                | Variable    | EVM bytecode               |
| [BlobType](/primitives/blob)                        | 128 KB      | EIP-4844 blob              |
| [HexType](/primitives/hex)                          | Variable    | Hex string (`0x...`)       |
| [Uint8Type](/primitives/uint8)                      | 1 byte      | 8-bit unsigned integer     |
| [Uint16Type](/primitives/uint16)                    | 2 bytes     | 16-bit unsigned integer    |
| [Uint32Type](/primitives/uint32)                    | 4 bytes     | 32-bit unsigned integer    |
| [Uint64Type](/primitives/uint64)                    | 8 bytes     | 64-bit unsigned integer    |
| [Uint128Type](/primitives/uint128)                  | 16 bytes    | 128-bit unsigned integer   |
| [Uint256Type](/primitives/uint)                     | 32 bytes    | 256-bit unsigned integer   |
| [Int8Type](/primitives/int8)                        | 1 byte      | 8-bit signed integer       |
| [Int16Type](/primitives/int16)                      | 2 bytes     | 16-bit signed integer      |
| [Int32Type](/primitives/int32)                      | 4 bytes     | 32-bit signed integer      |
| [Int64Type](/primitives/int64)                      | 8 bytes     | 64-bit signed integer      |
| [Int128Type](/primitives/int128)                    | 16 bytes    | 128-bit signed integer     |
| [Int256Type](/primitives/int256)                    | 32 bytes    | 256-bit signed integer     |
| [Bytes1-32](/primitives/bytes32)                    | 1-32 bytes  | Fixed-size byte arrays     |
| [Bytes64](/primitives/bytes/bytes64)                | 64 bytes    | 64-byte array (signatures) |
| [WeiType](/primitives/denomination)                 | bigint      | Wei denomination           |
| [GweiType](/primitives/denomination)                | bigint      | Gwei denomination          |
| [EtherType](/primitives/denomination)               | bigint      | Ether denomination         |
| [AccessListType](/primitives/accesslist)            | Variable    | EIP-2930 access list       |
| [AuthorizationType](/primitives/authorization)      | Variable    | EIP-7702 authorization     |
| [SignatureType](/primitives/signature)              | 64-65 bytes | ECDSA/Ed25519 signature    |
| [SelectorType](/primitives/selector)                | 4 bytes     | Function selector          |
| [CallDataType](/primitives/calldata)                | Variable    | Contract call data         |
| [EventLogType](/primitives/eventlog)                | Variable    | Event log entry            |
| [ReceiptType](/primitives/receipt)                  | Variable    | Transaction receipt        |
| [NonceType](/primitives/nonce)                      | bigint      | Account nonce              |
| [BlockNumberType](/primitives/block-number)         | bigint      | Block number               |
| [TransactionHashType](/primitives/transaction-hash) | 32 bytes    | Transaction hash           |
| [BlockHashType](/primitives/block-hash)             | 32 bytes    | Block hash                 |
| [GasLimitType](/primitives/gas)                     | bigint      | Gas limit                  |
| [GasPriceType](/primitives/gas)                     | bigint      | Gas price                  |
| [PrivateKeyType](/primitives/private-key)           | 32 bytes    | Private key                |
| [PublicKeyType](/primitives/public-key)             | 64 bytes    | Uncompressed public key    |
| [Base64Type](/primitives/base64)                    | Variable    | Base64 encoded string      |
| [RlpType](/primitives/rlp)                          | Variable    | RLP encoded data           |
| [ChainIdType](/primitives/chain)                    | number      | Chain identifier           |
| [OpcodeType](/primitives/opcode)                    | number      | EVM opcode                 |

## Schema Annotations

When using Effect Schema, annotate schemas with metadata for better error messages, JSON Schema generation, and form integration:

```typescript theme={null}
import * as S from "effect/Schema"

const AddressHex = S.String.pipe(
  S.pattern(/^0x[a-fA-F0-9]{40}$/),
  S.brand("Address")
).annotations({
  identifier: "Address.Hex",
  title: "Ethereum Address",
  description: "A 20-byte Ethereum address as a checksummed hex string",
  examples: [
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
  ],
  message: () => "Expected a valid Ethereum address (40 hex characters with 0x prefix)"
})
```

Benefits:

* **Better errors**: Custom `message` replaces raw parse errors
* **JSON Schema**: `JSONSchema.make()` generates OpenAPI-compatible specs
* **Form labels**: `title` and `description` for UI integration
* **IDE support**: Annotations surface in hover information

See [Schema Annotations](/concepts/schema-annotations) for complete documentation.

## Learn More

<CardGroup cols={2}>
  <Card title="Schema Annotations" icon="tag" href="/concepts/schema-annotations">
    Annotate schemas for better DX
  </Card>

  <Card title="Tree-Shakeable API" icon="leaf" href="/concepts/tree-shakeable-api">
    Functional API for minimal bundle size
  </Card>

  <Card title="Address Primitive" icon="cube" href="/primitives/address">
    Complete Address API reference
  </Card>
</CardGroup>
