polymarket开发文档-Websocket+Gamma Structure+Subgraph+Resolution

WSS Overview

一、核心定位:Websocket 是做什么的?

Polymarket 提供的 Websocket(WSS)通道,核心作用是:

让客户端(你的程序)实时接收推送更新 ,而非主动轮询接口,以此实现「几乎实时」的订单、交易、市场数据同步。

对比:普通 HTTP 接口是「你问我答」(比如每10秒查一次订单),Websocket 是「服务器主动通知」(订单有变化立刻告诉你),效率和实时性更高。

二、核心概念:两个核心通道(Channel)

Polymarket WSS 只开放了两种类型的通道,对应不同的推送内容:

通道类型(type) 作用 关注的标识
USER(用户通道) 接收当前用户的订单、交易相关实时事件(比如你的订单被成交、取消、挂单) markets(市场ID/condition IDs)指定要监听的市场
MARKET(市场通道) 接收全网市场的实时数据(比如某个标的的价格变动、成交量变化) assets_ids(资产ID/token IDs)指定要监听的资产

简单说:

  • 想监控「自己的订单状态」→ 订阅 USER 通道 + 传入关注的 markets
  • 想监控「某个标的的市场行情」→ 订阅 MARKET 通道 + 传入关注的 assets_ids

三、第一步:初始订阅(连接时的首次配置)

打开 Websocket 连接后,必须先发送「订阅消息」才能接收推送,消息需包含以下核心字段:

字段 类型 必选 作用
auth Auth 类型 身份认证信息(下文会单独讲 WSS 认证规则),没有认证会被拒绝连接
markets 字符串数组 仅 USER 通道 ✅ 要监听的市场ID列表(比如 ["12345", "67890"]
assets_ids 字符串数组 仅 MARKET 通道 ✅ 要监听的资产ID/代币ID列表(比如 ["token123", "token456"]
type 字符串 订阅的通道类型,只能是 USERMARKET
custom_feature_enabled 布尔值 开启/关闭自定义功能(一般默认 false 即可)

核心逻辑:连接建立后,先传「认证+要监听的内容+通道类型」,服务器验证通过后,才会开始推送对应事件。

四、第二步:动态订阅/取消订阅(连接后调整)

连接建立后,不需要断开重连,就能动态新增/取消监听的资产/市场,只需发送包含以下字段的消息:

字段 类型 必选 作用
assets_ids 字符串数组 仅 MARKET 通道 ✅ 要新增/取消的资产ID列表
markets 字符串数组 仅 USER 通道 ✅ 要新增/取消的市场ID列表
operation 字符串 操作类型:subscribe(订阅)或 unsubscribe(取消订阅)
custom_feature_enabled 布尔值 同上,自定义功能开关

举例

  • 已订阅 MARKET 通道监听资产 A,想新增监听资产 B → 发送 operation: "subscribe" + assets_ids: ["B的ID"]
  • 不想监听 USER 通道的市场 C → 发送 operation: "unsubscribe" + markets: ["C的ID"]

WSS Quickstart

🔑 第一部分:获取 API Keys

你需要一个以太坊私钥(Private Key)来初始化客户端。如果你使用的是邮箱登录(通过 Magic.link),可以去 https://reveal.magic.link/polymarket 导出私钥;否则从你的 Web3 钱包(如 MetaMask)导出。

✅ 安装依赖

bash 复制代码
npm install @polymarket/clob-client
npm install ethers

📜 JavaScript 代码(用于生成 API Key)

js 复制代码
import { ClobClient } from "@polymarket/clob-client";
import { Wallet } from "@ethersproject/wallet";

const host = 'https://clob.polymarket.com';
const signer = new Wallet("YourPrivateKey"); // 替换为你的私钥

// 初始化 CLOB 客户端(链 ID 137 是 Polygon)
const clobClient = new ClobClient(host, 137, signer);

(async () => {
  const apiKey = await clobClient.deriveApiKey();
  console.log("Generated API Key:", apiKey);
})();

运行这段代码后,你会得到一个包含 keysecretpassphrase 的对象,用于后续的 WebSocket 认证。

🌐 第二部分:连接 WebSocket(Market / User 频道)

📜 Python 代码(WebSocket 订阅示例)

python 复制代码
from websocket import WebSocketApp
import json
import time
import threading

MARKET_CHANNEL = "market"
USER_CHANNEL = "user"

class WebSocketOrderBook:
    def __init__(self, channel_type, url, data, auth, message_callback, verbose):
        self.channel_type = channel_type
        self.url = url
        self.data = data
        self.auth = auth
        self.message_callback = message_callback
        self.verbose = verbose
        furl = url + "/ws/" + channel_type
        self.ws = WebSocketApp(
            furl,
            on_message=self.on_message,
            on_error=self.on_error,
            on_close=self.on_close,
            on_open=self.on_open,
        )
        self.orderbooks = {}

    def on_message(self, ws, message):
        print("Received message:", message)

    def on_error(self, ws, error):
        print("Error:", error)
        exit(1)

    def on_close(self, ws, close_status_code, close_msg):
        print("Connection closed")
        exit(0)

    def on_open(self, ws):
        if self.channel_type == MARKET_CHANNEL:
            ws.send(json.dumps({"assets_ids": self.data, "type": MARKET_CHANNEL}))
        elif self.channel_type == USER_CHANNEL and self.auth:
            ws.send(
                json.dumps({
                    "markets": self.data,
                    "type": USER_CHANNEL,
                    "auth": self.auth
                })
            )
        else:
            exit(1)

        # 启动心跳线程(每10秒发一次 PING)
        thr = threading.Thread(target=self.ping, args=(ws,))
        thr.start()

    def subscribe_to_tokens_ids(self, assets_ids):
        if self.channel_type == MARKET_CHANNEL:
            self.ws.send(json.dumps({"assets_ids": assets_ids, "operation": "subscribe"}))

    def unsubscribe_to_tokens_ids(self, assets_ids):
        if self.channel_type == MARKET_CHANNEL:
            self.ws.send(json.dumps({"assets_ids": assets_ids, "operation": "unsubscribe"}))

    def ping(self, ws):
        while True:
            ws.send("PING")
            time.sleep(10)

    def run(self):
        self.ws.run_forever()


if __name__ == "__main__":
    url = "wss://ws-subscriptions-clob.polymarket.com"

    # 🔑 从第一部分 JS 脚本中获取这三个值
    api_key = ""          # e.g., "abc123..."
    api_secret = ""       # e.g., "def456..."
    api_passphrase = ""   # e.g., "ghi789..."

    asset_ids = [
        "109681959945973300464568698402968596289258214226684818748321941747028805721376",
    ]
    condition_ids = []  # 用户频道可能需要 condition_id,但通常可为空

    auth = {
        "apiKey": api_key,
        "secret": api_secret,
        "passphrase": api_passphrase
    }

    # 创建 Market 频道连接(订阅特定资产)
    market_connection = WebSocketOrderBook(
        MARKET_CHANNEL, url, asset_ids, auth, None, True
    )

    # 可选:动态订阅/取消订阅其他 asset_id
    market_connection.subscribe_to_tokens_ids(["123"])

    # 启动 Market 连接(阻塞主线程)
    market_connection.run()

    # 如果需要监听自己的订单,取消注释以下两行:
    # user_connection = WebSocketOrderBook(USER_CHANNEL, url, condition_ids, auth, None, True)
    # user_connection.run()

WSS Authentication

✅ 核心要点:

  • 只有连接到 user 频道时才需要认证

    连接 market 频道是公开的,不需要提供 API 凭据。

  • 如果你要订阅 用户私有数据 (比如自己的订单、持仓、成交等),就必须在连接 user 频道时提供有效的认证信息。

🔐 认证所需的三个字段(全部必填,尽管表格写"Optional: yes",但实际使用中是必需的):

字段名 是否可选 说明
apikey 否(实际必需) 你在 Polymarket CLOB 上为 Polygon 账户生成的 API Key
secret 否(实际必需) 对应的 API Secret(用于签名)
passphrase 否(实际必需) API Passphrase(通常是一个 UUID,用于增强安全性)

⚠️ 注意:虽然表格中标注为 "Optional: yes",但这很可能是文档笔误。在连接 user 频道时,这三个字段是必须提供的,否则服务器会拒绝连接或返回认证错误。

User Channel

由于 user 频道是经过认证的私有频道 ,它只会推送与当前 API Key 所属用户相关的活动(如自己下的单、自己的成交等)。

✅ 核心内容总结

1. 频道类型

  • 频道名称user
  • 认证要求 :必须提供有效的 apikeysecretpassphrase
  • 数据范围 :仅限当前认证用户的订单和交易活动

📥 一、Trade 消息(成交事件)

🔔 触发时机

  • 用户的 市价单被撮合(MATCHED)
  • 用户的 限价单作为 Maker 被撮合(MATCHED)
  • 成交状态后续更新:MINED(上链)、CONFIRMED(确认)、RETRYING(重试)、FAILED(失败)

换句话说:只要与你相关的交易发生或状态变化,就会收到此消息。

🧱 消息结构关键字段

字段 说明
type: "TRADE" 消息类型标识
event_type: "trade" 事件类型
id 成交唯一 ID(UUID)
status 当前成交状态(如 "MATCHED"
side "BUY""SELL"
price / size 成交价格和数量
asset_id 成交的 token ID(对应某个市场结果,如 "YES")
market 市场标识(即 condition ID)
maker_orders 包含所有参与此成交的 挂单方(Maker)订单详情
taker_order_id 吃单方(Taker)的订单 ID
owner / trade_owner 通常是你自己的 API Key(UUID 格式)

💡 注意:即使你是 Taker(吃单方),也会收到这条消息,因为成交涉及你的订单。

📥 二、Order 消息(订单事件)

🔔 触发时机

  • 下单成功type: "PLACEMENT"
  • 部分成交或更新type: "UPDATE"
  • 取消订单type: "CANCELLATION"

🧱 消息结构关键字段

字段 说明
type "PLACEMENT" / "UPDATE" / "CANCELLATION"
event_type: "order" 事件类型
id 订单 ID(通常是交易哈希)
asset_id 订单对应的 token ID
market 所属市场的 condition ID
side / price / original_size 订单方向、价格、原始数量
size_matched 已成交数量(UPDATE 时会增加)
associate_trades 关联的成交 ID 列表(可能为 null
owner / order_owner 你的 API Key(表示这是你的订单)

🔄 举例:

  • 初始下单:type=PLACEMENT, size_matched="0"
  • 部分成交后:收到 type=UPDATE, size_matched="5"
  • 全部成交或取消:可能再收到一次 UPDATECANCELLATION

Market Channel

该频道无需认证,任何人都可以订阅,适用于行情监控、做市策略、数据分析等场景。

✅ 核心要点总结

  • 频道名称market
  • 用途:接收实时市场深度(订单簿)、价格变动、成交价、新市场上线、市场结算等公开信息
  • 订阅方式 :通过 WebSocket 发送包含 assets_ids 的订阅消息
  • 所有消息都与特定 asset_id(即某个结果 token,如 "YES")或 market(condition ID)关联

📡 消息类型详解

1. book 消息 --- 完整订单簿快照

  • 触发时机
    • 首次订阅某个 asset_id
    • 有交易发生导致订单簿变化
  • 内容:当前买卖盘的聚合 Level 2 数据(价格 + 总量)
  • 字段说明
    • buys → 实际应为 bids(文档结构写的是 buys,但示例用 bids,可能是笔误)
    • sells → 实际应为 asks
    • hash:订单簿内容的摘要哈希,可用于检测是否重复或完整
    • timestamp:毫秒级 Unix 时间戳

2. price_change 消息 --- 增量订单簿更新(高效更新)

  • 触发时机
    • 新订单挂单
    • 订单被取消
  • 内容 :仅发送发生变化的价格档位(非全量)
  • 每个 PriceChange 包含
    • side(BUY/SELL)
    • price:价格档
    • size:该档位新的总挂单量(若为 0 表示该档消失)
    • best_bid / best_ask:当前最优买卖价(方便快速获取)
  • ⚠️ 重要提示:2025 年 9 月 15 日将有 Breaking Change(需关注迁移指南)

💡 适合高频更新场景,减少带宽消耗。

3. tick_size_change 消息 --- 最小价格变动单位变更

  • 触发时机
    • 当市场价格接近极端值( 0.96)时,系统自动缩小 tick size(如从 0.01 → 0.001)
  • 用途:提高价格精度,防止"卡死"在 0.01 步长
  • 字段old_tick_sizenew_tick_size

4. last_trade_price 消息 --- 最新成交价格

  • 触发时机:每当有 Maker 和 Taker 成交
  • 内容 :成交的 pricesizesideasset_id
  • 注意:不包含订单细节,仅成交快照

5. best_bid_ask 消息(需开启 feature flag)

  • 触发时机:最优买卖价发生变化
  • 内容
    • best_bid / best_ask
    • spread(价差)
  • 优势 :比解析完整 book 更轻量,适合只关心 top-of-book 的应用

6. new_market 消息(需开启 feature flag)

  • 触发时机:平台上线一个新预测市场
  • 内容
    • 市场问题(question
    • condition ID(market
    • 所有 outcome 的 asset_idsoutcomes(如 ["Yes", "No"])
    • 描述、slug、事件元数据等
  • 用途:自动化发现新市场,用于爬虫或监控系统

7. market_resolved 消息(需开启 feature flag)

  • 触发时机:市场已结算(结果揭晓)
  • 内容
    • winning_asset_id
    • winning_outcome(如 "Yes")
    • 其余字段同 new_market
  • 用途:自动跟踪市场结果,用于结算、回测或通知

Sports Websocket

Overview

📡 1. 用途

  • 提供 实时体育赛事更新 ,包括:
    • 比分(scores)
    • 节/局/半场等阶段信息(periods)
    • 比赛状态(如进行中、暂停、结束等)

🔌 2. 连接方式

  • WebSocket 地址
    wss://sports-api.polymarket.com/ws
  • 无需认证 :这是一个公开广播频道,任何人都可以连接。
  • 无需订阅消息
    只要建立连接,就会自动开始推送所有正在进行的体育赛事更新,不需要发送额外的订阅请求。

❤️ 3. 连接管理(心跳机制)

为保持长连接稳定,服务器和客户端需配合完成 Ping/Pong 心跳

参数 默认值 说明
PING 间隔 5 秒 服务器每隔 5 秒向客户端发送一次 PING
PONG 超时 10 秒 客户端必须在 10 秒内回复 PONG,否则连接会被强制关闭

客户端必须实现 PONG 响应逻辑,否则连接会频繁断开。

🔁 4. 健康与重连建议

  • 如果未及时响应 PING → 连接被服务器终止
  • 建议客户端实现
    • 自动重连机制
    • 指数退避(exponential backoff) 策略(例如:1s、2s、4s、8s... 逐步增加重试间隔),避免频繁重连导致服务压力

🍪 5. 会话亲和性(Session Affinity)

  • 服务器使用名为 sports-resultsCookie 来确保: 同一个客户端始终连接到同一个后端实例
  • 对浏览器用户透明:浏览器会自动处理 Cookie,无需额外操作
  • 非浏览器客户端(如 Python、Node.js)注意
    需要保存并携带服务器返回的 Cookie,否则可能因负载均衡切换后端而丢失上下文或触发限流

Message Format

✅ 核心内容总结

1. 消息类型
  • 唯一消息类型sport_result(虽然 JSON 中未显式包含 event_type 字段,但所有推送都属于此类)
  • 触发时机
    • 比赛开始(上线)
    • 比分变化
    • 节/局/半场等阶段变更(如"Q4"、"HT")
    • 比赛结束
    • NFL 和大学橄榄球(CFB):控球权(possession)切换

所有消息自动广播给所有连接客户端,无需订阅。

🧱 2. 消息结构(关键字段)

字段 类型 说明
gameId number 唯一标识符,用于区分不同比赛(核心 ID)
leagueAbbreviation string 联赛缩写,如 "nfl", "nba", "cs2"
homeTeam / awayTeam string 主队 / 客队名称或简称
status string 比赛状态,如 "InProgress", "finished"
live boolean 是否正在进行中
ended boolean 是否已结束
score string 当前比分(格式因运动而异)
period string 当前阶段(如 "Q4", "2H", "2/3"
elapsed string 当前节已过时间(如 "5:18"
finishedTimestamp string 比赛结束的 Unix 时间戳(仅在 ended: true 时存在)
turn string 仅 NFL/CFB :当前控球方(小写队名缩写,如 "lac"

📌 3. 特殊说明

🔹 比分格式(score)因项目而异
  • 传统体育 (NFL/NBA):简单数字,如 "3-16"
  • 电竞(CS2) :复杂结构,如 "000-000|2-0|Bo3"
    → 可能表示:小分 0-0,大分 2-0,赛制为 Best of 3
🔹 period 值对照表
含义
1H / 2H 上半场 / 下半场(足球、篮球等)
1Q--4Q 第1--4节(NFL、NBA)
HT 中场休息
FT 常规时间结束
FT OT 加时赛后结束
1/3, 2/3 Bo3 赛制中的第1、2图(电竞)
End 1 MLB 第1局结束
🔹 Slug 命名规范(虽未在消息中出现,但供参考)

格式:{league}-{team1}-{team2}-{date}

示例:

  • nfl-buf-kc-2025-01-26
  • nba-lal-bos-2025-02-15

可用于构建市场 URL 或唯一赛事标识(但消息本身用 gameId

💡 4. 客户端处理建议

  • gameId 作为唯一键 来更新本地状态

  • 示例逻辑(JavaScript):

    js 复制代码
    setSportsData(prev => {
      const existing = prev.find(item => item.gameId === data.gameId);
      if (existing) {
        // 更新已有比赛
        return prev.map(item => 
          item.gameId === data.gameId ? data : item
        );
      }
      // 新增比赛
      return [...prev, data];
    });

这确保即使收到多条同一比赛的更新,也能正确合并状态。
是构建体育赛事监控面板、预测市场联动或实时提醒系统的基础数据源。

Quickstart

✅ 核心内容总结

1. 基本连接方式
  • 端点(Endpoint)wss://sports-api.polymarket.com/ws
  • 无需认证:公开服务,直接连接即可
  • 自动广播 :连接后立即开始推送所有活跃赛事的更新,无需发送订阅消息
2. JavaScript 示例(含关键逻辑)

提供了一个完整的浏览器端 WebSocket 连接示例,包含:

  • onopen:连接成功日志
  • onmessage核心!必须处理 PING/PONG
  • onclose:简单重连(通过页面刷新)
  • onerror:错误捕获
3. ⚠️ 关键要求:正确处理 PING/PONG 心跳

这是最容易出错也最关键的点

  • 服务器行为 :每 5 秒发送一次纯文本 "ping"
  • 客户端必须 :收到 "ping"立即回复 "pong"
  • 错误示例 :直接对所有消息执行 JSON.parse() → 遇到 "ping" 字符串会抛出异常,导致连接断开
  • 后果:10 秒内未回复 PONG → 服务器主动关闭连接

✅ 正确做法:

js 复制代码
if (event.data === 'ping') {
  ws.send('pong');
  return;
}
// 再处理 JSON 消息
4. 连接状态管理建议
  • 发送前检查 ws.readyState === WebSocket.OPEN
  • 避免在非 OPEN 状态下发送数据(如 PONG),防止报错

5. 浏览器环境特殊问题:Tab 不可见时连接可能中断
  • 浏览器为省电,可能暂停后台 Tab 的 WebSocket 或定时器
  • 解决方案 :监听 visibilitychange 事件
    • 当用户切回 Tab 且连接已断 → 自动重连

6. 常见问题与调试技巧
问题 可能原因 调试建议
连接 10 秒后断开 未正确响应 PING 检查是否处理了 "ping" 字符串
频繁掉线 未实现重连 / 心跳失败 添加指数退避重连逻辑
UI 未更新 消息解析错误 / 状态未合并 打印原始消息,确认 gameId 更新逻辑
内存泄漏 组件卸载后未关闭 WebSocket 在 React 中用 useEffect 清理连接

调试工具建议

  • 开启详细日志(记录 open/close/error/message)
  • 定时打印 readyState 监控连接状态

Real Time Data Stream

Real Time Data Socket

📡 1. 服务概述

  • 名称:Real-Time Data Socket(RTDS)
  • 用途 :提供两类实时数据:
    • Crypto Prices:加密货币的实时价格更新
    • Comments:评论相关事件(如新评论、点赞/反应等)
  • 官方客户端 :提供 TypeScript SDK(real-time-data-client

🔌 2. 连接信息

  • WebSocket 地址wss://ws-live-data.polymarket.com
  • 协议:标准 WebSocket
  • 数据格式:JSON

🔐 3. 认证机制

  • 大多数数据公开 ,但部分用户专属流 (如个人评论通知)可能需要认证:

    json 复制代码
    "gamma_auth": {
      "address": "0xYourWalletAddress"
    }
  • 仅在订阅需要身份验证的 topic 时才需提供 gamma_auth

⚙️ 4. 连接管理特性

  • 动态订阅
    连接建立后,可随时通过发送消息添加、移除或修改订阅无需断开重连
  • 心跳保活
    客户端应每 5 秒主动发送一次 "PING" (注意:这里是客户端发 PING,与 Sports API 不同),以维持连接

💡 注意:此处是 客户端主动发 PING,而 Sports API 是服务器发 PING、客户端回 PONG。两者机制相反!

📥 5. 消息统一结构

所有推送消息遵循固定格式:

json 复制代码
{
  "topic": "crypto_prices",     // 订阅主题
  "type": "update",             // 事件类型
  "timestamp": 1712345678901,   // 毫秒级 Unix 时间戳
  "payload": { ... }            // 具体数据(结构依 topic/type 而定)
}

🔁 6. 订阅管理(核心交互方式)

✅ 订阅示例
json 复制代码
{
  "action": "subscribe",
  "subscriptions": [
    {
      "topic": "crypto_prices",
      "type": "update",
      "filters": "BTC,ETH"       // 可选:过滤特定币种
    },
    {
      "topic": "comments",
      "type": "reaction_created",
      "gamma_auth": {
        "address": "0x123..."
      }
    }
  ]
}
❌ 取消订阅

"action" 改为 "unsubscribe",其余结构相同。

⚠️ 重要

  • 仅支持文档中列出的 topictype
  • 发送无效订阅可能导致连接被关闭

🛑 7. 错误处理

  • 网络错误:客户端应自动重连
  • 无效订阅消息:可能导致服务器主动断开连接
  • 认证失败:无法订阅受保护的用户数据流(但不影响其他公开订阅)

RTDS Crypto Prices

✅ 核心内容总结

1. 两种价格数据源
特性 Binance 源 (crypto_prices) Chainlink 源 (crypto_prices_chainlink)
数据来源 Binance 交易所实时行情 Chainlink 去中心化预言机喂价
认证要求 无需认证 无需认证
符号格式 小写拼接(如 btcusdt 斜杠分隔(如 btc/usd
订阅类型 type: "update" type: "*"(通配所有事件类型)
过滤方式 字符串逗号分隔(如 "btcusdt,ethusdt" JSON 字符串(如 "{\"symbol\":\"eth/usd\"}"

💡 两者提供相似的价格信息,但格式、语义和底层来源不同,适用于不同场景:

  • Binance:适合交易策略、短期波动监控
  • Chainlink:适合 DeFi 应用、链上结算参考价

📥 2. 消息统一结构(含 payload 细节)

所有价格更新消息都遵循 RTDS 的通用格式:

json 复制代码
{
  "topic": "...",
  "type": "update",
  "timestamp": 1753314064237,        // 消息发送时间(毫秒)
  "payload": {
    "symbol": "xxx",                  // 交易对标识
    "timestamp": 1753314064213,       // 价格生成/记录时间(毫秒)
    "value": 67234.50                 // 当前价格(单位:报价货币,如 USD/USDT)
  }
}
  • payload.timestamp:价格实际产生的时间(来自数据源)
  • 外层 timestamp:Polymarket 服务器推送该消息的时间

🔧 3. 订阅方式示例

✅ 订阅全部 Binance 价格
json 复制代码
{
  "action": "subscribe",
  "subscriptions": [{
    "topic": "crypto_prices",
    "type": "update"
  }]
}
✅ 只订阅 BTC 和 ETH(Binance)
json 复制代码
{
  "action": "subscribe",
  "subscriptions": [{
    "topic": "crypto_prices",
    "type": "update",
    "filters": "btcusdt,ethusdt"
  }]
}
json 复制代码
{
  "action": "subscribe",
  "subscriptions": [{
    "topic": "crypto_prices_chainlink",
    "type": "*",
    "filters": "{\"symbol\":\"eth/usd\"}"
  }]
}

⚠️ 注意:Chainlink 的 filtersJSON 字符串,不是普通字符串!


📊 4. 支持的交易对示例

资产 Binance 符号 Chainlink 符号
Bitcoin btcusdt btc/usd
Ethereum ethusdt eth/usd
Solana solusdt sol/usd
XRP xrpusdt xrp/usd

所有报价货币均为 USD 或 USDT(稳定币等价)


📌 5. 关键注意事项

  • 无认证要求:所有价格流都是公开的
  • 实时推送:价格变动时立即推送,非轮询
  • 时间戳双重含义:区分"价格生成时间"和"消息推送时间"
  • 官方 SDK 支持 :推荐使用 real-time-data-client(TypeScript)简化接入

RTDS Comments

✅ 核心内容总结

1. 功能概述
  • 用途:实时推送 Polymarket 平台上的用户评论活动
  • 支持的事件类型
    • comment_created:新评论发布(包括顶层评论和回复)
    • comment_removed:评论被删除
    • reaction_created / reaction_removed:对评论的点赞/取消点赞
  • 适用场景
    • 实时评论流展示
    • 讨论线程监控
    • 社区情绪分析

🔌 2. 订阅方式

  • Topiccomments
  • Type :指定具体事件类型(如 "comment_created"
  • 认证
    • 公开评论流通常无需认证
    • 若需接收用户私有数据 (如"我收到的回复"),可能需要提供 gamma_auth(含钱包地址)
  • 过滤(可选):可按评论 ID、用户地址、实体类型等筛选

订阅示例

json 复制代码
{
  "action": "subscribe",
  "subscriptions": [{
    "topic": "comments",
    "type": "comment_created"
  }]
}

📥 3. 消息结构

所有评论事件遵循 RTDS 统一格式:

json 复制代码
{
  "topic": "comments",
  "type": "comment_created",
  "timestamp": 1753454975808,   // 消息推送时间(毫秒 Unix 时间戳)
  "payload": { ... }            // 具体事件数据
}

🧾 4. Payload 字段详解(以 comment_created 为例)

字段 类型 说明
body string 评论正文内容
createdAt string 评论创建时间(ISO 8601 格式 ,如 "2025-07-25T14:49:35.801298Z"
id string 评论唯一 ID
parentCommentID string 父评论 ID(若为顶层评论则为 null 或空)
parentEntityID number 所属实体 ID(如某个 Event 或 Market 的 ID)
parentEntityType string 实体类型:"Event""Market"
userAddress string 发帖用户的 Polygon 钱包地址
replyAddress string 用于接收回复的地址(可能与 userAddress 不同)
reactionCount number 当前点赞数
reportCount number 被举报次数
profile object 用户公开资料
👤 Profile 对象字段
  • baseAddress:用户主地址
  • name:显示名称(如 "salted.caramel"
  • pseudonym:系统生成的匿名昵称(如 "Adored-Disparity"
  • displayUsernamePublic:是否公开用户名
  • proxyWallet:用于交易的代理钱包地址

🌲 5. 评论层级结构(嵌套回复)

  • 顶层评论parentCommentID 为空或 null
  • 回复评论parentCommentID 指向被回复的评论 ID
  • 所有评论都关联到一个父实体(如某个预测事件或市场)

示例:A 评论 → B 回复 A → C 回复 B,形成讨论链


⏱️ 6. 时间戳说明

  • payload.createdAt:评论实际创建时间(ISO 8601)
  • 外层 timestamp:WebSocket 消息发送时间(毫秒级 Unix 时间戳)

两者可能略有差异,反映网络传输延迟。


🛠️ 7. 使用建议与注意事项

  • 地址多样性 :注意区分 userAddressreplyAddressproxyWalletbaseAddress
  • 隐私控制 :用户名是否显示由 displayUsernamePublic 控制
  • 扩展性 :未来可能支持更多 parentEntityType(如文章、用户页等)
  • 官方 SDK :推荐使用 real-time-data-client(TypeScript)简化开发

Gamma Structure

Overview

✅ 核心要点总结

1. 背景:市场数据的两种来源
  • 链上数据(权威来源)
    所有用于市场结算(resolution) 的关键数据都已写入区块链(例如 UMA 协议中的 ancillaryData),这是最终、不可篡改的依据。
  • Gamma(托管索引服务)
    Polymarket 提供的一个中心化托管服务 ,用于:
    • 索引链上市场数据
    • 补充额外元数据(如分类、交易量统计、标签等)

💡 换句话说:结算靠链上,体验靠 Gamma


2. Gamma REST API 的定位
  • 只读公开接口:面向公众开放,无需认证(对普通用户)
  • 用途广泛 ,适用于:
    • 非营利性研究项目
    • 第三方交易平台 / 替代前端
    • 自动化交易机器人
    • 数据分析与可视化工具
3. API 端点
  • 基础 URL:
    https://gamma-api.polymarket.com

Gamma Structure

✅ 核心内容总结

1. 基本组成单元:Market(市场)
  • Market 是最基础、最核心的元素
  • 每个 Market 代表一个可交易的预测问题,例如:"Will Barron attend Harvard?"
  • 技术上,一个 Market 对应:
    • 一对 CLOB(中央限价订单簿)的 token IDs
    • 一个市场合约地址(market address)
    • 一个问题 ID(question ID)
    • 一个条件 ID(condition ID,通常来自预言机如 UMA)

简言之:每个 Market = 一个具体的"是/否"或"多选"预测合约

2. 组织容器:Event(事件)
  • Event 是一组相关 Markets 的集合,用于逻辑归类。
  • 所有 Market 都属于某个 Event,但 Event 本身不直接交易。
  • 两种常见变体
    • 单市场事件(SMP, Single-Market Prediction)
      一个 Event 只包含 1 个 Market(例如一个简单的二元问题)。
    • 多市场事件(GMP, Grouped-Market Prediction)
      一个 Event 包含 ≥2 个互斥或相关的 Markets(通常构成一个完整预测集)。

📌 示例说明

以问题 "Where will Barron Trump attend College?" 为例:

  • 这是一个 Event
  • 它包含多个互斥的 Markets
    • "Will Barron attend Georgetown?"
    • "Will Barron attend NYU?"
    • "Will Barron attend UPenn?"
    • "Will Barron attend Harvard?"
    • "Will Barron attend another college?"

这些 Markets 共同覆盖所有可能结果,构成一个典型的 GMP(多市场事件)

🔑 关键要点

  • Market 是交易和结算的基本单位
  • Event 是 UI/UX 和数据组织的逻辑分组,帮助用户理解上下文。
  • Gamma 通过这种层级结构,使复杂预测市场更易浏览、分析和集成。

How to Fetch Markets

✅ 核心内容总结

🎯 三大获取策略(按使用场景划分)
策略 适用场景 推荐接口 优势
1. 按 Slug 获取 已知具体市场或事件(如从 URL 得到) GET /events/slug/{slug}``GET /markets/slug/{slug} 最精准、高效,直接命中目标
2. 按标签(Tags)过滤 按类别、体育项目、主题筛选(如"NFL"、"政治") GET /markets?tag_id=xxx``GET /events?tag_id=xxx 灵活分类浏览,支持多维筛选
3. 获取所有活跃市场 全量市场发现、分析、监控 GET /events?closed=false&order=id... 最完整覆盖,通过 Event 关联 Market

🔍 详细说明

1. 按 Slug 获取(精准查询)
  • Slug 来源 :Polymarket 前端 URL 中 /event//market/ 后的路径
    例:https://polymarket.com/event/fed-decision-in-october → slug = fed-decision-in-october
  • 用途 :当你已经知道某个市场的唯一标识时(如用户分享链接),这是最快、最可靠的方式
2. 按 Tags 过滤(分类查询)
  • 先发现标签

    • 通用标签:GET /tags
    • 体育标签及元数据:GET /sports(含图片、赛程、解析源等)
  • 再用标签查询

    bash 复制代码
    curl "https://gamma-api.polymarket.com/events?tag_id=100381&closed=false"
  • 高级过滤

    • related_tags=true:包含相关标签的市场
    • exclude_tag_id=xxx:排除某些标签
3. 获取所有活跃市场(全量抓取)
  • 为什么用 /events 而不是 /markets
    因为 Event 是 Market 的容器,一个 Event 可包含多个 Markets(如多选题),通过 Event 能更完整地组织数据。
  • 关键参数组合
    • closed=false:只获取未结算 的活跃市场(强烈建议默认加上
    • order=id&ascending=false:按 ID 降序 → 最新市场优先
    • limit + offset:分页控制

📖 分页机制(Pagination)

  • 所有列表接口(/events, /markets)均支持分页

  • 使用 limit(每页数量)和 offset(起始偏移)实现翻页

  • 示例

    bash 复制代码
    # 第1页(0-49)
    ?limit=50&offset=0
    # 第2页(50-99)
    ?limit=50&offset=50

⚠️ 注意:不要一次性请求大量数据,应循环分页获取。


🛠️ 最佳实践(Best Practices)

场景 建议
获取单个市场 ✅ 优先用 slug
浏览某类市场 ✅ 用 tag_id 过滤
全量市场同步 ✅ 用 /events + 分页 + closed=false
避免无效数据 ✅ 默认加 closed=false(除非需要历史数据)
生产环境 ✅ 实现 速率限制(rate limiting),避免被限流

🔗 补充资源

  • /tags:获取所有可用标签
  • /sports:获取体育赛事专属标签与元数据
  • 搜索功能 :另有 Search Markets 接口(未展开)

Subgraph

Polymarket 将链上数据通过开源的 The Graph 子图 进行索引和聚合,并通过 GraphQL 接口提供结构化、实时的市场与用户数据,供开发者查询使用。

✅ 核心要点总结

1. 什么是 Subgraph?

  • 是基于 The Graph 协议构建的数据索引服务。
  • 从 Polymarket 的智能合约中实时监听并处理链上事件(如订单、交易、持仓变化等)。
  • 将原始链上数据转化为可查询的结构化模型(如用户持仓、市场成交量、活动历史等)。

2. 功能与用途

  • 提供 聚合计算历史事件索引 ,包括:
    • 市场交易量(Volume)
    • 用户持仓(Positions)
    • 订单簿数据(Orders)
    • 活动记录(Activity)
    • 未平仓合约(Open Interest)
    • 盈亏(PNL, Profit and Loss)
  • 数据实时更新,与 Polymarket 主站前端展示的数据保持一致。
  • 可用于构建:
    • 第三方分析仪表盘
    • 交易机器人
    • 钱包集成
    • 研究工具

3. 开源与托管

  • 完全开源 :代码托管在 Polymarket GitHub,数据模型定义在 schema.graphql 文件中。
  • 公共托管 :由第三方服务商 Goldsky 提供免费、公开的 GraphQL 查询端点(无需自建节点)。

4. 可用的子图列表(Hosted on Goldsky)

每个子图聚焦不同维度的数据:

子图名称 功能 公共查询地址
Orderbook Subgraph 订单簿、挂单数据 .../orderbook-subgraph/0.0.1/gn
Positions Subgraph 用户当前持仓 .../positions-subgraph/0.0.7/gn
Activity Subgraph 用户/市场活动历史(交易、创建等) .../activity-subgraph/0.0.4/gn
Open Interest (OI) Subgraph 市场未平仓量 .../oi-subgraph/0.0.6/gn
PNL Subgraph 用户盈亏计算 .../pnl-subgraph/0.0.14/gn

所有链接均附带 GraphQL Playground,可直接在浏览器中编写和测试查询。

Resolution

✅ 核心内容总结

1. 结算机制基础:UMA Optimistic Oracle(OO)

  • Polymarket 使用 UMA 的 Optimistic Oracle 作为其市场结果的去中心化裁决系统
  • OO 的核心逻辑是 "乐观假设 + 争议挑战"
    • 任何人都可对某个问题提出一个结果(称为"报价",price proposal),并质押一笔保证金(proposalBond)。
    • 如果 无人在"存活期"(liveness period)内提出异议,该结果自动生效。
    • 如果 有人质疑 ,则触发 争议(Dispute) ,问题被提交给 UMA 的 DVM(Data Verification Mechanism) ------ 由 UMA 代币持有者投票决定最终答案。
    • DVM 投票通常需要 几天时间,但作为最终仲裁保障。

💡 这是一种 低成本、高效率、抗女巫攻击 的预言机设计:大多数情况无需投票,仅在有争议时才启动昂贵的链上治理。


2. Polymarket 的适配器:UmaCtfAdapter

  • 由于 Polymarket 的 CTF 市场与 UMA OO 的接口不直接兼容,Polymarket 开发了 自定义智能合约 UmaCtfAdapter 作为桥梁。
  • 该适配器负责:
    • 初始化市场(调用 initialize()
    • 向 OO 提交问题(含 ancillaryData
    • 处理奖励、保证金、存活期等参数
    • 在 OO 返回结果后,更新 Polymarket 市场状态

3. 关键概念:Ancillary Data 与 Clarifications(澄清)

  • 每个市场的问题文本和上下文存储在 ancillaryData 中。
  • v2+ 版本的适配器支持"公告板"功能
    • 市场创建者可在结算前发布澄清说明(clarifications),例如修正歧义或提供额外上下文。
    • 如果允许澄清,ancillaryData 会包含类似语句: "Updates made by the question creator via the bulletin board on [地址] should be considered..."
    • 澄清不能改变问题原意,仅用于消除模糊性。

4. 结算流程(Resolution Flow)

整个过程由以下动作组成:

步骤 说明
Initialize 创建市场,设置问题、奖励、保证金、存活期等,获得 questionID
Propose Price 任何人可提交结果(如 "1" 表示"是"),并质押 proposalBond
Dispute(可选) 若有人反对,可发起争议,需质押反向保证金
🔄 三种可能的流程路径:
  1. 无争议快速结算
    Initialize → Propose → Resolve

    (最常见,高效)

  2. 一次争议后结算
    Initialize → Propose → Dispute → Propose → Resolve

    (第一次提案被挑战,第二次提案无人反对)

  3. 两次争议,进入 DVM 投票
    Initialize → Propose → Dispute → Propose → Dispute → Resolve (via DVM)

    (最终由 UMA 持币者投票裁决)

🔒 设计优势

  • 防止"垃圾提案"拖延结算(第一次离谱提案可被挑战,不影响整体进度)
  • 提高恶意攻击成本(需连续两次发起争议才能触发 DVM)

5. 已部署合约地址(Polygon 主网)

版本 地址
v3.0 0x157Ce2d672854c848c9b79C49a8Cc6cc89176a49
v2.0 0x6A9D0222186C0FceA7547534cC13c3CFd9b7b6A4
v1.0 0xC8B122858a4EF82C2d4eE2E6A276C719e6929951

⚠️ 注意:v2+ 支持澄清功能,v1 不支持。


6. 附加资源

  • 审计报告(Audit)
  • 智能合约源代码(Source Code)
  • UMA 官方文档与 Oracle Portal(用于查询提案/争议状态)
相关推荐
阿豪学编程2 小时前
【Linux】Socket网络编程
linux·服务器·网络
阿钱真强道2 小时前
06 thingsboard-ubuntu20-rk3588-连通性-测试 MQTT HTTP COAP
网络·物联网·网络协议·http
嵌入式×边缘AI:打怪升级日志11 小时前
[特殊字符] USBX 学习笔记(基于 Azure® RTOS)
网络
米羊12112 小时前
Linux 内核漏洞提权
网络·安全·web安全
运维行者_12 小时前
2026 技术升级,OpManager 新增 AI 网络拓扑与带宽预测功能
运维·网络·数据库·人工智能·安全·web安全·自动化
Ar呐13 小时前
软考网规篇之局域网——网关冗余技术VRRP
网络·计算机网络
头发还没掉光光13 小时前
HTTP协议从基础到实战全解析
linux·服务器·网络·c++·网络协议·http
漂洋过海的鱼儿13 小时前
设计模式——EIT构型(三)
java·网络·设计模式