clob-client-rust 0.2.6

Polymarket CLOB client ported to Rust: build, sign and submit orders; helper utilities.
Documentation
clob-client-rust
===============

Rust client for Polymarket CLOB (ported from the official TypeScript `clob-client`).

This crate focuses on:
- Order building + EIP-712 signing parity
- Typed endpoint calls
- TS v5.1.0 parity additions: Readonly API Key + RFQ client + HTTP PUT + optional geo token

Important behavior note:
- Tick size is **not** auto-resolved from the backend. If you need a market-specific tick, fetch it externally and pass it in. Otherwise the SDK uses the fallback tick `"0.01"`.

## Install

```toml
[dependencies]
clob-client-rust = "0.1"
```

## Auth models (TS parity)

### 1) L2 auth (signer + API key creds)

Used for trading flows (create/post/cancel) and authenticated reads.

```rust
use clob_client_rust::client::ClobClient;
use clob_client_rust::signer_adapter::EthersSigner;
use clob_client_rust::types::ApiKeyCreds;
use std::sync::Arc;

let signer = Arc::new(EthersSigner::new_from_private_key(&pk)?);
let creds = ApiKeyCreds { key, secret, passphrase };
let mut client = ClobClient::new(&host, chain_id, Some(signer), Some(creds), true);
```

### 2) Readonly API key headers (TS parity)

Important TS parity note:
- TypeScript `client.getOpenOrders()` still uses **L2 auth** (HMAC headers).
- The readonly key is used only in the standalone TS example `getOpenOrdersWithReadonlyKey.ts`, by manually calling `GET /data/orders` with extra headers.

Rust parity example (same as TS example, via `http_helpers`):

```rust
use clob_client_rust::endpoints::GET_OPEN_ORDERS;
use clob_client_rust::http_helpers::{RequestOptions, get};
use clob_client_rust::types::SignedOrder;
use std::collections::HashMap;

let endpoint = format!("{}{}", host.trim_end_matches('/'), GET_OPEN_ORDERS);

let mut headers = HashMap::new();
headers.insert("POLY_READONLY_API_KEY".to_string(), readonly_key);
headers.insert("POLY_ADDRESS".to_string(), address.clone());

let mut params = HashMap::new();
params.insert("maker_address".to_string(), address);

let opts = RequestOptions { headers: Some(headers), data: None, params: Some(params) };
let val = get(&endpoint, Some(opts)).await?;

let arr = if val.is_array() { val } else { val["data"].clone() };
let orders: Vec<SignedOrder> = serde_json::from_value(arr)?;
```

## Geo block token

TypeScript injects `geo_block_token` into every request automatically. In Rust it is **optional**:

```rust
let client = client.with_geo_block_token(token);
```

When set, the SDK injects `geo_block_token` into query parameters for supported calls.

## RFQ client (TS v5.1.0)

RFQ is exposed as a sub-client similar to TS: `client.rfq()`.

```rust
use clob_client_rust::types::GetRfqQuotesParams;

let quotes = client
	.rfq()
	.get_rfq_quotes(Some(GetRfqQuotesParams { limit: Some(10), ..Default::default() }))
	.await?;
```

Accept/approve will:
1) fetch the quote
2) build a signed order via `client.create_order(...)`
3) post the action payload to the RFQ endpoint

Tick size behavior stays explicit (fallback is `"0.01"`).

## Readonly API key management

The SDK exposes the endpoints added in TS v5.1.0:
- `create_readonly_api_key`
- `get_readonly_api_keys`
- `delete_readonly_api_key`
- `validate_readonly_api_key`

TS parity:
- `create/get/delete` require L2 auth.
- `validate_readonly_api_key` is a public GET (query params), no L2 needed.

See the examples in `examples/`.

## HTTP helpers (GET/POST/PUT/DELETE)

`http_helpers` provides typed request wrappers including `put_typed/put`.

## Examples

Build/sign only (no network):

```bash
cargo run --example sign_order
```

Readonly open orders (TS parity headers):

```bash
cargo run --example get_open_orders_with_readonly_key
```

RFQ quotes:

```bash
cargo run --example rfq_get_quotes
```