PolyEdge 官方 SDK 使用指南

PolyEdge 为 TypeScript / Node.js、Python、Rust 和 Go 提供了官方客户端开发库,用于超低时延出块前内存池Polymarket交易推流及调用链上 Polymarket 交易分析 API。

语言 包名 安装命令 相关链接
TypeScript polyedge npm i polyedge npm · GitHub
Python polyedge pip install polyedge PyPI · GitHub
Rust polyedge cargo add polyedge crates.io · GitHub
Go polyedge-go go get github.com/PolyEdgeDev/polyedge-go pkg.go.dev · GitHub

内置连接稳定性保障

  • 45 秒保活看门狗(Watchdog):自动检测心跳中断与静默 TCP 半开连接,触发平滑重连。
  • Last-Event-ID 增量恢复:重连时携带最新事件 ID,服务端自动补发缓冲期内的出块前内存池Polymarket交易。

TypeScript / Node.js

npm install polyedge
import { PolyEdgeClient } from "polyedge";

const client = new PolyEdgeClient({
  apiKey: process.env.POLYEDGE_API_KEY || "pe_live_your_api_key",
});

async function main() {
  // 1. 获取顶级交易员排行榜
  const leaderboard = await client.analytics.getLeaderboard({ limit: 5 });
  console.log(`全网追踪交易员总数: ${leaderboard.total_count}`);
  leaderboard.traders?.forEach((t, i) => {
    console.log(
      `#${i + 1} ${t.profile?.address} (${t.profile?.name || "匿名交易员"}) | 收益: $${t.total_pnl} | 胜率: ${t.win_rate}%`
    );
  });

  // 2. 创建按 Tag 和 Series 过滤的交易流
  const stream = await client.streams.create({
    name: "Crypto & Solana 5M Stream",
    tags: ["crypto"],
    series: ["sol-up-or-down-5m"],
  });
  console.log(`流创建成功: ${stream.id}`);

  // 3. 连接实时内存池 SSE 数据流
  const conn = client.streams.connect(stream.id, { heartbeatTimeoutMs: 45_000 });

  // 方式 A: 现代异步迭代器 (for await)
  for await (const tx of conn) {
    console.log(`⚡ [Tx] ${tx.tx_hash.slice(0, 18)}... | ${tx.market?.question}`);
    console.log(`   吃单: ${tx.taker?.outcome} (${tx.taker?.side}) | 份额: ${tx.taker?.shares} | USDC: ${tx.taker?.usdc}`);
  }

  // 方式 B: 事件监听器
  // conn.on("tx", (tx, id) => {
  //   console.log(`⚡ [Tx #${id}] ${tx.tx_hash.slice(0, 18)}... | ${tx.market?.question}`);
  // });
  // conn.on("error", (err) => console.error("数据流异常:", err));
}

main().catch(console.error);

Python

pip install polyedge
import os
import asyncio
from polyedge import PolyEdgeClient

client = PolyEdgeClient(api_key=os.getenv("POLYEDGE_API_KEY", "pe_live_your_api_key"))

async def main():
    # 1. 获取顶级交易员排行榜
    leaderboard = client.analytics.get_leaderboard(limit=5)
    print(f"全网追踪交易员总数: {leaderboard.get('total_count')}")
    for i, t in enumerate(leaderboard.get("traders", [])):
        profile = t.get("profile", {})
        print(f"#{i + 1} {profile.get('address')} ({profile.get('name') or '匿名交易员'}) | 收益: ${t.get('total_pnl')} | 胜率: {t.get('win_rate')}%")

    # 2. 创建按 Tag 和 Series 过滤的交易流
    stream = client.streams.create({
        "name": "Crypto & Solana 5M Stream",
        "tags": ["crypto"],
        "series": ["sol-up-or-down-5m"],
    })
    print(f"流创建成功: {stream['id']}")

    # 3. 连接实时内存池 SSE 数据流 (默认 45 秒看门狗保活)
    conn = client.streams.connect(stream["id"], heartbeat_timeout=45.0)
    try:
        async for tx in conn.subscribe():
            taker = tx.get("taker", {})
            print(f"⚡ [Tx] {tx.get('tx_hash', '')[:18]}... | {tx.get('market', {}).get('question')}")
            print(f"   吃单: {taker.get('outcome')} ({taker.get('side')}) | 份额: {taker.get('shares')} | USDC: {taker.get('usdc')}")
    finally:
        conn.close()

if __name__ == "__main__":
    asyncio.run(main())

Rust

cargo add polyedge tokio --features full futures-util
use futures_util::StreamExt;
use polyedge::client::UserCreateStreamRequest;
use polyedge::PolyEdgeClient;
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = env::var("POLYEDGE_API_KEY").unwrap_or_else(|_| "pe_live_your_api_key".to_string());
    let client = PolyEdgeClient::new(&api_key);

    // 1. 获取顶级交易员排行榜
    let leaderboard = client.analytics().get_leaderboard(Some(5), None).await?;
    println!("全网追踪交易员总数: {:?}", leaderboard.total_count);
    for (i, t) in leaderboard.traders.unwrap_or_default().iter().enumerate() {
        let addr = t.profile.as_ref().and_then(|p| p.address.as_deref()).unwrap_or("unknown");
        let name = t.profile.as_ref().and_then(|p| p.name.as_deref()).unwrap_or("匿名交易员");
        println!("#{i + 1} {addr} ({name}) | 收益: ${:?} | 胜率: {:?}%", t.total_pnl, t.win_rate);
    }

    // 2. 创建按 Tag 和 Series 过滤的交易流
    let req = UserCreateStreamRequest {
        name: Some("Crypto & Solana 5M Stream".to_string()),
        tags: Some(vec!["crypto".to_string()]),
        series: Some(vec!["sol-up-or-down-5m".to_string()]),
        addresses: None,
    };
    let stream = client.streams().create(&req).await?;
    let stream_id = stream.id.unwrap_or_default();
    println!("流创建成功: {}", stream_id);

    // 3. 连接实时内存池 SSE 数据流
    let conn = client.streams().connect(&stream_id);
    let mut stream_iter = Box::pin(conn.subscribe());

    while let Some(item) = stream_iter.next().await {
        if let Ok(tx) = item {
            let hash = tx.tx_hash.unwrap_or_default();
            let short_hash = if hash.len() > 18 { &hash[..18] } else { &hash };
            let question = tx.market.and_then(|m| m.question).unwrap_or_default();
            let taker = tx.taker;
            let outcome = taker.as_ref().and_then(|t| t.outcome.as_deref()).unwrap_or_default();
            let side = taker.as_ref().and_then(|t| t.side.as_ref());
            let shares = taker.as_ref().and_then(|t| t.shares.as_deref()).unwrap_or_default();

            println!("⚡ [Tx] {}... | {}", short_hash, question);
            println!("   吃单: {} ({:?}) | 份额: {}", outcome, side, shares);
        }
    }

    Ok(())
}

Go

go get github.com/PolyEdgeDev/polyedge-go
package main

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

	polyedge "github.com/PolyEdgeDev/polyedge-go"
)

func main() {
	apiKey := os.Getenv("POLYEDGE_API_KEY")
	if apiKey == "" {
		apiKey = "pe_live_your_api_key"
	}

	client, err := polyedge.NewClient(apiKey)
	if err != nil {
		panic(err)
	}

	ctx := context.Background()

	// 1. 获取顶级交易员排行榜
	leaderboard, err := client.Analytics.GetLeaderboard(ctx, 5, 0)
	if err != nil {
		panic(err)
	}
	fmt.Printf("全网追踪交易员总数: %d\n", leaderboard.TotalCount)
	for i, t := range leaderboard.Traders {
		name := t.Profile.Name
		if name == "" {
			name = "匿名交易员"
		}
		fmt.Printf("#%d %s (%s) | 收益: $%d | 胜率: %.2f%%\n",
			i+1, t.Profile.Address, name, t.TotalPnl, t.WinRate)
	}

	// 2. 创建按 Tag 和 Series 过滤的交易流
	stream, err := client.Streams.Create(ctx, &polyedge.UserCreateStreamRequest{
		Name:   "Crypto & Solana 5M Stream",
		Tags:   []string{"crypto"},
		Series: []string{"sol-up-or-down-5m"},
	})
	if err != nil {
		panic(err)
	}
	fmt.Printf("流创建成功: %s\n", stream.ID)

	// 3. 连接实时内存池 SSE 数据流
	conn, err := client.Streams.Connect(stream.ID, polyedge.StreamOptions{
		HeartbeatTimeout: 45 * time.Second,
	})
	if err != nil {
		panic(err)
	}

	txCh, errCh := conn.Subscribe(ctx)
	for {
		select {
		case tx, ok := <-txCh:
			if !ok {
				return
			}
			hash := tx.TxHash
			if len(hash) > 18 {
				hash = hash[:18]
			}
			fmt.Printf("⚡ [Tx] %s... | %s\n", hash, tx.Market.Question)
			fmt.Printf("   吃单: %s (%s) | 份额: %s | USDC: %s\n",
				tx.Taker.Outcome, tx.Taker.Side, tx.Taker.Shares, tx.Taker.USDC)

		case err, ok := <-errCh:
			if ok && err != nil {
				fmt.Printf("数据流异常: %v\n", err)
			}

		case <-ctx.Done():
			return
		}
	}
}