polymarket-client

module
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: Apache-2.0

README

polymarket-client

Go Reference Go Report Card CI

Go SDK for Polymarket — the decentralized prediction market platform on Polygon.

Features

  • Complete CLOB v2 coverage — market data, order management, positions, RFQ (request-for-quote), rewards
  • WebSocket support — live order book and order update streams
  • Three-tier auth — public (no auth), L1 (EIP-712 signatures), L2 (API key + passphrase + wallet signature)
  • All Polymarket APIs — CLOB, Relayer, Data, Gamma, Bridge
  • Zero live dependencies — all tests use httptest.NewServer, run entirely offline
  • One external dependencygithub.com/ethereum/go-ethereum only

Installation

go get github.com/bububa/polymarket-client

Requires Go 1.23+ (CI uses >=1.23.0; go.mod declares 1.22).

Quick Start

Read-Only (No Auth Required)
package main

import (
    "context"
    "fmt"

    "github.com/bububa/polymarket-client/clob"
)

func main() {
    client := clob.NewClient("") // defaults to CLOB v2 host

    // Fetch market data
    marketInfo := clob.ClobMarketInfo{ConditionID: "0xabc123"}
    if err := client.GetClobMarketInfo(context.Background(), &marketInfo); err != nil {
        panic(err)
    }
    fmt.Printf("Market: %s (negRisk=%v)\n", marketInfo.ConditionID, marketInfo.NegRisk)

    // Get order book
    book, err := client.GetOrderBook(context.Background(), "token-id-here")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Best bid: %v, Best ask: %v\n", book.Bids[0].Price, book.Asks[0].Price)
}
Trading (L2 Authentication Required)

The easiest way to trade is using the OrderBuilder, which handles price conversion, tick-size validation, and market option lookups automatically:

package main

import (
    "context"
    "fmt"

    "github.com/ethereum/go-ethereum/crypto"

    "github.com/bububa/polymarket-client/clob"
    "github.com/bububa/polymarket-client/internal/polyauth"
)

func main() {
    privateKey, _ := crypto.HexToECDSA("your-private-key-hex")

    client := clob.NewClient("",
        clob.WithCredentials(clob.Credentials{
            Key:        "your-api-key",
            Secret:     "your-api-secret",
            Passphrase: "your-api-passphrase",
        }),
        clob.WithSigner(polyauth.NewSigner(privateKey)),
        clob.WithChainID(clob.PolygonChainID), // 137
    )

    b := clob.NewOrderBuilder(client)

    // Place a limit order (auto-fetches tickSize and negRisk)
    resp, err := b.CreateAndPostOrderForToken(context.Background(), clob.OrderArgsV2{
        TokenID: "your-token-id",
        Price:   "0.50",   // price per share
        Size:    "10.0",   // number of shares
        Side:    clob.SideBuy,
    }, clob.GTC, nil)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Order placed: %s (success=%v)\n", resp.OrderID, resp.Success)
}

For advanced use cases (pre-fetched market options, custom tick-size handling):

b := clob.NewOrderBuilder(client)

// Advanced: manually supply tickSize and negRisk
order, err := b.BuildOrder(clob.OrderArgsV2{
    TokenID: "your-token-id",
    Price:   "0.50",
    Size:    "10.0",
    Side:    clob.SideBuy,
}, clob.CreateOrderOptions{TickSize: "0.01", NegRisk: false})

// Then post manually
resp, err := b.CreateAndPostOrder(ctx, args, opts, clob.GTC, nil)

Note: OrderBuilder only constructs, validates, signs, and optionally submits orders. It does not check balance, allowance, or reserved open-order capacity. The caller is responsible for ensuring sufficient funds before posting.

Using Other APIs
// Data API — positions, trades, activity (no auth)
import "github.com/bububa/polymarket-client/data"

dataClient := data.New(data.Config{})
positions, _ := dataClient.GetPositions(ctx, data.PositionParams{User: "0x..."})

// Gamma API — events, markets search, tags (no auth)
import "github.com/bububa/polymarket-client/gamma"

gammaClient := gamma.New(gamma.Config{})
markets, _ := gammaClient.GetMarkets(ctx, gamma.MarketFilterParams{/* ... */})

// Relayer API — submit signed transactions (L1 auth via API key)
import "github.com/bububa/polymarket-client/relayer"

relayerClient := relayer.New(relayer.Config{
    Credentials: &relayer.Credentials{
        APIKey:  "...",
        Address: "0x...",
    },
})

Package Overview

Package Purpose Default Host Auth Required
clob CLOB v2 — orders, markets, positions, RFQ https://clob.polymarket.com Depends on endpoint
clob/ws WebSocket live order book & updates wss://ws-orderbook.clob.polymarket.com L2
clob/ws/rtds WebSocket real-time data subscriptions wss://ws-data.clob.polymarket.com None
relayer Submit signed on-chain transactions https://relayer-v2.polymarket.com L1
data Positions, trades, activity, leaderboard https://data-api.polymarket.com None
gamma Market search, events, tags, profiles https://gamma-api.polymarket.com None
bridge Bridge API https://bridge-api.polymarket.com None
shared Shared scalar types (String, Int, Float64, Time)

Authentication

Polymarket uses three authentication levels:

Level Description How It Works Endpoints
AuthNone (0) Public access No headers Market data, orderbook, prices
AuthL1 (1) Wallet-signed EIP-712 signature of timestamp + nonce CreateAPIKey, DeriveAPIKey
AuthL2 (2) Full trading API key + HMAC-secret + wallet signature Orders, trades, positions, RFQ

L2 auth requires BOTH a polyauth.Signer (from your private key) AND Credentials (API key, secret, passphrase).

Creating API Keys
client := clob.NewClient("",
    clob.WithSigner(polyauth.NewSigner(privateKey)),
    clob.WithChainID(clob.PolygonChainID),
)

// Create new API key (L1 — wallet-signed)
creds, err := client.CreateAPIKey(ctx, nonce)
// Use returned credentials for L2 requests

CLOB Package

All CLOB v2 endpoints:

Market Data (No Auth)
Method Endpoint Description
GetOk /ok Health check
GetVersion /version API version
GetServerTime /time Server timestamp
GetMarkets /markets Paginated markets
GetClobMarketInfo /clob-markets/:id Single market details
GetOrderBook /book Order book for token
GetMidpoint /midpoint Midpoint price
GetPrice /price Last price by side
GetSpread /spread Bid-ask spread
GetLastTradePrice /last-trade-price Most recent trade
GetTickSize /tick-size Minimum price increment
Orders & Trading (AuthL2)
Method Endpoint Description
PostOrder /order Submit single order
PostOrders /orders Submit batch orders (supports postOnly, deferExec)
CancelOrder /order Cancel by order ID
CancelOrders /orders Cancel multiple orders
CancelAll /cancel-all Cancel all user orders
CancelMarketOrders /cancel-market-orders Cancel by market
GetOrder /data/order/:id Get order by ID
GetOpenOrders /data/orders List open orders
GetTrades /data/trades List user trades
GetTickSize /tick-size Minimum price increment
GetTickSizeByTokenID /tick-size/:id Minimum price increment by token
GetNegRisk /neg-risk Whether a token uses neg-risk resolution

The OrderBuilder provides a high-level API that automatically fetches tickSize and negRisk from the CLOB API, so you don't need to supply them:

b := clob.NewOrderBuilder(client)

// Limit order — auto-fetches tickSize + negRisk
resp, err := b.CreateAndPostOrderForToken(ctx, clob.OrderArgsV2{
    TokenID: "token-id",
    Price:   "0.50",
    Size:    "10.0",
    Side:    clob.SideBuy,
}, clob.GTC, nil)

// Market order — Amount is USDC for BUY, shares for SELL
resp, err := b.CreateAndPostMarketOrderForToken(ctx, clob.MarketOrderArgsV2{
    TokenID: "token-id",
    Price:   "0.50",   // worst-price limit
    Amount:  "100",    // BUY: USDC to spend / SELL: shares to sell
    Side:    clob.SideBuy,
}, clob.FOK, nil)

Order types: GTC, GTD for limit orders; FOK, FAK for market orders.

deferExec (post-only) is only valid with GTC/GTD. Pairing it with FOK/FAK returns an error.

RFQ (Request for Quote) (AuthL2)
Method Endpoint Description
CreateRFQRequest /rfq/request Create RFQ
GetRFQRequests /rfq/data/requests List RFQs
CreateRFQQuote /rfq/quote Create RFQ quote
AcceptRFQRequest /rfq/request/accept Accept RFQ
ApproveRFQQuote /rfq/quote/approve Approve quote
Rewards (AuthL2 + Public)
Method Auth Description
GetEarningsForUserForDay L2 User rewards for a date
GetCurrentRewards None Active reward campaigns
GetRewardsForMarket None Rewards for a market
GetBuilderFeeRate None Builder fee configuration
WebSocket (clob/ws)
import "github.com/bububa/polymarket-client/clob/ws"

wsClient, err := ws.New(ws.Config{
    Host: "", // defaults to production
    // Optional: auth for order notifications
    Signer:      polyauth.NewSigner(privateKey),
    Credentials: &ws.Credentials{/* ... */},
    ChainID:     137,
})
defer wsClient.Close()

// Subscribe to order book
err = wsClient.SubscribeOrderBook("token-id")
// Subscribe to order updates (requires auth)
err = wsClient.SubscribeOrders()

// Read updates
for update := range wsClient.Channel {
    fmt.Printf("Update: %+v\n", update)
}

Development

# Build
go build -v ./...

# Run tests (all offline — httptest.NewServer)
go test -v ./...

# Tidy dependencies
go mod tidy
Test Files
File Coverage
clob/auth_test.go Auth header generation, HMAC signatures
clob/client_test.go CLOB v2 endpoints, flexible JSON parsing
clob/ctf_test.go CTF relayer transaction submission
clob/amount_test.go Amount calculation, tick validation, bytes32 checks
clob/order_builder_test.go OrderBuilder price invariants, market order semantics, deferExec
clob/sign_order_test.go V2 signing, domain hash, expiration handling
relayer/client_test.go Relayer documented endpoints
shared/flex_test.go Flexible JSON scalar serialization

License

MIT

Directories

Path Synopsis
Package bridge provides a client for the Polymarket Bridge API.
Package bridge provides a client for the Polymarket Bridge API.
Package clob provides a Go client for the Polymarket CLOB v2 API.
Package clob provides a Go client for the Polymarket CLOB v2 API.
ws
Package ws provides WebSocket clients for live Polymarket CLOB order book and user updates.
Package ws provides WebSocket clients for live Polymarket CLOB order book and user updates.
ws/rtds
Package rtds implements the Polymarket real-time data stream client.
Package rtds implements the Polymarket real-time data stream client.
Package data provides a read-only client for the Polymarket Data API.
Package data provides a read-only client for the Polymarket Data API.
Package gamma provides a read-only client for the Polymarket Gamma market-data API.
Package gamma provides a read-only client for the Polymarket Gamma market-data API.
internal
polyauth
Package polyauth provides EIP-712 signing and authentication header generation for the Polymarket CLOB API.
Package polyauth provides EIP-712 signing and authentication header generation for the Polymarket CLOB API.
polyhttp
Package polyhttp provides the shared HTTP client used by all Polymarket API packages (clob, data, gamma, relayer, bridge).
Package polyhttp provides the shared HTTP client used by all Polymarket API packages (clob, data, gamma, relayer, bridge).
Package relayer provides a client for the Polymarket Relayer API.
Package relayer provides a client for the Polymarket Relayer API.
Package shared contains shared JSON scalar helpers used by Polymarket API packages.
Package shared contains shared JSON scalar helpers used by Polymarket API packages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL