Package Logo
polymarket
polymarket@v0.2.0
Total Downloads
38
Published
18 hours ago
Network
polygon polygon
Publisher
User Avatar PaulieB14

Readme

Polymarket Substreams

A high-performance Substreams package for extracting and processing Polymarket prediction market data on Polygon, with built-in support for PostgreSQL, ClickHouse, and SQL sinks.

Features

  • 13 Event Types: Full coverage of CTF Exchange events (order fills, matches, cancellations, fees, token registrations, admin/operator changes, factory updates, trading pauses)
  • SQL Sink Ready: db_out module produces DatabaseChanges for direct use with substreams-sink-sql
  • PostgreSQL & ClickHouse: Schemas included for both databases with indexes and ClickHouse materialized views
  • Stateful Stores: Cumulative order counts and trading volume per market via BigInt stores
  • Block Filtering: Efficient indexing using ethcommon:index_events filters

Contracts Indexed

Contract Address Events
CTF Exchange 0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e OrderFilled, OrdersMatched, OrderCancelled, FeeCharged, TokenRegistered, TradingPaused/Unpaused, Admin/Operator changes, Factory updates
Conditional Tokens 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 ConditionPreparation, ConditionResolution, PositionSplit/Merge/Redeem
USDC (Collateral) 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 Transfer, Approval

Architecture

                    ┌─────────────────────────┐
                    │  sf.ethereum.type.v2.Block  │
                    └────────────┬────────────┘
                                 │
              ┌──────────────────┼──────────────────┐
              ▼                  ▼                  ▼
   map_ctf_exchange_events  map_ctf_events    map_usdc_events
              │
     ┌────────┼────────┐
     ▼        ▼        ▼
  store_     store_   db_out ──▶ DatabaseChanges
  total_     total_              │
  order_     volume         ┌────┴────┐
  count                     ▼         ▼
                        PostgreSQL  ClickHouse

Modules

Map Modules

Module Input Output Description
map_ctf_exchange_events Block CtfExchangeEvents Extracts all 13 CTF Exchange event types
map_ctf_events Block CtfEvents CTF condition/position events (placeholder)
map_usdc_events Block UsdcEvents USDC transfer/approval events (placeholder)
map_trading_data Block TradingData Enriched trading information
db_out map_ctf_exchange_events + store deltas DatabaseChanges SQL/ClickHouse sink output

Store Modules

Store Policy Type Description
store_total_order_count add bigint Cumulative order fill count per market
store_total_volume add bigint Cumulative trading volume per market

Quick Start

Prerequisites

  1. Install the Substreams CLI
  2. Get an API key from The Graph Market

Build

git clone https://github.com/PaulieB14/Polymarket-Substreams.git
cd Polymarket-Substreams
substreams build

Stream Events

# Stream CTF Exchange events
substreams gui substreams.yaml map_ctf_exchange_events -e polygon.substreams.pinax.network:443

# Stream database changes (for sink testing)
substreams gui substreams.yaml db_out -e polygon.substreams.pinax.network:443

SQL Sink Setup

PostgreSQL

# 1. Setup the database schema
substreams-sink-sql setup "psql://user:password@localhost:5432/polymarket" ./substreams.yaml

# 2. Run the sink
substreams-sink-sql run "psql://user:password@localhost:5432/polymarket" ./substreams.yaml

ClickHouse

# 1. Setup using ClickHouse schema
substreams-sink-sql setup "clickhouse://user:password@localhost:9000/polymarket" ./substreams.yaml --schema ./schema.clickhouse.sql

# 2. Run the sink
substreams-sink-sql run "clickhouse://user:password@localhost:9000/polymarket" ./substreams.yaml --engine clickhouse

Note: Pass the DSN on the command line, not in the manifest. The schema.sql (PostgreSQL) and schema.clickhouse.sql (ClickHouse) files define the table structures.

Database Tables

Event Tables

Table Source Event Key Fields
order_fills OrderFilled maker, taker, maker_asset_id, amounts, fee
orders_matched OrdersMatched taker_order_hash, asset IDs, amounts
order_cancellations OrderCancelled order_hash
fee_charges FeeCharged receiver, token_id, amount
token_registrations TokenRegistered token0, token1, condition_id
trading_status_changes TradingPaused/Unpaused pauser, status
admin_changes NewAdmin/RemovedAdmin admin, target_address, action
operator_changes NewOperator/RemovedOperator admin, target_address, action
factory_updates ProxyFactory/SafeFactory Updated factory_type, old/new factory

Aggregate Tables (from Store Deltas)

Table Source Store Description
order_count_updates store_total_order_count Running fill count per market
volume_updates store_total_volume Running volume per market

ClickHouse Materialized Views

  • mv_hourly_volume: Hourly trading volume, trade count, and fees per market
  • mv_trader_stats: Per-trader stats (trade count, total volume, fees paid)

Example Queries

PostgreSQL: Top Markets by Order Volume

SELECT maker_asset_id, COUNT(*) AS fills, SUM(CAST(maker_amount_filled AS NUMERIC)) AS volume
FROM order_fills
GROUP BY maker_asset_id
ORDER BY fills DESC
LIMIT 20;

PostgreSQL: Most Active Traders

SELECT taker, COUNT(*) AS trades, SUM(CAST(fee AS NUMERIC)) AS total_fees
FROM order_fills
GROUP BY taker
ORDER BY trades DESC
LIMIT 20;

ClickHouse: Hourly Volume (from materialized view)

SELECT hour, trade_count, total_maker_volume
FROM mv_hourly_volume
WHERE maker_asset_id = '<MARKET_ID>'
ORDER BY hour DESC
LIMIT 24;

Development

Building from Source

# Install Rust and wasm target
rustup target add wasm32-unknown-unknown

# Build
cargo build --target wasm32-unknown-unknown --release

# Or use the Substreams CLI
substreams build

Project Structure

├── abi/                          # Contract ABI JSON
├── proto/
│   └── contract.proto            # Protobuf definitions
├── src/
│   ├── abi/                      # Generated ABI bindings
│   ├── pb/                       # Generated protobuf code
│   └── lib.rs                    # Module handlers (maps, stores, db_out)
├── schema.sql                    # PostgreSQL DDL
├── schema.clickhouse.sql         # ClickHouse DDL with materialized views
├── substreams.yaml               # Module manifest with sink config
├── Cargo.toml                    # Rust dependencies
└── build.rs                      # ABI code generation

Adding New Event Types

  1. Add the contract ABI to abi/
  2. Define protobuf messages in proto/contract.proto
  3. Add a map module in src/lib.rs and substreams.yaml
  4. Add corresponding tables in schema.sql and schema.clickhouse.sql
  5. Wire the new events into the db_out function

Publishing

# Package the substreams
substreams pack

# Publish to the registry
substreams publish

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

License

MIT - see LICENSE.

Links

Documentation

Modules

Maps icon
Maps

map
map_ctf_exchange_events

47134bf534e3cf9cfaa1338594d582928f6e004f
map map_ctf_exchange_events (
blocksf.ethereum.type.v2.Block
)  -> contract.v1.CtfExchangeEvents
substreams gui polymarket@v0.2.0 map_ctf_exchange_events

map
map_ctf_events

9f042b34d02467281a8ba4f8f3ab0017af7b6afa
map map_ctf_events (
)  -> contract.v1.CtfEvents
substreams gui polymarket@v0.2.0 map_ctf_events

map
map_usdc_events

9c651d42262bda5a5eba8df7e4ec8e7572d4557c
map map_usdc_events (
)  -> contract.v1.UsdcEvents
substreams gui polymarket@v0.2.0 map_usdc_events

map
map_trading_data

e1f0c255f243216ead2d41042ff623df7ae1682a
map map_trading_data (
)  -> contract.v1.TradingData
substreams gui polymarket@v0.2.0 map_trading_data

map
db_out

4b0cafd36b4ae60777dda8207829f8c5bf1a41c0
substreams gui polymarket@v0.2.0 db_out

map
ethcommon:all_events

963652a247fd23d0823dde62d21ae54c783b6073
map ethcommon:all_events (
)  -> sf.substreams.ethereum.v1.Events

all_events gives you all the events in a block (from successful transactions), with basic block hash/number/timestamp and transaction hash

substreams gui polymarket@v0.2.0 ethcommon:all_events
Stores icon
Stores

store
store_total_order_count

dbea084dc3beb7f58e90d40ee76ccc9a8f08ffb4
store <add,bigint> store_total_order_count (
)
substreams gui polymarket@v0.2.0 store_total_order_count

store
store_total_volume

a031a82637b34066d4aa98cd8e4dc3a9338d044c
store <add,bigint> store_total_volume (
)
substreams gui polymarket@v0.2.0 store_total_volume
Block Indexes icon
Block Indexes

blockIndex
ethcommon:index_events

87255243f80f5d4755cd826ec57bf70696a4d7b6

index_events sets the following keys on the block:

  • Event signatures evt_sig:0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef (signature in hex, prefixed by 0x)
  • Event address evt_addr:0x0123456789abcdef0123456789abcdef01234567 (address in hex, prefixed by 0x)
substreams gui polymarket@v0.2.0 ethcommon:index_events
Protobuf

Protobuf Docs Explorer

sf.ethereum.type.v2
contract.v1
sf.ethereum.substreams.v1