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

Generic contract call: ABI encode → eth_call → ABI decode in one function.

Eliminates the 3-step `with` chain every consumer writes for contract reads.
Takes a contract address, function signature, params, and return type — returns
decoded values.

## Error Format

Errors pass through from the underlying module that failed:

| Source | Error Shape |
|--------|-------------|
| `Onchain.Address.validate/1` | `{:error, {:invalid_address, input}}` |
| `Onchain.ABI.encode_call/2` | `{:error, {:encode_error, reason}}` |
| `Onchain.RPC.eth_call/3` | `{:error, {:rpc_error, map}}` |
| `Onchain.ABI.decode_response/2` | `{:error, {:decode_error, reason}}` |

## Functions

| Function | Purpose |
|----------|---------|
| `call/5` | Generic contract read → decoded values list |
| `call!/5` | Same, raises on error |

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `call!` | 5 | Execute a read-only contract call. Raises on error. | `address: value`, `signature: value`, `params: value`, `return_type: value`, `opts: value` |
| `call` | 5 | Execute a read-only contract call: encode → eth_call → decode. | `address: value`, `signature: value`, `params: value`, `return_type: value`, `opts: value` |

# `call`

```elixir
@spec call(String.t() | binary(), String.t(), list(), String.t(), keyword()) ::
  {:ok, list()} | {:error, term()}
```

Execute a read-only contract call: encode → eth_call → decode.

## Parameters

  * `address` - Contract address as 0x hex string or 20-byte binary (value)
  * `signature` - Function signature, e.g. "balanceOf(address)" (value)
  * `params` - List of parameter values matching the signature (value)
  * `return_type` - Tuple type signature for decoding, e.g. "(uint256)" or "(uint256,bool)" (value)
  * `opts` - Options: :rpc_url, :timeout, :block (default: `[]`, value)

## Returns

List of decoded return values from the contract call (`{:ok, [decoded_values]} | {:error, term()}`)

```elixir
# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    address: %{
      description: "Contract address as 0x hex string or 20-byte binary",
      kind: :value
    },
    signature: %{
      description: "Function signature, e.g. \"balanceOf(address)\"",
      kind: :value
    },
    params: %{
      description: "List of parameter values matching the signature",
      kind: :value
    },
    return_type: %{
      description: "Tuple type signature for decoding, e.g. \"(uint256)\" or \"(uint256,bool)\"",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, [decoded_values]} | {:error, term()}",
    description: "List of decoded return values from the contract call",
    example: "{:ok, [1000000]}"
  }
}
```

# `call!`

```elixir
@spec call!(String.t() | binary(), String.t(), list(), String.t(), keyword()) ::
  list()
```

Execute a read-only contract call. Raises on error.

## Parameters

  * `address` - Contract address as 0x hex string or 20-byte binary (value)
  * `signature` - Function signature, e.g. "balanceOf(address)" (value)
  * `params` - List of parameter values matching the signature (value)
  * `return_type` - Tuple type signature for decoding, e.g. "(uint256)" (value)
  * `opts` - Options: :rpc_url, :timeout, :block (default: `[]`, value)

## Returns

List of decoded return values from the contract call (`[decoded_values]`)

```elixir
# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    address: %{
      description: "Contract address as 0x hex string or 20-byte binary",
      kind: :value
    },
    signature: %{
      description: "Function signature, e.g. \"balanceOf(address)\"",
      kind: :value
    },
    params: %{
      description: "List of parameter values matching the signature",
      kind: :value
    },
    return_type: %{
      description: "Tuple type signature for decoding, e.g. \"(uint256)\"",
      kind: :value
    }
  },
  returns: %{
    type: "[decoded_values]",
    description: "List of decoded return values from the contract call"
  }
}
```

---

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