Official PolyEdge SDKs
PolyEdge provides official client libraries for TypeScript / Node.js, Python, Rust, and Go to stream Polymarket mempool trades with ultra-low latency and query the on-chain Polymarket trade analytics API.
| Language | Package | Install | Links |
|---|---|---|---|
| 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 |
Built-in Streaming Reliability
- 45s Keep-Alive Watchdog: Automatically detects silent TCP half-open connection drops and reconnects.
- Auto-Resume with
Last-Event-ID: Replays buffered trades upon reconnection to prevent missed events.
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. Query Top Traders Leaderboard
const leaderboard = await client.analytics.getLeaderboard({ limit: 5 });
console.log(`Tracked Traders: ${leaderboard.total_count}`);
leaderboard.traders?.forEach((t, i) => {
console.log(
`#${i + 1} ${t.profile?.address} (${t.profile?.name || "Anonymous"}) | PnL: $${t.total_pnl} | WinRate: ${t.win_rate}%`
);
});
// 2. Create Stream Filtered by Tag and Series
const stream = await client.streams.create({
name: "Crypto & Solana 5M Stream",
tags: ["crypto"],
series: ["sol-up-or-down-5m"],
});
console.log(`Stream created: ${stream.id}`);
// 3. Connect to Real-Time Mempool SSE Feed
const conn = client.streams.connect(stream.id, { heartbeatTimeoutMs: 45_000 });
// Option A: Modern Async Iterator (for await)
for await (const tx of conn) {
console.log(`⚡ [Tx] ${tx.tx_hash.slice(0, 18)}... | ${tx.market?.question}`);
console.log(` Taker: ${tx.taker?.outcome} (${tx.taker?.side}) | Shares: ${tx.taker?.shares} | USDC: ${tx.taker?.usdc}`);
}
// Option B: Event Listener
// conn.on("tx", (tx, id) => {
// console.log(`⚡ [Tx #${id}] ${tx.tx_hash.slice(0, 18)}... | ${tx.market?.question}`);
// });
// conn.on("error", (err) => console.error("Stream 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. Query Top Traders Leaderboard
leaderboard = client.analytics.get_leaderboard(limit=5)
print(f"Tracked Traders: {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 'Anonymous'}) | PnL: ${t.get('total_pnl')} | WinRate: {t.get('win_rate')}%")
# 2. Create Stream Filtered by Tag and Series
stream = client.streams.create({
"name": "Crypto & Solana 5M Stream",
"tags": ["crypto"],
"series": ["sol-up-or-down-5m"],
})
print(f"Stream created: {stream['id']}")
# 3. Connect to Real-Time Mempool SSE Feed (default 45s watchdog)
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: {taker.get('outcome')} ({taker.get('side')}) | Shares: {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. Query Top Traders Leaderboard
let leaderboard = client.analytics().get_leaderboard(Some(5), None).await?;
println!("Tracked Traders: {:?}", 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("Anonymous");
println!("#{i + 1} {addr} ({name}) | PnL: ${:?} | WinRate: {:?}%", t.total_pnl, t.win_rate);
}
// 2. Create Stream Filtered by Tag and 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 created: {}", stream_id);
// 3. Connect to Real-Time Mempool SSE Feed
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!(" Taker: {} ({:?}) | Shares: {}", 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. Query Top Traders Leaderboard
leaderboard, err := client.Analytics.GetLeaderboard(ctx, 5, 0)
if err != nil {
panic(err)
}
fmt.Printf("Tracked Traders: %d\n", leaderboard.TotalCount)
for i, t := range leaderboard.Traders {
name := t.Profile.Name
if name == "" {
name = "Anonymous"
}
fmt.Printf("#%d %s (%s) | PnL: $%d | WinRate: %.2f%%\n",
i+1, t.Profile.Address, name, t.TotalPnl, t.WinRate)
}
// 2. Create Stream Filtered by Tag and 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("Stream created: %s\n", stream.ID)
// 3. Connect to Real-Time Mempool SSE Feed
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(" Taker: %s (%s) | Shares: %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("Stream error: %v\n", err)
}
case <-ctx.Done():
return
}
}
}