# `Onchain.ABI`
[🔗](https://github.com/ZenHive/onchain/blob/v0.5.0/lib/onchain/abi.ex#L1)

ABI encoding/decoding for Ethereum contract calls.

Wraps the `abi` library (a dep of signet) with `0x`-prefixed hex string
handling and consistent error tuples. Consumers work with hex strings from
RPC; this module bridges the gap.

## Type Signatures

`decode_response/2` expects **tuple type syntax** for return values, e.g.
`"(uint256)"` or `"(uint256,bool)"`. This is the standard pattern for
decoding `eth_call` responses — NOT function signatures with names.

## Error Format

- Encode errors: `{:error, {:encode_error, reason}}`
- Decode errors: `{:error, {:decode_error, reason}}`

Where `reason` is either:
- A string from the upstream exception message
- A tuple like `{:invalid_hex, hex_data}` preserving the original hex error

## Functions

| Function | Purpose |
|----------|---------|
| `encode_call/2` | Function signature + params → hex calldata |
| `encode_call!/2` | Same, raises on error |
| `decode_response/2` | Type signature + hex data → decoded values |
| `decode_response!/2` | Same, raises on error |

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `decode_response!` | 2 | Decode hex-encoded ABI response data to Elixir values. Raises on error. | `type_signature: value`, `hex_data: value` |
| `decode_response` | 2 | Decode hex-encoded ABI response data to Elixir values. | `type_signature: value`, `hex_data: value` |
| `encode_call!` | 2 | Encode a function call to 0x-prefixed hex calldata. Raises on error. | `signature: value`, `params: value` |
| `encode_call` | 2 | Encode a function call to 0x-prefixed hex calldata. | `signature: value`, `params: value` |

# `decode_response`

```elixir
@spec decode_response(String.t(), String.t()) ::
  {:ok, list()} | {:error, {:decode_error, term()}}
```

Decode hex-encoded ABI response data to Elixir values.

## Parameters

  * `type_signature` - Tuple type signature, e.g. "(uint256)" or "(uint256,bool)" (value)
  * `hex_data` - 0x-prefixed hex string of ABI-encoded data (value)

## Returns

List of decoded values (`{:ok, list} | {:error, {:decode_error, reason}}`)

```elixir
# descripex:contract
%{
  params: %{
    type_signature: %{
      description: "Tuple type signature, e.g. \"(uint256)\" or \"(uint256,bool)\"",
      kind: :value
    },
    hex_data: %{
      description: "0x-prefixed hex string of ABI-encoded data",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, list} | {:error, {:decode_error, reason}}",
    description: "List of decoded values"
  }
}
```

# `decode_response!`

```elixir
@spec decode_response!(String.t(), String.t()) :: list()
```

Decode hex-encoded ABI response data to Elixir values. Raises on error.

## Parameters

  * `type_signature` - Tuple type signature, e.g. "(uint256)" or "(uint256,bool)" (value)
  * `hex_data` - 0x-prefixed hex string of ABI-encoded data (value)

## Returns

List of decoded values (`list`)

```elixir
# descripex:contract
%{
  params: %{
    type_signature: %{
      description: "Tuple type signature, e.g. \"(uint256)\" or \"(uint256,bool)\"",
      kind: :value
    },
    hex_data: %{
      description: "0x-prefixed hex string of ABI-encoded data",
      kind: :value
    }
  },
  returns: %{type: :list, description: "List of decoded values"}
}
```

# `encode_call`

```elixir
@spec encode_call(String.t(), list()) ::
  {:ok, String.t()} | {:error, {:encode_error, term()}}
```

Encode a function call to 0x-prefixed hex calldata.

## Parameters

  * `signature` - Function signature, e.g. "balanceOf(address)" (value)
  * `params` - List of parameter values matching the signature (value)

## Returns

0x-prefixed hex-encoded calldata (`{:ok, hex_string} | {:error, {:encode_error, reason}}`)

```elixir
# descripex:contract
%{
  params: %{
    signature: %{
      description: "Function signature, e.g. \"balanceOf(address)\"",
      kind: :value
    },
    params: %{
      description: "List of parameter values matching the signature",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, hex_string} | {:error, {:encode_error, reason}}",
    description: "0x-prefixed hex-encoded calldata",
    example: "0x70a08231..."
  }
}
```

# `encode_call!`

```elixir
@spec encode_call!(String.t(), list()) :: String.t()
```

Encode a function call to 0x-prefixed hex calldata. Raises on error.

## Parameters

  * `signature` - Function signature, e.g. "balanceOf(address)" (value)
  * `params` - List of parameter values matching the signature (value)

## Returns

0x-prefixed hex-encoded calldata (`string`)

```elixir
# descripex:contract
%{
  params: %{
    signature: %{
      description: "Function signature, e.g. \"balanceOf(address)\"",
      kind: :value
    },
    params: %{
      description: "List of parameter values matching the signature",
      kind: :value
    }
  },
  returns: %{type: :string, description: "0x-prefixed hex-encoded calldata"}
}
```

---

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