# `Cartouche.RPC.DSL`
[🔗](https://github.com/zenhive/cartouche/blob/main/lib/cartouche/rpc/dsl.ex#L1)

Compile-time DSL for the uniform thin JSON-RPC wrappers in `Cartouche.RPC`.

`defrpc/3` generates, from one declaration, the four artifacts these
wrappers otherwise hand-maintain in lockstep:

  1. the public function,
  2. its `@spec` (return type derived from `:decode`),
  3. its `@doc` (carrying the doctest), and
  4. the Descripex `api/3` metadata block read by `Cartouche.describe/2`.

Two uniform shapes are covered, selected by whether `:address_desc` is given:

  * **address-at-block** — `name(<<_::160>> = address, opts) ->
    send_rpc(method, [encode(address), block_number], decode: ...)`
    (e.g. `get_balance`, `get_code`).
  * **no-arg** — `name(opts) -> send_rpc(method, [], decode: ...)`
    (e.g. `eth_chain_id`, `gas_price`).

Only the genuinely uniform shapes are covered. Wrappers with extra guards,
struct dispatch, multi-clause normalization, or per-method prose deviations
(e.g. `get_nonce`, whose param name, encoder, and opts description all differ)
stay hand-written — folding them in would grow more knobs than the
duplication it removes.

Prototype for ROADMAP Task 110 (defrpc), proving the `api()` introspection
stays byte-identical across the conversion.

# `defrpc`
*macro* 

```elixir
@spec defrpc(atom(), String.t(), Keyword.t()) :: Macro.t()
```

Define a uniform thin JSON-RPC wrapper.

`name` is the generated function (and `api/3`) name; `method` is the JSON-RPC
method string. Required `opts`:

  * `:decode` — `send_rpc/3` decode mode; also fixes the `@spec` return type
    (`:hex` → `binary()`, `:hex_unsigned` → `non_neg_integer()`).
  * `:summary` — one-line Descripex description.
  * `:returns_desc` — Descripex description of the `:ok` return.
  * `:doc` — the `@doc` body (with doctest).

Shape selection / optional:

  * `:address_desc` — present ⇒ the address-at-block shape; its value is the
    Descripex description of the leading `address` param. Absent ⇒ no-arg shape.
  * `:encode` — address encoder for the address shape, `:to_hex` (default) or
    `:big_hex`. Ignored by the no-arg shape.

---

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