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

# BrandedHardfork

> Branded type pattern for type-safe hardfork representation

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

# BrandedHardfork

Branded type pattern for type-safe hardfork representation.

## Overview

BrandedHardfork uses TypeScript's branded type pattern to create a distinct type from strings while maintaining runtime string behavior.

```typescript theme={null}
type BrandedHardfork = string & { readonly __tag: "Hardfork" };
```

## Type Definition

### BrandedHardfork Type

```typescript theme={null}
/**
 * Branded Hardfork type
 *
 * Hardfork is a branded string type that represents Ethereum protocol upgrades.
 * Each hardfork represents a protocol upgrade that changes EVM behavior,
 * gas costs, or adds new features.
 */
export type BrandedHardfork = string & {
  readonly __tag: "Hardfork";
};
```

**Key Properties:**

* Extends `string` - all string methods available
* Phantom `__tag` property - compile-time only, no runtime overhead
* Readonly - immutable by type system
* Nominal typing - distinct from plain strings

## Branded Type Pattern

### What is Branding?

Branding adds a phantom type property to distinguish similar types at compile time:

```typescript theme={null}
type UserId = string & { __tag: "UserId" };
type Email = string & { __tag: "Email" };

// Compile error - types are distinct
function sendEmail(email: Email) { }
const userId: UserId = "user123" as UserId;
sendEmail(userId);  // Error: UserId not assignable to Email
```

### Why Use Branding?

**Type Safety:**

```typescript theme={null}
// Without branding - both are strings
function processNetwork(hardfork: string, chainId: string) {
  // Easy to swap arguments accidentally
}

// With branding - compile-time protection
function processNetwork(hardfork: BrandedHardfork, chainId: ChainId) {
  // Arguments can't be swapped
}
```

**Runtime Behavior:**

```typescript theme={null}
// Branded types are still strings at runtime
const fork: BrandedHardfork = "cancun" as BrandedHardfork;
console.log(typeof fork);  // "string"
console.log(fork.toUpperCase());  // "CANCUN"
```

**No Runtime Overhead:**

```typescript theme={null}
// Phantom property doesn't exist at runtime
const fork: BrandedHardfork = "cancun" as BrandedHardfork;
console.log(fork.__tag);  // undefined (not "Hardfork")
```

## Implementation

### Constants

All hardfork constants are branded strings:

```typescript theme={null}
// From constants.js
export const FRONTIER: BrandedHardfork = "frontier" as BrandedHardfork;
export const HOMESTEAD: BrandedHardfork = "homestead" as BrandedHardfork;
export const CANCUN: BrandedHardfork = "cancun" as BrandedHardfork;
// ...
```

### Factory Function

```typescript theme={null}
function fromString(name: string): BrandedHardfork | undefined {
  const lower = name.toLowerCase();
  return NAME_TO_HARDFORK[lower];  // Returns branded type or undefined
}
```

### Ordering Array

```typescript theme={null}
export const HARDFORK_ORDER: BrandedHardfork[] = [
  FRONTIER,
  HOMESTEAD,
  DAO,
  // ...
  OSAKA,
];
```

### Name Lookup

```typescript theme={null}
export const NAME_TO_HARDFORK: Record<string, BrandedHardfork> = {
  frontier: FRONTIER,
  homestead: HOMESTEAD,
  // ...
  paris: MERGE,  // Alias
};
```

## Usage Patterns

### Type Guards

```typescript theme={null}
function isBrandedHardfork(value: unknown): value is BrandedHardfork {
  if (typeof value !== "string") return false;
  return Hardfork.isValidName(value);
}

// Usage
const input: unknown = getUserInput();
if (isBrandedHardfork(input)) {
  // input is BrandedHardfork here
  Hardfork.hasEIP1559(input);
}
```

### Type Assertions

```typescript theme={null}
// Safe - validated first
const fork = Hardfork("cancun");
if (fork) {
  // fork is BrandedHardfork
}

// Unsafe - skip validation (use carefully)
const fork = "cancun" as BrandedHardfork;
```

### Function Signatures

```typescript theme={null}
// Clear type requirements
function estimateGas(
  fork: BrandedHardfork,
  bytecode: Uint8Array
): bigint {
  if (Hardfork.hasEIP3855(fork)) {
    // PUSH0 available
  }
  // ...
}

// Can't accidentally pass wrong type
estimateGas("cancun", data);  // Error: string not BrandedHardfork
estimateGas(CANCUN, data);    // OK
```

## Advantages

### 1. Compile-Time Safety

```typescript theme={null}
// Prevents mixing up similar string parameters
function compare(a: BrandedHardfork, b: BrandedHardfork): number {
  return Hardfork.compare(a, b);
}

// Can't accidentally swap with other strings
const chainId = "1";
compare(CANCUN, chainId);  // Error: string not assignable to BrandedHardfork
```

### 2. Self-Documenting Code

```typescript theme={null}
// Clear what type of string is expected
function getFeatures(fork: BrandedHardfork): Features {
  // Obviously dealing with hardfork, not just any string
}
```

### 3. Zero Runtime Cost

```typescript theme={null}
// No runtime overhead - still just strings
const fork: BrandedHardfork = "cancun" as BrandedHardfork;
console.log(fork.length);     // 6
console.log(fork[0]);          // "c"
console.log(fork.includes("c")); // true
```

## Best Practices

### 1. Use Factory Functions

```typescript theme={null}
// Good - validated and branded
const fork = Hardfork(userInput);
if (!fork) throw new Error("Invalid hardfork");

// Bad - unsafe assertion
const fork = userInput as BrandedHardfork;
```

### 2. Validate at Boundaries

```typescript theme={null}
// Validate at system boundaries
function handleApiRequest(req: Request): Response {
  const hardforkStr = req.body.hardfork;

  // Validate and brand
  const fork = Hardfork(hardforkStr);
  if (!fork) {
    return badRequest("Invalid hardfork");
  }

  // Now type-safe throughout application
  return processRequest(fork);
}
```

### 3. Documentation

```typescript theme={null}
/**
 * Estimates gas for operation
 * @param fork - Ethereum hardfork version (e.g., CANCUN, SHANGHAI)
 * @param operation - Operation to estimate
 * @returns Estimated gas cost
 */
function estimateGas(fork: BrandedHardfork, operation: Operation): bigint {
  // ...
}
```

## Related Branded Types

Similar pattern used throughout primitives:

```typescript theme={null}
// Address primitive
type AddressType = Uint8Array & { __tag: "Address" };

// Hex primitive
type HexType = string & { __tag: "Hex" };

// Hash primitive
type HashType = Uint8Array & { __tag: "Hash" };
```

**Consistency Benefits:**

* Similar API patterns across primitives
* Predictable type safety
* Zero runtime overhead across all types
