Polymarket.RPC (Polymarket v0.2.0)

Copy Markdown View Source

Stateless JSON-RPC 2.0 client for Polygon (and any other EVM chain that speaks standard eth_* JSON-RPC).

The building blocks a transaction-submission layer needs:

This module is intentionally stateless. The Polymarket.RPC struct carries :url, :headers, :timeout, :retry, :max_retries, and :plug (test-only). No GenServer, no connection pool of our own — Req's Finch pool handles transport. Caller threads the struct through calls.

Response contract

  • {:ok, result} — successful RPC response. result is the decoded result field (a hex string for most eth_* calls, a map or list for others). Typed helpers parse result into a typed value before returning.
  • {:error, {:rpc_error, code, message, data}} — JSON-RPC protocol error returned by the node. data is nil when the node didn't include it.
  • {:error, {:http_error, status, body}} — non-2xx HTTP response from the node.
  • {:error, {:transport_error, reason}} — Req-level transport failure.
  • {:error, {:invalid_response, body_or_message}} — well-formed HTTP 200 but the body is missing the expected result / error shape, or a typed helper got back something it couldn't parse (e.g. chain_id/1 got non-hex).

Scope

This module ships only the JSON-RPC client and nonce/gas primitives. Higher-level submit wrappers (Polymarket.CTF.redeem_positions/2 etc.) compose calldata (Polymarket.ABI) + tx serialization (Polymarket.Tx) + this RPC layer.

Options

  • :url (required) — RPC endpoint URL (e.g. "https://polygon-rpc.com").
  • :headers — extra request headers (default []).
  • :timeoutreceive_timeout in milliseconds (default 15_000).
  • :retry — Req retry policy. Default false. JSON-RPC POSTs are not idempotent at the application layer (sending a tx twice double-spends nonce); leave retry off unless the caller knows the specific RPC method is safe to retry.
  • :max_retries — Req max retries (default 0).
  • :plug — test-only; injects a Req.Test plug into the request.

Summary

Functions

Calls eth_blockNumber. Returns the latest block number as an integer.

Performs a raw JSON-RPC call. Returns the decoded result field on success; see the moduledoc for the full error shape.

Calls eth_chainId. Returns the chain id as a non-negative integer.

Calls eth_estimateGas. params is a map with optional keys

Calls eth_gasPrice. Returns wei as an integer.

Builds a Polymarket.RPC config struct.

Calls eth_getTransactionCount(address, block_tag). Default block tag is "pending" so the returned nonce is suitable for the next transaction the caller will sign.

Calls eth_sendRawTransaction(signed_bytes). Returns the 0x-prefixed transaction hash from the node on success.

Types

t()

@type t() :: %Polymarket.RPC{
  headers: list(),
  max_retries: non_neg_integer(),
  plug: term(),
  retry: term(),
  timeout: pos_integer(),
  url: String.t()
}

Functions

block_number(client)

@spec block_number(t()) :: {:ok, non_neg_integer()} | {:error, term()}

Calls eth_blockNumber. Returns the latest block number as an integer.

call(client, method, params)

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

Performs a raw JSON-RPC call. Returns the decoded result field on success; see the moduledoc for the full error shape.

chain_id(client)

@spec chain_id(t()) :: {:ok, non_neg_integer()} | {:error, term()}

Calls eth_chainId. Returns the chain id as a non-negative integer.

estimate_gas(client, params)

@spec estimate_gas(t(), map()) :: {:ok, non_neg_integer()} | {:error, term()}

Calls eth_estimateGas. params is a map with optional keys:

  • :from — sender address (0x-prefixed hex).
  • :to — destination address (0x-prefixed hex).
  • :value — non-negative integer (wei).
  • :gas — non-negative integer (gas units).
  • :gas_price — non-negative integer (wei).
  • :data — binary or 0x-prefixed hex string.

Integer amounts are encoded as 0x-prefixed hex on the wire.

gas_price(client)

@spec gas_price(t()) :: {:ok, non_neg_integer()} | {:error, term()}

Calls eth_gasPrice. Returns wei as an integer.

new(opts)

@spec new(keyword()) :: t()

Builds a Polymarket.RPC config struct.

Required: :url. Optional: :headers, :timeout, :retry, :max_retries, :plug.

nonce(client, address, block_tag \\ "pending")

@spec nonce(t(), String.t(), String.t()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Calls eth_getTransactionCount(address, block_tag). Default block tag is "pending" so the returned nonce is suitable for the next transaction the caller will sign.

send_raw_transaction(client, tx)

@spec send_raw_transaction(t(), Polymarket.Tx.t() | binary()) ::
  {:ok, String.t()} | {:error, term()}

Calls eth_sendRawTransaction(signed_bytes). Returns the 0x-prefixed transaction hash from the node on success.

Accepts:

  • a Polymarket.Tx struct that has been signed (:v populated);
  • a 0x-prefixed hex string;
  • a raw binary (will be hex-encoded with 0x prefix).