# `Onchain.Hex`
[🔗](https://github.com/ZenHive/onchain/blob/v0.5.4/lib/onchain/hex.ex#L1)

Hex encoding/decoding for Ethereum data.

Curated 7-function API delegating to `Cartouche.Hex` with normalized error tuples
and descripex self-description. All hex strings use the `0x` prefix convention.

## Error Format

All failable functions return `{:error, {:invalid_hex, input}}` where `input`
is the original value that failed to decode. Bang variants raise
`Cartouche.Hex.InvalidHex`.

## Functions

| Function | Purpose |
|----------|---------|
| `decode/1` | Hex string → binary |
| `decode!/1` | Hex string → binary (raises) |
| `encode/1` | Binary → hex string |
| `to_integer/1` | Hex string → integer |
| `to_integer!/1` | Hex string → integer (raises) |
| `from_integer/1` | Integer → compact hex string |
| `valid?/1` | Check if string is valid hex |

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `valid?` | 1 | Check whether a string is valid hex (with or without 0x prefix). | `input: value` |
| `from_integer` | 1 | Encode a non-negative integer as a compact 0x-prefixed hex string. | `n: value` |
| `to_integer!` | 1 | Decode a hex string to a non-negative integer. Raises on invalid input. | `hex_string: value` |
| `to_integer` | 1 | Decode a hex string to a non-negative integer. | `hex_string: value` |
| `encode` | 1 | Encode raw binary to a 0x-prefixed lowercase hex string. | `binary: value` |
| `decode!` | 1 | Decode a hex string to raw binary. Raises on invalid input. | `hex_string: value` |
| `decode` | 1 | Decode a hex string to raw binary. | `hex_string: value` |

# `decode`

```elixir
@spec decode(String.t()) :: {:ok, binary()} | {:error, {:invalid_hex, String.t()}}
```

Decode a hex string to raw binary.

## Parameters

  * `hex_string` - Hex string with or without 0x prefix (value)

## Returns

Decoded binary bytes (`{:ok, binary} | {:error, {:invalid_hex, input}}`)

```elixir
# descripex:contract
%{
  params: %{
    hex_string: %{
      description: "Hex string with or without 0x prefix",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, binary} | {:error, {:invalid_hex, input}}",
    description: "Decoded binary bytes"
  }
}
```

# `decode!`

```elixir
@spec decode!(String.t()) :: binary()
```

Decode a hex string to raw binary. Raises on invalid input.

## Parameters

  * `hex_string` - Hex string with or without 0x prefix (value)

## Returns

Decoded binary bytes (`binary`)

```elixir
# descripex:contract
%{
  params: %{
    hex_string: %{
      description: "Hex string with or without 0x prefix",
      kind: :value
    }
  },
  returns: %{type: :binary, description: "Decoded binary bytes"}
}
```

# `encode`

```elixir
@spec encode(binary()) :: String.t()
```

Encode raw binary to a 0x-prefixed lowercase hex string.

## Parameters

  * `binary` - Raw binary bytes to encode (value)

## Returns

0x-prefixed lowercase hex string (`string`)

```elixir
# descripex:contract
%{
  params: %{binary: %{description: "Raw binary bytes to encode", kind: :value}},
  returns: %{
    type: :string,
    description: "0x-prefixed lowercase hex string",
    example: "0xaabb"
  }
}
```

# `from_integer`

```elixir
@spec from_integer(non_neg_integer()) :: String.t()
```

Encode a non-negative integer as a compact 0x-prefixed hex string.

## Parameters

  * `n` - Non-negative integer to encode (value)

## Returns

Compact lowercase hex string (no leading zeros) (`string`)

```elixir
# descripex:contract
%{
  params: %{n: %{description: "Non-negative integer to encode", kind: :value}},
  returns: %{
    type: :string,
    description: "Compact lowercase hex string (no leading zeros)",
    example: "0xff"
  }
}
```

# `to_integer`

```elixir
@spec to_integer(String.t()) ::
  {:ok, non_neg_integer()} | {:error, {:invalid_hex, String.t()}}
```

Decode a hex string to a non-negative integer.

## Parameters

  * `hex_string` - Hex string with or without 0x prefix (value)

## Returns

Big-endian decoded integer (`{:ok, non_neg_integer} | {:error, {:invalid_hex, input}}`)

```elixir
# descripex:contract
%{
  params: %{
    hex_string: %{
      description: "Hex string with or without 0x prefix",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, non_neg_integer} | {:error, {:invalid_hex, input}}",
    description: "Big-endian decoded integer"
  }
}
```

# `to_integer!`

```elixir
@spec to_integer!(String.t()) :: non_neg_integer()
```

Decode a hex string to a non-negative integer. Raises on invalid input.

## Parameters

  * `hex_string` - Hex string with or without 0x prefix (value)

## Returns

Big-endian decoded integer (`non_neg_integer`)

```elixir
# descripex:contract
%{
  params: %{
    hex_string: %{
      description: "Hex string with or without 0x prefix",
      kind: :value
    }
  },
  returns: %{type: :non_neg_integer, description: "Big-endian decoded integer"}
}
```

# `valid?`

```elixir
@spec valid?(term()) :: boolean()
```

Check whether a string is valid hex (with or without 0x prefix).

## Parameters

  * `input` - Value to check (value)

## Returns

true if valid hex string with at least one hex digit (`boolean`)

```elixir
# descripex:contract
%{
  params: %{input: %{description: "Value to check", kind: :value}},
  returns: %{
    type: :boolean,
    description: "true if valid hex string with at least one hex digit"
  }
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
