ResoMarket/Docs/Trading API

Trading API v1

HTTP and WebSocket protocol for automated trading and market making across ADI Mainnet and Polygon. USDC / pUSD · EIP-712 · HMAC.

Protocol v1Wallet-nativeADI Mainnet · Chain 36900Polygon · Chain 137USDC / pUSDEIP-712 + HMAC
Download JavaScript API demov0.1.2 · SHA-256 1920806fdb8c... · Node 20crypto: Previewsports: Previewbtc-3m: Preview

Preview means the API and offline demo are available, but the current release ZIP has not completed per-product runtime and real-funds closed-loop acceptance. Validate with a controlled wallet and the minimum amount before production funding.

Orders require an owner-wallet signature. Only a signed-in session with a managed owner signer may have one order server-signed; L2 credentials cannot sign orders or withdraw funds.

L1 wallet auth

L1 proves control of the bound funding wallet. Without a Cookie Session, callers submit fundingWallet and sign the AuthChallenge with that external wallet. Reso derives and manages a separate Trading Account owner.

Auth challenge and credential endpoints do not require a Cookie Session. Clients submit fundingWallet and sign with that bound external wallet; Reso provisions a separate managed owner. Signed-in users may also use the self-service page: Open API key settings

Code example
POST /api/trading/auth/challenges{"fundingWallet":"0x...","action":"CREATE_OR_READ_ACCOUNT","resource":{}}# Sign typedData, then consume the challenge:POST /api/trading/auth/challenges{"fundingWallet":"0x...","challengeId":"0x...","signature":"0x..."}# Response: {"account":{"ownerWallet":"0x...","status":"ACTIVE",...}}
Code example
POST /api/trading/auth/challenges{"fundingWallet":"0x...","action":"CREATE_CREDENTIAL","resource":{"label":"bot-prod","expiresAtMs":null}}# Sign typedData with owner wallet, then:POST /api/trading/auth/credentials{"fundingWallet":"0x...","challengeId":"0x...","signature":"0x...","label":"bot-prod","expiresAtMs":null}

Actions are CREATE_OR_READ_ACCOUNT, CREATE_CREDENTIAL, ROTATE_CREDENTIAL, and REVOKE_CREDENTIAL. Challenges are one-time and expire after five minutes. Polymarket CLOB Credential registration uses REGISTER_POLYMARKET_CREDENTIAL; withdrawals use WITHDRAW.

Polymarket CLOB Credential

Public Gamma/Data/CLOB reads need no authentication; CLOB trading writes need all L2 headers and still require a locally owner-signed order payload. Like Polymarket's L1/L2 split, the wallet proves ownership while API credentials authenticate CLOB requests. The Credential wallet must equal the Reso owner wallet. Current Polymarket deposit wallets use pUSD and SignatureTypeV2.POLY_1271 (type 3); use the enum instead of a numeric literal. The owner signer creates the wrapped signature, while order.signer and order.maker are both polymarketFunderWallet. Managed Trading accounts prepare missing CLOB pUSD spender allowances through the official relayer WALLET flow before one bounded retry. Self-custody accounts must prepare and refresh allowance before trading; the downloadable Demo provides `provider polymarket prepare --execute`. Hash UTF-8 credential values locally with SHA-256 for the challenge resource; send plaintext only in the final TLS request, where Reso encrypts secret and passphrase at rest.

Code example
# Derive these credentials for the platform-managed owner using Polymarket's official client.# The challenge resource contains SHA-256 hashes, never plaintext secrets.POST /api/trading/auth/challenges{"fundingWallet":"0x...","action":"REGISTER_POLYMARKET_CREDENTIAL","resource":{ "credentialWallet":"0x...","apiKeyHash":"0x...","apiSecretHash":"0x...", "apiPassphraseHash":"0x..."}}# Sign typedData with the bound funding wallet, then register the plaintext values once:PUT /api/provider-credentials/polymarket{"fundingWallet":"0x...","credentialWallet":"0x...","apiKey":"...", "apiSecret":"...","apiPassphrase":"...","challengeId":"0x...","signature":"0x..."}

L2 HMAC auth

Credential creation and rotation return credentialId, base64url secret, and passphrase once. Store them outside source control and logs.

Code example
X-RESO-ADDRESS: 0x<owner>X-RESO-API-KEY: <credentialId>X-RESO-PASSPHRASE: <passphrase>X-RESO-TIMESTAMP-MS: <unix-ms>X-RESO-NONCE: <15-128 chars>X-RESO-SIGNATURE: <lowercase hex HMAC-SHA256>

The signed message joins timestamp, nonce, uppercase method, canonical target, and SHA-256 of the exact body bytes with newlines. Query keys are unique and RFC3986 sorted. Never put secret/passphrase in URLs or WebSocket subscriptions.

Code example
import crypto from "node:crypto";const rfc3986 = (value) => encodeURIComponent(value)  .replace(/[!'()*]/g, (ch) => "%" + ch.charCodeAt(0).toString(16).toUpperCase());const canonicalTarget = (input) => {  const url = new URL(input, "https://reso.invalid");  const pairs = [...url.searchParams];  if (new Set(pairs.map(([key]) => key)).size !== pairs.length) throw new Error("duplicate query key");  pairs.sort(([a], [b]) => a.localeCompare(b));  const query = pairs.map(([key, value]) => rfc3986(key) + "=" + rfc3986(value)).join("&");  return query ? url.pathname + "?" + query : url.pathname;};export function resoL2Headers({ owner, apiKey, secret, passphrase, method, target, body = "" }) {  const timestamp = String(Date.now());  const nonce = crypto.randomUUID().replaceAll("-", "");  const bodyHash = crypto.createHash("sha256").update(body).digest("hex");  const message = ["RESO-HMAC-SHA256", timestamp, nonce, method.toUpperCase(),    canonicalTarget(target), bodyHash].join("\n");  return {    "X-RESO-ADDRESS": owner,    "X-RESO-API-KEY": apiKey,    "X-RESO-PASSPHRASE": passphrase,    "X-RESO-TIMESTAMP-MS": timestamp,    "X-RESO-NONCE": nonce,    "X-RESO-SIGNATURE": crypto.createHmac("sha256", Buffer.from(secret, "base64url"))      .update(message).digest("hex")  };}

Environment-variable names are not part of the API protocol. This is only an example client mapping: X-RESO-API-KEY receives credentialId, secret signs the HMAC, and owner wallet must match the Trading Account.

Code example
# Example client mapping; names are not part of the API protocol.TRADING_BASE_URL=https://reso.marketTRADING_OWNER_WALLET=0x...TRADING_API_KEY=cred_...TRADING_API_SECRET=<base64url secret>TRADING_API_PASSPHRASE=<passphrase>