polymarket

package module
v1.1.5 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README ΒΆ

Polymarket Go SDK

Go CI Go Reference

Official docs alignment: Implements Polymarket Order Attribution (builder auth headers for leaderboard/grants) and follows the Builder Authentication/Remote Signing guidance referenced by the Relayer Client docs; official docs: Order Attribution, Relayer Client.

An unofficial, production-ready, and feature-complete Go SDK for the Polymarket CLOB (Central Limit Order Book). Designed for high-frequency trading, market making, and data analysis.

Note: This is a community-maintained project and is not officially affiliated with Polymarket. We aim to provide a high-quality, spec-compliant implementation that can be relied upon by professionals.

Current Architecture Snapshot

The SDK is organized as a layered trading foundation:

  • Application layer: Client entry points for CLOB REST, WebSocket, and RTDS workflows.
  • Execution layer: pkg/execution for place/cancel/query/replay contracts and unified lifecycle state.
  • Protocol layer: pkg/clob, pkg/clob/ws, and pkg/rtds for exchange interaction and streams.
  • Security layer: pkg/auth for EIP-712/HMAC signing, Proxy/Safe/KMS flows, and builder attribution headers.
  • Transport layer: pkg/transport for retry policy, error normalization, and request shaping.

The SDK is organized into modular packages to ensure maintainability and extensibility:

graph TD
    Client[Client Interface] --> Transport[Transport Layer]
    Client --> CLOB[CLOB Module]
    Client --> Auth[Auth Module]
    Client --> WS[WebSocket Module]
    
    CLOB --> Orders[Order Management]
    CLOB --> Markets[Market Data]
    CLOB --> Account[Account & Rewards]
    
    Auth --> EOA[Private Key Signer]
    Auth --> KMS[AWS KMS Signer]
    
    WS --> Stream[Event Streams]
Core Capabilities
  • Type-safe integration surface: Fully typed requests/responses and predictable error handling.
  • Realtime resilience: Built-in heartbeat + reconnect behavior for long-running WebSocket sessions.
  • Institutional auth support: EOA, Proxy, Safe, and AWS KMS signer compatibility.
  • Builder-first integration: Native order attribution fields and remote signing support.
  • Low-latency trading paths: Optimized REST/WS primitives for execution and market data.
Package Responsibilities
  • pkg/clob: The core client for REST API interactions (Orders, Markets, Account).
  • pkg/clob/ws: Robust WebSocket client with auto-reconnect and typed event channels.
  • pkg/auth: Cryptographic primitives for EIP-712 signing and HMAC generation.
  • pkg/transport: HTTP transport layer handling signing injection, retries, and error parsing.
  • pkg/execution: Unified execution contract (Place/Cancel/Query/Replay) with CLOB adapter bindings.
Execution Core (Current State)
  • 6-state lifecycle model: created -> accepted -> partial -> filled/canceled/rejected.
  • Deterministic idempotency: Canonical key spec (tenant + strategy + client_order_id) for replay-safe execution.
  • Standard retry policy: Shared handling for network timeout and HTTP 5xx failure classes.
  • WS runtime policy helpers: Reconnect and heartbeat policy primitives for strategy services.
  • Attribution pass-through: Execution payload compatibility for builder, funder, and source.
  • Schema compatibility tests: Guards for message aliases (event_type/type, bids/asks + buys/sells, assets_ids + asset_ids).

πŸš€ Installation

go get github.com/marretti/polymarket-go-sdk

πŸ›  Quick Start

1. Initialize Client & Authentication
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/marretti/polymarket-go-sdk"
	"github.com/marretti/polymarket-go-sdk/pkg/auth"
	"github.com/marretti/polymarket-go-sdk/pkg/clob"
	"github.com/marretti/polymarket-go-sdk/pkg/clob/clobtypes"
	"github.com/marretti/polymarket-go-sdk/pkg/clob/ws"
	"github.com/marretti/polymarket-go-sdk/pkg/rtds"
)

func main() {
	// 1. Initialize Signer (Private Key or KMS)
	pk := os.Getenv("POLYMARKET_PK")
	signer, err := auth.NewPrivateKeySigner(pk, 137) // 137 = Polygon Mainnet
	if err != nil {
		log.Fatal(err)
	}

	// 2. Initialize Credentials
	creds := &auth.APIKey{
		Key:        os.Getenv("POLY_API_KEY"),
		Secret:     os.Getenv("POLY_API_SECRET"),
		Passphrase: os.Getenv("POLY_API_PASSPHRASE"),
	}

	// 3. Optional: Explicit WS/RTDS runtime config (instead of env vars)
	wsCfg := ws.DefaultClientConfig()
	wsCfg.ReconnectMax = 10
	wsCfg.HeartbeatInterval = 5 * time.Second

	rtdsCfg := rtds.DefaultClientConfig()
	rtdsCfg.PingInterval = 3 * time.Second

	// 4. Create Client (strict constructor returns init errors)
	client, err := polymarket.NewClientE(
		polymarket.WithCLOBWSConfig(wsCfg),
		polymarket.WithRTDSConfig(rtdsCfg),
	)
	if err != nil {
		log.Printf("client initialized with partial failures: %v", err)
	}
	client = client.WithAuth(signer, creds)

	// 5. Check System Status
status, _ := client.CLOB.Health(context.Background())
fmt.Println("System Status:", status)
}

Tip: call WithAuth(...) before starting WebSocket subscriptions so auth and stream lifecycle stay aligned.

2. Place an Order (Complex Signing Made Easy)

The SDK handles the complex EIP-712 hashing and signing automatically.

ctx := context.Background()

// Create an order builder
resp, err := client.CLOB.CreateOrder(ctx,
    clob.NewOrderBuilder(client.CLOB, signer).
        TokenID("TOKEN_ID_HERE").
        Side("BUY").
        Price(0.50).
        Size(100.0).
        OrderType(clobtypes.OrderTypeGTC).
        Build(),
)

if err != nil {
    log.Fatal("Order failed:", err)
}
fmt.Printf("Order Placed: %s\n", resp.ID)
3. Stream Market Data (WebSocket)
wsClient := client.CLOB.WS()
defer wsClient.Close()

// Subscribe to price updates
sub, err := wsClient.SubscribePrices(ctx, []string{"TOKEN_ID_HERE"})
if err != nil {
    log.Fatal(err)
}

for event := range sub {
    fmt.Printf("New Price for %s: %s\n", event.AssetID, event.Price)
}
4. Fetch All Markets (Auto-Pagination)

Forget about manually handling next_cursor.

// Automatically iterates through all pages
allMarkets, err := client.CLOB.MarketsAll(ctx, &clobtypes.MarketsRequest{
    Active: boolPtr(true),
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Fetched %d active markets\n", len(allMarkets))
5. Balance/Allowance & Rewards (Signature Type)

Balance/allowance requests now support asset_type, token_id, and signature_type (with asset kept for compatibility). Responses return an allowances map keyed by spender address.

// Set a default signature type on the CLOB client (0=EOA, 1=Proxy, 2=Safe)
clobClient := client.CLOB.WithSignatureType(auth.SignatureProxy)

bal, err := clobClient.BalanceAllowance(ctx, &clobtypes.BalanceAllowanceRequest{
    AssetType: clobtypes.AssetTypeConditional,
    TokenID:   "TOKEN_ID_HERE",
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Balance:", bal.Balance)
fmt.Println("Allowances:", bal.Allowances)

rewards, err := clobClient.UserRewardsByMarket(ctx, &clobtypes.UserRewardsByMarketRequest{
    Date:          "2026-01-01",
    OrderBy:       "date",
    NoCompetition: true,
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("User rewards: %d entries\n", len(rewards))
6. Client Defaults (Signature / Nonce / Funder / Salt)

You can set client-level defaults that apply to order signing and API key creation:

  • WithSignatureType applies to order signing and balance/rewards queries.
  • WithAuthNonce becomes the default nonce for create/derive API key calls.
  • WithFunder sets a maker address override (Proxy/Safe flows).
  • WithSaltGenerator customizes order salt generation.
client := polymarket.NewClient()

authClient := client.CLOB.
    WithAuth(signer, nil).
    WithSignatureType(auth.SignatureProxy).
    WithAuthNonce(1).
    WithSaltGenerator(func() (*big.Int, error) {
        return big.NewInt(42), nil
    })

// Optional: explicit funder address for proxy/safe signatures
authClient = authClient.WithFunder(common.HexToAddress("0xFunder..."))

builder := clob.NewOrderBuilder(authClient, signer).
    TokenID("TOKEN_ID_HERE").
    Side("BUY").
    Price(0.5).
    Size(10).
    TickSize("0.01").
    FeeRateBps(0)

signable, _ := builder.BuildSignableWithContext(ctx)
fmt.Println("Maker:", signable.Order.Maker.Hex())

See examples/client_defaults for a runnable version.

7. StreamData (Generic Pagination Helper)

Use clob.StreamData to iterate through any cursor-based endpoint without writing a custom loop:

stream := clob.StreamData(ctx, func(ctx context.Context, cursor string) ([]clobtypes.Market, string, error) {
    resp, err := client.CLOB.Markets(ctx, &clobtypes.MarketsRequest{
        Limit:  3,
        Cursor: cursor,
    })
    if err != nil {
        return nil, "", err
    }
    return resp.Data, resp.NextCursor, nil
})

for res := range stream {
    if res.Err != nil {
        log.Fatal(res.Err)
    }
    fmt.Println(res.Item.Question)
}

See examples/stream_data for a runnable version.

πŸ›‘οΈ Best Practices

1. Structured Error Handling

The SDK provides typed errors in pkg/errors to help you handle trading failures programmatically.

import (
    "errors"
    sdkerrors "github.com/marretti/polymarket-go-sdk/pkg/errors"
)

resp, err := client.CLOB.CreateOrder(ctx, order)
if err != nil {
    if errors.Is(err, sdkerrors.ErrInsufficientFunds) {
        fmt.Println("Please deposit more USDC")
    } else if errors.Is(err, sdkerrors.ErrRateLimitExceeded) {
        fmt.Println("Backing off due to rate limits...")
    }
}
2. High-Precision Orders

Always use decimal.Decimal (via PriceDec or SizeDec) when precision is critical to avoid floating-point issues common in financial applications.

builder.PriceDec(decimal.NewFromFloat(0.5001)).
        SizeDec(decimal.NewFromInt(100))
3. Remote Builder Attribution

If you are developing a client-side application (Web/Mobile) and want to receive builder rewards without exposing your Builder Secret to the end users, you can use the Remote Signer pattern.

  1. Deploy the standalone signer service found in cmd/signer-server to your secure infrastructure (support for Docker included).
  2. Configure your client to use the remote signer:
client := polymarket.NewClient(
    polymarket.WithBuilderConfig(&auth.BuilderConfig{
        Remote: &auth.BuilderRemoteConfig{
            Host: "https://your-signer-api.com/v1/sign-builder",
        },
    }),
)

If you need to switch an already-authenticated client into builder attribution mode (and restart heartbeats with the new headers), use PromoteToBuilder:

builderClient := authClient.PromoteToBuilder(myBuilderConfig)

πŸ—Ί Roadmap

We are committed to maintaining this SDK as the best-in-class solution for Polymarket.

  • Core CLOB REST API: Complete coverage of Order, Market, and Account endpoints.
  • WebSocket Client: Robust, auto-reconnecting stream client with heartbeat.
  • Authentication: Support for EOA, Proxy, Safe, and AWS KMS.
  • Pagination: Helper methods for automatic resource iteration (MarketsAll, OrdersAll).
  • Gamma API: Read-only metadata and discovery services.
  • CI/CD: Linting, Testing, and strictly enforced Coverage.
  • Institutional Performance Benchmarking: High-throughput stress testing and tick-to-trade latency analysis.
  • CTF Exchange: Direct interaction with the CTF Exchange contract for on-chain actions.
  • CLI Tool: A standalone CLI for managing orders and keys.

🀝 Contributing

Contributions are welcome! Please check out the examples/ directory for more usage patterns.

  1. Fork the repository.
  2. Create your feature branch (git checkout -b feature/amazing-feature).
  3. Commit your changes (git commit -m 'Add some amazing feature').
  4. Push to the branch (git push origin feature/amazing-feature).
  5. Open a Pull Request.

Requirements:

  • Pass go test ./...
  • Pass golangci-lint run ./...
  • Maintain >=40% test coverage (strictly enforced by CI).

πŸ“œ License

Distributed under the Apache License 2.0. See LICENSE for more information.


This project is an independent effort to provide a high-quality Go ecosystem for Polymarket. If you find it useful, please star the repo!

Star History

Star History Chart

Documentation ΒΆ

Overview ΒΆ

Package polymarket provides a unified Go SDK surface for Polymarket services.

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

type BaseURLs ΒΆ

type BaseURLs struct {
	CLOB     string
	CLOBWS   string
	Geoblock string
	Gamma    string
	Data     string
	Bridge   string
	RTDS     string
	CTF      string
}

BaseURLs defines per-service base endpoints.

type Client ΒΆ

type Client struct {
	Config Config

	CLOB   clob.Client
	CLOBWS ws.Client
	Gamma  gamma.Client
	Data   data.Client
	Bridge bridge.Client
	RTDS   rtds.Client
	CTF    ctf.Client

	InitErrors []error
	// contains filtered or unexported fields
}

Client aggregates service clients behind a shared configuration.

func NewClient ΒΆ

func NewClient(opts ...Option) *Client

NewClient creates a new root client with optional overrides.

func NewClientE ΒΆ

func NewClientE(opts ...Option) (*Client, error)

NewClientE creates a new root client and returns an aggregated error if any sub-client fails to initialize.

func (*Client) WithAuth ΒΆ

func (c *Client) WithAuth(signer auth.Signer, apiKey *auth.APIKey) *Client

WithAuth returns a new client with auth credentials applied to all sub-clients. For best WebSocket behavior, call this before opening WS subscriptions.

type Config ΒΆ

type Config struct {
	BaseURLs      BaseURLs
	HTTPClient    transport.Doer
	UserAgent     string
	Timeout       time.Duration
	UseServerTime bool
	CLOBWSConfig  ws.ClientConfig
	RTDSConfig    rtds.ClientConfig
}

Config holds shared SDK configuration.

func DefaultConfig ΒΆ

func DefaultConfig() Config

DefaultConfig returns default service endpoints.

type InitError ΒΆ

type InitError struct {
	Component string
	Err       error
}

InitError records a non-fatal client initialization failure for a sub-service.

func (*InitError) Error ΒΆ

func (e *InitError) Error() string

func (*InitError) Unwrap ΒΆ

func (e *InitError) Unwrap() error

type Option ΒΆ

type Option func(*Client)

Option mutates the root client.

func WithBridge ΒΆ

func WithBridge(client bridge.Client) Option

func WithBuilderAttribution ΒΆ

func WithBuilderAttribution(apiKey, secret, passphrase string) Option

WithBuilderAttribution configures the client to attribute volume to a specific Builder. Use this if you have your own Builder API Key from builders.polymarket.com.

func WithBuilderConfig ΒΆ

func WithBuilderConfig(cfg *auth.BuilderConfig) Option

WithBuilderConfig configures builder attribution using either local or remote signing.

func WithCLOB ΒΆ

func WithCLOB(client clob.Client) Option

func WithCLOBWS ΒΆ

func WithCLOBWS(client ws.Client) Option

func WithCLOBWSConfig ΒΆ

func WithCLOBWSConfig(cfg ws.ClientConfig) Option

WithCLOBWSConfig sets explicit WebSocket runtime behavior for the CLOB WS client.

func WithCTF ΒΆ

func WithCTF(client ctf.Client) Option

func WithConfig ΒΆ

func WithConfig(cfg Config) Option

func WithData ΒΆ

func WithData(client data.Client) Option

func WithGamma ΒΆ

func WithGamma(client gamma.Client) Option

func WithHTTPClient ΒΆ

func WithHTTPClient(doer transport.Doer) Option

func WithOfficialGoSDKSupport ΒΆ

func WithOfficialGoSDKSupport() Option

WithOfficialGoSDKSupport configures the client to attribute volume to the SDK maintainer. This is enabled by default. Use this option to explicitly restore the official attribution if it was previously overwritten.

func WithRTDS ΒΆ

func WithRTDS(client rtds.Client) Option

func WithRTDSConfig ΒΆ

func WithRTDSConfig(cfg rtds.ClientConfig) Option

WithRTDSConfig sets explicit runtime behavior for the RTDS WebSocket client.

func WithUseServerTime ΒΆ

func WithUseServerTime(use bool) Option

func WithUserAgent ΒΆ

func WithUserAgent(userAgent string) Option

Directories ΒΆ

Path Synopsis
cmd
acceptance command
polymarket-bot command
signer-server command
bot command
builder_flow command
client_defaults command
complete command
ctf_client command
data_client command
gamma_client command
gtd_order command
market_data command
market_order command
order_builder command
pagination command
rfq_flow command
rfq_quotes command
rtds_client command
stream_data command
trading command
ws_client command
ws_user_client command
pkg
auth
Package auth provides cryptographic primitives for Polymarket authentication.
Package auth provides cryptographic primitives for Polymarket authentication.
bot
clob
Package clob provides the client for interacting with the Polymarket Central Limit Order Book.
Package clob provides the client for interacting with the Polymarket Central Limit Order Book.
clob/cloberrors
Package cloberrors provides error mapping utilities for the Polymarket CLOB.
Package cloberrors provides error mapping utilities for the Polymarket CLOB.
clob/ws
Package ws provides a high-level WebSocket client for Polymarket.
Package ws provides a high-level WebSocket client for Polymarket.
ctf
errors
Package errors provides unified error definitions for the SDK.
Package errors provides unified error definitions for the SDK.
gamma
Package gamma provides the client for interacting with the Polymarket Gamma API.
Package gamma provides the client for interacting with the Polymarket Gamma API.
logger
Package logger provides a unified logging interface for the SDK.
Package logger provides a unified logging interface for the SDK.
transport
Package transport provides a robust HTTP client wrapper optimized for Polymarket's API.
Package transport provides a robust HTTP client wrapper optimized for Polymarket's API.

Jump to

Keyboard shortcuts

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