polyoxide-relay 0.12.5

Rust client library for Polymarket Relayer API
Documentation

polyoxide-relay

Rust client library for Polymarket Relayer API.

The Relay API enables submitting gasless on-chain transactions through Polymarket's relayer service on Polygon. The relayer pays gas fees on behalf of users, supporting two wallet types:

  • Safe wallets -- Gnosis Safe multisig contracts (must be deployed before first use)
  • Proxy wallets -- lightweight proxy contracts that auto-deploy on first transaction

More information about this crate can be found in the crate documentation.

Installation

[dependencies]
polyoxide-relay = "0.12"

Or use the unified client:

[dependencies]
polyoxide = { version = "0.12", features = ["full"] }

Authentication

Relay operations require a private key for EIP-712 transaction signing and one of two authentication schemes for relay submission:

Builder API Credentials (HMAC-SHA256)

use polyoxide_relay::{RelayClient, BuilderAccount, BuilderConfig};

let config = BuilderConfig::new(
    "your-api-key".into(),
    "your-secret".into(),
    Some("your-passphrase".into()),
);
let account = BuilderAccount::new("0xprivatekey...", Some(config))?;
let client = RelayClient::from_account(account)?;

Relayer API Key (static headers)

use polyoxide_relay::{RelayClient, BuilderAccount};

let account = BuilderAccount::with_relayer_api_key(
    "0xprivatekey...",
    "your-relayer-api-key".into(),
    "0xyour-address".into(),
)?;
let client = RelayClient::from_account(account)?;

Usage

Builder Pattern

use polyoxide_relay::{RelayClient, BuilderAccount, BuilderConfig, WalletType};

let config = BuilderConfig::new("key".into(), "secret".into(), None);
let account = BuilderAccount::new("0xprivatekey...", Some(config))?;

let client = RelayClient::builder()?
    .with_account(account)
    .wallet_type(WalletType::Safe)
    .chain_id(137)               // Polygon mainnet (default)
    .max_concurrent(2)
    .build()?;

Or pull settings from environment variables (RELAYER_URL, CHAIN_ID):

let client = RelayClient::default_builder()?
    .with_account(account)
    .build()?;

Gasless Redemption

use alloy::primitives::U256;

let condition_id = [0u8; 32]; // your condition ID
let index_sets = vec![U256::from(1)];

let response = client
    .submit_gasless_redemption(condition_id, index_sets)
    .await?;

println!("Transaction ID: {}", response.transaction_id);

Gasless Redemption with Gas Estimation

let response = client
    .submit_gasless_redemption_with_gas_estimation(
        condition_id,
        index_sets,
        true, // estimate gas via RPC simulation
    )
    .await?;

Execute Arbitrary Transactions

use polyoxide_relay::SafeTransaction;
use alloy::primitives::{Address, U256, Bytes};

let tx = SafeTransaction {
    to: "0x...".parse().unwrap(),
    value: U256::ZERO,
    data: Bytes::from(calldata),
    operation: 0, // CALL
};

let response = client.execute(vec![tx], None).await?;

Query Operations (no auth required)

use alloy::primitives::Address;

// Check Safe deployment status
let deployed = client.get_deployed(safe_address).await?;

// Fetch current nonce
let nonce = client.get_nonce(address).await?;

// Query transaction status
let status = client.get_transaction("tx-id").await?;
println!("State: {}", status.state);

// Measure API latency
let latency = client.ping().await?;
println!("Relay API latency: {}ms", latency.as_millis());

Wallet Address Derivation

// Derive expected Safe address via CREATE2
let safe_address = client.get_expected_safe()?;

// Derive expected Proxy wallet address via CREATE2
let proxy_address = client.get_expected_proxy_wallet()?;

Environment Variables

Variable Description
POLYMARKET_PRIVATE_KEY Hex-encoded private key for EIP-712 signing
BUILDER_API_KEY Builder API key (HMAC auth)
BUILDER_SECRET Builder API secret (HMAC auth)
BUILDER_PASS_PHRASE Builder API passphrase (HMAC auth, optional)
RELAYER_API_KEY Relayer API key (static auth)
RELAYER_API_KEY_ADDRESS Address associated with relayer API key
RELAYER_URL Custom relayer URL (default: https://relayer-v2.polymarket.com)
CHAIN_ID Target chain ID (default: 137 for Polygon mainnet)

API Coverage

  • Transaction Submission: Sign and submit gasless transactions via Safe or Proxy wallets
  • Gasless Redemptions: Redeem CTF positions without holding MATIC
  • Gas Estimation: Simulate redemptions against Polygon RPC for accurate gas limits
  • Nonce Management: Fetch current nonce from the relayer
  • Deployment Check: Verify whether a Safe wallet is deployed on-chain
  • Transaction Status: Query the state of submitted relay transactions
  • Wallet Derivation: Compute expected Safe and Proxy wallet addresses via CREATE2
  • Multi-Send Batching: Automatically batch multiple transactions via Gnosis Safe MultiSend

Supported Chains

Chain ID Notes
Polygon mainnet 137 Full support (Safe + Proxy)
Amoy testnet 80002 Safe only (Proxy not available)

License

Licensed under either of MIT or Apache-2.0 at your option.