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

> Validate EIP-55 checksummed address

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

<Tabs>
  <Tab title="TypeScript - Factory">
    ## `Address.IsValidChecksum({ keccak256 })`

    Factory function that creates a checksum validator with explicit crypto dependency.

    **Parameters:**

    * `deps: { keccak256: (data: Uint8Array) => Uint8Array }` - Crypto dependencies

    **Returns:** `(str: string) => boolean`

    **Bundle size benefit:** Crypto dependencies explicit - only bundled if you import them.

    **Example:**

    ```typescript theme={null}
    import { IsValidChecksum } from 'tevm/Address/AddressType'
    import { hash as keccak256 } from 'tevm/crypto/Keccak256'

    // Create factory with explicit crypto dependency
    const isValidChecksum = IsValidChecksum({ keccak256 })

    // Validate checksummed addresses
    isValidChecksum("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed") // true
    isValidChecksum("0x5aaeb6053F3E94C9b9A09f33669435E7Ef1BeAed") // false
    ```
  </Tab>

  <Tab title="C">
    ## `bool primitives_address_validate_checksum(const char* hex)`

    Validate EIP-55 checksum in C. Checks if hex string has valid mixed-case checksum.

    **Parameters:**

    * `hex: const char*` - Address hex string (with or without `0x` prefix)

    **Returns:** `bool` - `true` if checksum is valid

    **Example:**

    ```c theme={null}
    #include "primitives.h"
    #include <stdio.h>

    // Valid checksummed addresses
    bool valid1 = primitives_address_validate_checksum("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed");
    printf("Valid: %d\n", valid1); // 1 (true)

    bool valid2 = primitives_address_validate_checksum("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e");
    printf("Valid: %d\n", valid2); // 1 (true)

    // Invalid checksum (wrong casing)
    bool invalid1 = primitives_address_validate_checksum("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed");
    printf("Valid: %d\n", invalid1); // 0 (false)

    bool invalid2 = primitives_address_validate_checksum("0x742D35CC6634C0532925A3B844BC9E7595F51E3E");
    printf("Valid: %d\n", invalid2); // 0 (false) - wrong case

    // All lowercase/uppercase passes (no checksum)
    bool lower = primitives_address_validate_checksum("0x742d35cc6634c0532925a3b844bc9e7595f51e3e");
    printf("Valid: %d\n", lower); // 1 (true)

    bool upper = primitives_address_validate_checksum("0x742D35CC6634C0532925A3B844BC9E7595F51E3E");
    printf("Valid: %d\n", upper); // 1 (true)
    ```

    **EIP-55 Rules:**

    * All lowercase: valid (no checksum to verify)
    * All uppercase: valid (no checksum to verify)
    * Mixed case: must match keccak256-based checksum

    **Use Case - Strict Validation:**

    ```c theme={null}
    #include "primitives.h"

    int parse_strict_address(const char* input, PrimitivesAddress* out) {
        // Validate checksum first
        if (!primitives_address_validate_checksum(input)) {
            return -1; // Invalid checksum
        }

        // Parse if valid
        return primitives_address_from_hex(input, out);
    }
    ```

    **Memory:** No allocation - pure validation function.

    **Defined in:** [primitives.h:130](https://github.com/evmts/voltaire/blob/main/src/primitives.h#L130)
  </Tab>
</Tabs>

## EIP-55 Checksum Rules

**All lowercase:** Valid (no checksum to verify)

```typescript theme={null}
Address.isValidChecksum("0x742d35cc6634c0532925a3b844bc9e7595f51e3e") // true
```

**All uppercase:** Valid (no checksum to verify)

```typescript theme={null}
Address.isValidChecksum("0x742D35CC6634C0532925A3B844BC9E7595F51E3E") // true
```

**Mixed case:** Must match keccak256-based checksum

```typescript theme={null}
// Correct mixed case
Address.isValidChecksum("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e") // true

// Incorrect mixed case
Address.isValidChecksum("0x742d35cc6634c0532925a3b844bc9e7595f51e3E") // false
```

## Use Cases

### Strict Validation

Require checksummed addresses:

```typescript theme={null}
import { Address } from 'tevm'

function parseStrictAddress(input: string): Address {
  if (!Address.isValid(input)) {
    throw new Error('Invalid address format')
  }

  if (!Address.isValidChecksum(input)) {
    throw new Error('Invalid or missing EIP-55 checksum')
  }

  return Address(input)
}
```

### Warn on Invalid Checksum

Accept but warn about invalid checksums:

```typescript theme={null}
import { Address } from 'tevm'

function parseAddressWithWarning(input: string): Address {
  if (!Address.isValid(input)) {
    throw new Error('Invalid address format')
  }

  if (!Address.isValidChecksum(input)) {
    console.warn('Address has invalid checksum. Double-check the address.')
  }

  return Address(input)
}
```

### UI Validation

Provide checksum feedback in forms:

```typescript theme={null}
import { Address } from 'tevm'

function validateAddressInput(value: string) {
  if (!value) {
    return { valid: false, message: 'Address required' }
  }

  if (!Address.isValid(value)) {
    return { valid: false, message: 'Invalid address format' }
  }

  if (!Address.isValidChecksum(value)) {
    return {
      valid: true,
      warning: 'Invalid checksum. Address may be mistyped.'
    }
  }

  return { valid: true }
}
```

### Accept Lowercase, Return Checksummed

Accept any valid format, return checksummed:

```typescript theme={null}
import { Address } from 'tevm'

function normalizeAddress(input: string): string {
  if (!Address.isValid(input)) {
    throw new Error('Invalid address')
  }

  const addr = Address(input)
  return addr.toChecksummed() // Always return checksummed
}

// All inputs normalized to checksummed
console.log(normalizeAddress("0x742d35cc6634c0532925a3b844bc9e7595f51e3e"))
// "0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e"
```

## Checksum Calculation

The checksum is computed as follows:

1. Convert address to lowercase hex (without `0x`)
2. Compute keccak256 hash of lowercase string
3. For each hex character (if letter):
   * If corresponding hash nibble >= 8: uppercase
   * Otherwise: lowercase

**Example:**

```typescript theme={null}
import { Address } from 'tevm'

const lowercase = "0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed"
const addr = Address(lowercase)

// Generate checksummed version
const checksummed = addr.toChecksummed()
console.log(checksummed)
// "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"
//     ^  ^     ^  ^ ^^     ^  ^             ^

// Verify checksum
console.log(Address.isValidChecksum(checksummed)) // true
console.log(Address.isValidChecksum(lowercase))   // true (all lowercase = no checksum)
```

## Common Scenarios

**QR Code addresses:** Often all uppercase (valid):

```typescript theme={null}
const qrCode = "0x742D35CC6634C0532925A3B844BC9E7595F51E3E"
console.log(Address.isValidChecksum(qrCode)) // true (all uppercase)
```

**Database addresses:** Often lowercase (valid):

```typescript theme={null}
const db = "0x742d35cc6634c0532925a3b844bc9e7595f51e3e"
console.log(Address.isValidChecksum(db)) // true (all lowercase)
```

**User input:** May have incorrect checksum (invalid):

```typescript theme={null}
const userInput = "0x742d35cc6634c0532925a3b844bc9e7595f51e3E" // Wrong!
console.log(Address.isValidChecksum(userInput)) // false (mixed case wrong)
```

## Error Detection

Checksums help detect typos:

```typescript theme={null}
import { Address } from 'tevm'

// Original (correct)
const correct = "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"

// Typo: changed 'a' to 'b' at position 3
const typo = "0x5bAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"

console.log(Address.isValidChecksum(correct)) // true
console.log(Address.isValidChecksum(typo))    // false (checksum mismatch)
```

**Detection rate:** EIP-55 checksums can detect:

* \~99.986% of single character errors
* Most multi-character errors

**Not detected:**

* All lowercase → all lowercase (no checksum)
* All uppercase → all uppercase (no checksum)

## Performance

**Cryptographic operation:** Uses keccak256 hash internally.

**Bundle size impact:** With the factory pattern, keccak256 is only bundled if you explicitly import it. Crypto dependencies are now explicit and tree-shakeable.

**Alternative:** Use `isValid()` if checksum verification not required.

## Integration with Parsing

**Validate before parsing:**

```typescript theme={null}
import { Address } from 'tevm'

if (!Address.isValid(input)) {
  throw new Error('Invalid format')
}

if (!Address.isValidChecksum(input)) {
  console.warn('Invalid checksum')
}

const addr = Address(input)
```

**Parse then validate:**

```typescript theme={null}
import { Address } from 'tevm'

const addr = Address(input)

// Check if input had valid checksum
if (!Address.isValidChecksum(input)) {
  console.warn('Input had invalid checksum')
}

// Always return checksummed
return addr.toChecksummed()
```

## See Also

* [toChecksummed](/primitives/address/to-checksummed) - Generate checksummed address
* [isValid](/primitives/address/is-valid) - Validate address format
* [fromHex](/primitives/address/from-hex) - Parse address from hex
* [EIP-55: Mixed-case checksum](https://eips.ethereum.org/EIPS/eip-55)
* [Keccak256](/crypto/keccak256) - Keccak256 hash function
