@catalyst-team/poly-sdk 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +665 -807
- package/README.zh-CN.md +645 -342
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js +267 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.js +6 -3
- package/dist/__tests__/integration/data-api.integration.test.js.map +1 -1
- package/dist/__tests__/integration/market-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/market-service.integration.test.js +173 -0
- package/dist/__tests__/integration/market-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.js +58 -0
- package/dist/__tests__/integration/trading-service.integration.test.js.map +1 -0
- package/dist/clients/clob-api.d.ts +73 -0
- package/dist/clients/clob-api.d.ts.map +1 -1
- package/dist/clients/clob-api.js +60 -0
- package/dist/clients/clob-api.js.map +1 -1
- package/dist/clients/ctf-client.d.ts +6 -4
- package/dist/clients/ctf-client.d.ts.map +1 -1
- package/dist/clients/ctf-client.js.map +1 -1
- package/dist/clients/data-api.d.ts +333 -15
- package/dist/clients/data-api.d.ts.map +1 -1
- package/dist/clients/data-api.js +398 -26
- package/dist/clients/data-api.js.map +1 -1
- package/dist/clients/gamma-api.d.ts +5 -0
- package/dist/clients/gamma-api.d.ts.map +1 -1
- package/dist/clients/gamma-api.js +2 -0
- package/dist/clients/gamma-api.js.map +1 -1
- package/dist/clients/subgraph.d.ts +196 -0
- package/dist/clients/subgraph.d.ts.map +1 -0
- package/dist/clients/subgraph.js +332 -0
- package/dist/clients/subgraph.js.map +1 -0
- package/dist/clients/websocket-manager.d.ts +3 -0
- package/dist/clients/websocket-manager.d.ts.map +1 -1
- package/dist/clients/websocket-manager.js +10 -3
- package/dist/clients/websocket-manager.js.map +1 -1
- package/dist/core/cache.d.ts +3 -0
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +5 -0
- package/dist/core/cache.js.map +1 -1
- package/dist/core/errors.d.ts +2 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +2 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/rate-limiter.d.ts +3 -1
- package/dist/core/rate-limiter.d.ts.map +1 -1
- package/dist/core/rate-limiter.js +12 -0
- package/dist/core/rate-limiter.js.map +1 -1
- package/dist/core/types.d.ts +205 -13
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +30 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/types.test.d.ts +7 -0
- package/dist/core/types.test.d.ts.map +1 -0
- package/dist/core/types.test.js +122 -0
- package/dist/core/types.test.js.map +1 -0
- package/dist/index.d.ts +84 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +139 -132
- package/dist/index.js.map +1 -1
- package/dist/scripts/dip-arb/auto-trade.d.ts +20 -0
- package/dist/scripts/dip-arb/auto-trade.d.ts.map +1 -0
- package/dist/scripts/dip-arb/auto-trade.js +373 -0
- package/dist/scripts/dip-arb/auto-trade.js.map +1 -0
- package/dist/scripts/dip-arb/example-basic.d.ts +30 -0
- package/dist/scripts/dip-arb/example-basic.d.ts.map +1 -0
- package/dist/scripts/dip-arb/example-basic.js +222 -0
- package/dist/scripts/dip-arb/example-basic.js.map +1 -0
- package/dist/scripts/dip-arb/redeem-positions.d.ts +11 -0
- package/dist/scripts/dip-arb/redeem-positions.d.ts.map +1 -0
- package/dist/scripts/dip-arb/redeem-positions.js +201 -0
- package/dist/scripts/dip-arb/redeem-positions.js.map +1 -0
- package/dist/scripts/dip-arb/scan-markets.d.ts +6 -0
- package/dist/scripts/dip-arb/scan-markets.d.ts.map +1 -0
- package/dist/scripts/dip-arb/scan-markets.js +73 -0
- package/dist/scripts/dip-arb/scan-markets.js.map +1 -0
- package/dist/services/arbitrage-service.d.ts +3 -2
- package/dist/services/arbitrage-service.d.ts.map +1 -1
- package/dist/services/arbitrage-service.js +71 -43
- package/dist/services/arbitrage-service.js.map +1 -1
- package/dist/services/binance-service.d.ts +154 -0
- package/dist/services/binance-service.d.ts.map +1 -0
- package/dist/services/binance-service.js +266 -0
- package/dist/services/binance-service.js.map +1 -0
- package/dist/services/dip-arb-service.d.ts +209 -0
- package/dist/services/dip-arb-service.d.ts.map +1 -0
- package/dist/services/dip-arb-service.js +1602 -0
- package/dist/services/dip-arb-service.js.map +1 -0
- package/dist/services/dip-arb-types.d.ts +553 -0
- package/dist/services/dip-arb-types.d.ts.map +1 -0
- package/dist/services/dip-arb-types.js +164 -0
- package/dist/services/dip-arb-types.js.map +1 -0
- package/dist/services/market-service.d.ts +267 -8
- package/dist/services/market-service.d.ts.map +1 -1
- package/dist/services/market-service.js +771 -42
- package/dist/services/market-service.js.map +1 -1
- package/dist/services/onchain-service.d.ts +309 -0
- package/dist/services/onchain-service.d.ts.map +1 -0
- package/dist/services/onchain-service.js +417 -0
- package/dist/services/onchain-service.js.map +1 -0
- package/dist/services/realtime-service-v2.d.ts +362 -0
- package/dist/services/realtime-service-v2.d.ts.map +1 -0
- package/dist/services/realtime-service-v2.js +858 -0
- package/dist/services/realtime-service-v2.js.map +1 -0
- package/dist/services/realtime-service.d.ts +17 -17
- package/dist/services/realtime-service.d.ts.map +1 -1
- package/dist/services/realtime-service.js +91 -59
- package/dist/services/realtime-service.js.map +1 -1
- package/dist/services/smart-money-service.d.ts +352 -0
- package/dist/services/smart-money-service.d.ts.map +1 -0
- package/dist/services/smart-money-service.js +582 -0
- package/dist/services/smart-money-service.js.map +1 -0
- package/dist/services/trading-service.d.ts +177 -0
- package/dist/services/trading-service.d.ts.map +1 -0
- package/dist/services/trading-service.js +422 -0
- package/dist/services/trading-service.js.map +1 -0
- package/dist/services/wallet-service.d.ts +225 -3
- package/dist/services/wallet-service.d.ts.map +1 -1
- package/dist/services/wallet-service.js +511 -3
- package/dist/services/wallet-service.js.map +1 -1
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.js +267 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.js +260 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.js +234 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/data-api.integration.test.d.ts +9 -0
- package/dist/src/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/data-api.integration.test.js +164 -0
- package/dist/src/__tests__/integration/data-api.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.js +170 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/market-service.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/market-service.integration.test.js +180 -0
- package/dist/src/__tests__/integration/market-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.js +58 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/test-utils.d.ts +92 -0
- package/dist/src/__tests__/test-utils.d.ts.map +1 -0
- package/dist/src/__tests__/test-utils.js +143 -0
- package/dist/src/__tests__/test-utils.js.map +1 -0
- package/dist/src/clients/bridge-client.d.ts +388 -0
- package/dist/src/clients/bridge-client.d.ts.map +1 -0
- package/dist/src/clients/bridge-client.js +587 -0
- package/dist/src/clients/bridge-client.js.map +1 -0
- package/dist/src/clients/ctf-client.d.ts +475 -0
- package/dist/src/clients/ctf-client.d.ts.map +1 -0
- package/dist/src/clients/ctf-client.js +915 -0
- package/dist/src/clients/ctf-client.js.map +1 -0
- package/dist/src/clients/data-api.d.ts +452 -0
- package/dist/src/clients/data-api.d.ts.map +1 -0
- package/dist/src/clients/data-api.js +637 -0
- package/dist/src/clients/data-api.js.map +1 -0
- package/dist/src/clients/gamma-api.d.ts +421 -0
- package/dist/src/clients/gamma-api.d.ts.map +1 -0
- package/dist/src/clients/gamma-api.js +359 -0
- package/dist/src/clients/gamma-api.js.map +1 -0
- package/dist/src/clients/subgraph.d.ts +196 -0
- package/dist/src/clients/subgraph.d.ts.map +1 -0
- package/dist/src/clients/subgraph.js +332 -0
- package/dist/src/clients/subgraph.js.map +1 -0
- package/dist/src/core/cache-adapter-bridge.d.ts +36 -0
- package/dist/src/core/cache-adapter-bridge.d.ts.map +1 -0
- package/dist/src/core/cache-adapter-bridge.js +81 -0
- package/dist/src/core/cache-adapter-bridge.js.map +1 -0
- package/dist/src/core/cache.d.ts +43 -0
- package/dist/src/core/cache.d.ts.map +1 -0
- package/dist/src/core/cache.js +76 -0
- package/dist/src/core/cache.js.map +1 -0
- package/dist/src/core/errors.d.ts +39 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +86 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/rate-limiter.d.ts +33 -0
- package/dist/src/core/rate-limiter.d.ts.map +1 -0
- package/dist/src/core/rate-limiter.js +82 -0
- package/dist/src/core/rate-limiter.js.map +1 -0
- package/dist/src/core/types.d.ts +506 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +49 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/types.test.d.ts +7 -0
- package/dist/src/core/types.test.d.ts.map +1 -0
- package/dist/src/core/types.test.js +122 -0
- package/dist/src/core/types.test.js.map +1 -0
- package/dist/src/core/unified-cache.d.ts +63 -0
- package/dist/src/core/unified-cache.d.ts.map +1 -0
- package/dist/src/core/unified-cache.js +114 -0
- package/dist/src/core/unified-cache.js.map +1 -0
- package/dist/src/index.d.ts +159 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +262 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/arbitrage-service.d.ts +409 -0
- package/dist/src/services/arbitrage-service.d.ts.map +1 -0
- package/dist/src/services/arbitrage-service.js +1450 -0
- package/dist/src/services/arbitrage-service.js.map +1 -0
- package/dist/src/services/authorization-service.d.ts +97 -0
- package/dist/src/services/authorization-service.d.ts.map +1 -0
- package/dist/src/services/authorization-service.js +279 -0
- package/dist/src/services/authorization-service.js.map +1 -0
- package/dist/src/services/binance-service.d.ts +154 -0
- package/dist/src/services/binance-service.d.ts.map +1 -0
- package/dist/src/services/binance-service.js +266 -0
- package/dist/src/services/binance-service.js.map +1 -0
- package/dist/src/services/dip-arb-service.d.ts +245 -0
- package/dist/src/services/dip-arb-service.d.ts.map +1 -0
- package/dist/src/services/dip-arb-service.js +1865 -0
- package/dist/src/services/dip-arb-service.js.map +1 -0
- package/dist/src/services/dip-arb-types.d.ts +553 -0
- package/dist/src/services/dip-arb-types.d.ts.map +1 -0
- package/dist/src/services/dip-arb-types.js +164 -0
- package/dist/src/services/dip-arb-types.js.map +1 -0
- package/dist/src/services/market-service.d.ts +370 -0
- package/dist/src/services/market-service.d.ts.map +1 -0
- package/dist/src/services/market-service.js +1200 -0
- package/dist/src/services/market-service.js.map +1 -0
- package/dist/src/services/onchain-service.d.ts +309 -0
- package/dist/src/services/onchain-service.d.ts.map +1 -0
- package/dist/src/services/onchain-service.js +417 -0
- package/dist/src/services/onchain-service.js.map +1 -0
- package/dist/src/services/realtime-service-v2.d.ts +367 -0
- package/dist/src/services/realtime-service-v2.d.ts.map +1 -0
- package/dist/src/services/realtime-service-v2.js +876 -0
- package/dist/src/services/realtime-service-v2.js.map +1 -0
- package/dist/src/services/smart-money-service.d.ts +352 -0
- package/dist/src/services/smart-money-service.d.ts.map +1 -0
- package/dist/src/services/smart-money-service.js +582 -0
- package/dist/src/services/smart-money-service.js.map +1 -0
- package/dist/src/services/swap-service.d.ts +217 -0
- package/dist/src/services/swap-service.d.ts.map +1 -0
- package/dist/src/services/swap-service.js +695 -0
- package/dist/src/services/swap-service.js.map +1 -0
- package/dist/src/services/trading-service.d.ts +177 -0
- package/dist/src/services/trading-service.d.ts.map +1 -0
- package/dist/src/services/trading-service.js +422 -0
- package/dist/src/services/trading-service.js.map +1 -0
- package/dist/src/services/wallet-service.d.ts +316 -0
- package/dist/src/services/wallet-service.d.ts.map +1 -0
- package/dist/src/services/wallet-service.js +681 -0
- package/dist/src/services/wallet-service.js.map +1 -0
- package/dist/src/utils/price-utils.d.ts +153 -0
- package/dist/src/utils/price-utils.d.ts.map +1 -0
- package/dist/src/utils/price-utils.js +236 -0
- package/dist/src/utils/price-utils.js.map +1 -0
- package/dist/src/utils/price-utils.test.d.ts +5 -0
- package/dist/src/utils/price-utils.test.d.ts.map +1 -0
- package/dist/src/utils/price-utils.test.js +192 -0
- package/dist/src/utils/price-utils.test.js.map +1 -0
- package/dist/utils/price-utils.test.d.ts +5 -0
- package/dist/utils/price-utils.test.d.ts.map +1 -0
- package/dist/utils/price-utils.test.js +192 -0
- package/dist/utils/price-utils.test.js.map +1 -0
- package/package.json +6 -5
- package/README.en.md +0 -502
package/README.md
CHANGED
|
@@ -1,320 +1,292 @@
|
|
|
1
1
|
# @catalyst-team/poly-sdk
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@catalyst-team/poly-sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
Unified SDK for Polymarket
|
|
6
|
+
**Unified TypeScript SDK for Polymarket** - Trading, market data, smart money analysis, and on-chain operations.
|
|
7
7
|
|
|
8
8
|
**Builder**: [@hhhx402](https://x.com/hhhx402) | **Project**: [Catalyst.fun](https://x.com/catalystdotfun)
|
|
9
9
|
|
|
10
|
+
[中文文档](README.zh-CN.md)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Installation](#installation)
|
|
18
|
+
- [Architecture](#architecture)
|
|
19
|
+
- [Quick Start](#quick-start)
|
|
20
|
+
- [Services Guide](#services-guide)
|
|
21
|
+
- [PolymarketSDK (Entry Point)](#polymarketsdk-entry-point)
|
|
22
|
+
- [TradingService](#tradingservice)
|
|
23
|
+
- [MarketService](#marketservice)
|
|
24
|
+
- [OnchainService](#onchainservice)
|
|
25
|
+
- [RealtimeServiceV2](#realtimeservicev2)
|
|
26
|
+
- [WalletService](#walletservice)
|
|
27
|
+
- [SmartMoneyService](#smartmoneyservice)
|
|
28
|
+
- [ArbitrageService](#arbitrageservice)
|
|
29
|
+
- [DipArbService](#diparbservice)
|
|
30
|
+
- [Low-Level Clients](#low-level-clients)
|
|
31
|
+
- [Breaking Changes (v0.3.0)](#breaking-changes-v030)
|
|
32
|
+
- [Examples](#examples)
|
|
33
|
+
- [API Reference](#api-reference)
|
|
34
|
+
- [License](#license)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Overview
|
|
39
|
+
|
|
40
|
+
`@catalyst-team/poly-sdk` is a comprehensive TypeScript SDK that provides:
|
|
41
|
+
|
|
42
|
+
- **Trading** - Place limit/market orders (GTC, GTD, FOK, FAK)
|
|
43
|
+
- **Market Data** - Real-time prices, orderbooks, K-lines, historical trades
|
|
44
|
+
- **Smart Money Analysis** - Track top traders, calculate smart scores, follow wallet strategies
|
|
45
|
+
- **On-chain Operations** - CTF (split/merge/redeem), approvals, DEX swaps
|
|
46
|
+
- **Arbitrage Detection** - Real-time arbitrage scanning and execution
|
|
47
|
+
- **WebSocket Streaming** - Live price feeds and orderbook updates
|
|
48
|
+
|
|
49
|
+
### Key Features
|
|
50
|
+
|
|
51
|
+
| Feature | Description |
|
|
52
|
+
|---------|-------------|
|
|
53
|
+
| **Unified API** | Single SDK for all Polymarket APIs |
|
|
54
|
+
| **Type Safety** | Full TypeScript support with comprehensive types |
|
|
55
|
+
| **Rate Limiting** | Built-in rate limiting per API endpoint |
|
|
56
|
+
| **Caching** | TTL-based caching with pluggable adapters |
|
|
57
|
+
| **Error Handling** | Structured errors with auto-retry |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
10
61
|
## Installation
|
|
11
62
|
|
|
12
63
|
```bash
|
|
13
64
|
pnpm add @catalyst-team/poly-sdk
|
|
14
|
-
```
|
|
15
65
|
|
|
16
|
-
|
|
66
|
+
# or
|
|
67
|
+
npm install @catalyst-team/poly-sdk
|
|
17
68
|
|
|
18
|
-
|
|
19
|
-
|
|
69
|
+
# or
|
|
70
|
+
yarn add @catalyst-team/poly-sdk
|
|
71
|
+
```
|
|
20
72
|
|
|
21
|
-
|
|
73
|
+
---
|
|
22
74
|
|
|
23
|
-
|
|
24
|
-
const market = await sdk.getMarket('will-trump-win-2024');
|
|
25
|
-
console.log(market.tokens.yes.price); // 0.65
|
|
75
|
+
## Architecture
|
|
26
76
|
|
|
27
|
-
|
|
28
|
-
const orderbook = await sdk.getOrderbook(market.conditionId);
|
|
29
|
-
console.log(orderbook.summary.longArbProfit); // Arbitrage opportunity
|
|
77
|
+
The SDK is organized into three layers:
|
|
30
78
|
|
|
31
|
-
// Detect arbitrage
|
|
32
|
-
const arb = await sdk.detectArbitrage(market.conditionId);
|
|
33
|
-
if (arb) {
|
|
34
|
-
console.log(`${arb.type} arb: ${arb.profit * 100}% profit`);
|
|
35
|
-
}
|
|
36
79
|
```
|
|
80
|
+
poly-sdk Architecture
|
|
81
|
+
================================================================================
|
|
37
82
|
|
|
38
|
-
## Architecture
|
|
39
|
-
|
|
40
|
-
```
|
|
41
83
|
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
42
|
-
│
|
|
84
|
+
│ PolymarketSDK │
|
|
85
|
+
│ (Entry Point) │
|
|
43
86
|
├──────────────────────────────────────────────────────────────────────────────┤
|
|
44
|
-
│
|
|
45
|
-
│
|
|
46
|
-
│ │
|
|
47
|
-
│
|
|
48
|
-
│ │
|
|
49
|
-
│
|
|
50
|
-
│
|
|
51
|
-
│ │
|
|
52
|
-
│
|
|
53
|
-
│
|
|
54
|
-
│
|
|
55
|
-
│
|
|
87
|
+
│ │
|
|
88
|
+
│ Layer 3: High-Level Services (Recommended) │
|
|
89
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
90
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
91
|
+
│ │ TradingService │ │ MarketService │ │ OnchainService │ │
|
|
92
|
+
│ │ ────────────── │ │ ────────────── │ │ ────────────── │ │
|
|
93
|
+
│ │ • Limit orders │ │ • K-lines │ │ • Split/Merge │ │
|
|
94
|
+
│ │ • Market orders│ │ • Orderbook │ │ • Redeem │ │
|
|
95
|
+
│ │ • Order mgmt │ │ • Price history│ │ • Approvals │ │
|
|
96
|
+
│ │ • Rewards │ │ • Arbitrage │ │ • Swaps │ │
|
|
97
|
+
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
98
|
+
│ │
|
|
99
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
100
|
+
│ │RealtimeServiceV2│ │ WalletService │ │SmartMoneyService│ │
|
|
101
|
+
│ │ ────────────── │ │ ────────────── │ │ ────────────── │ │
|
|
102
|
+
│ │ • WebSocket │ │ • Profiles │ │ • Top traders │ │
|
|
103
|
+
│ │ • Price feeds │ │ • Smart scores │ │ • Copy trading │ │
|
|
104
|
+
│ │ • Book updates │ │ • Sell detect │ │ • Signal detect │ │
|
|
105
|
+
│ │ • User events │ │ • PnL calc │ │ • Leaderboard │ │
|
|
106
|
+
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
107
|
+
│ │
|
|
108
|
+
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
|
109
|
+
│ │ ArbitrageService │ │
|
|
110
|
+
│ │ ───────────────────────────────────────────────────────────────────── │ │
|
|
111
|
+
│ │ • Market scanning • Auto execution • Rebalancer • Smart clearing │ │
|
|
112
|
+
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
|
113
|
+
│ │
|
|
114
|
+
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
|
115
|
+
│ │ DipArbService │ │
|
|
116
|
+
│ │ ───────────────────────────────────────────────────────────────────── │ │
|
|
117
|
+
│ │ • 15m crypto UP/DOWN • Dip detection • Auto-rotate • Background redeem│
|
|
118
|
+
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
|
119
|
+
│ │
|
|
56
120
|
├──────────────────────────────────────────────────────────────────────────────┤
|
|
57
|
-
│
|
|
58
|
-
│
|
|
59
|
-
│ │
|
|
60
|
-
│
|
|
61
|
-
│ │
|
|
62
|
-
│
|
|
63
|
-
│
|
|
64
|
-
│ │
|
|
65
|
-
│ │
|
|
66
|
-
│
|
|
121
|
+
│ │
|
|
122
|
+
│ Layer 2: Low-Level Clients (Advanced Users / Raw API Access) │
|
|
123
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
124
|
+
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
125
|
+
│ │GammaApiClnt│ │DataApiClnt │ │SubgraphClnt│ │ CTFClient │ │BridgeClient│ │
|
|
126
|
+
│ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │
|
|
127
|
+
│ │ • Markets │ │ • Positions│ │ • On-chain │ │ • Split │ │ • Cross- │ │
|
|
128
|
+
│ │ • Events │ │ • Trades │ │ • PnL │ │ • Merge │ │ chain │ │
|
|
129
|
+
│ │ • Search │ │ • Activity │ │ • OI │ │ • Redeem │ │ • Deposits │ │
|
|
130
|
+
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
|
|
131
|
+
│ │
|
|
132
|
+
│ Uses Official Polymarket Clients: │
|
|
133
|
+
│ • @polymarket/clob-client - Trading, orderbook, market data │
|
|
134
|
+
│ • @polymarket/real-time-data-client - WebSocket real-time updates │
|
|
135
|
+
│ │
|
|
67
136
|
├──────────────────────────────────────────────────────────────────────────────┤
|
|
68
|
-
│
|
|
69
|
-
│
|
|
70
|
-
│ │
|
|
71
|
-
│
|
|
72
|
-
│
|
|
137
|
+
│ │
|
|
138
|
+
│ Layer 1: Core Infrastructure │
|
|
139
|
+
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
140
|
+
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
141
|
+
│ │RateLimiter │ │ Cache │ │ Errors │ │ Types │ │Price Utils │ │
|
|
142
|
+
│ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │
|
|
143
|
+
│ │ • Per-API │ │ • TTL-based│ │ • Retry │ │ • Unified │ │ • Arb calc │ │
|
|
144
|
+
│ │ • Bottleneck│ │ • Pluggable│ │ • Codes │ │ • K-lines │ │ • Rounding │ │
|
|
145
|
+
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
|
|
146
|
+
│ │
|
|
73
147
|
└──────────────────────────────────────────────────────────────────────────────┘
|
|
74
148
|
```
|
|
75
149
|
|
|
76
|
-
|
|
150
|
+
### Service Responsibilities
|
|
77
151
|
|
|
78
|
-
|
|
152
|
+
| Service | Responsibility |
|
|
153
|
+
|---------|---------------|
|
|
154
|
+
| **PolymarketSDK** | Entry point, integrates all services |
|
|
155
|
+
| **TradingService** | Order management (place/cancel/query) |
|
|
156
|
+
| **MarketService** | Market data (orderbook/K-lines/search) |
|
|
157
|
+
| **OnchainService** | On-chain ops (split/merge/redeem/approve/swap) |
|
|
158
|
+
| **RealtimeServiceV2** | WebSocket real-time data |
|
|
159
|
+
| **WalletService** | Wallet/trader analysis |
|
|
160
|
+
| **SmartMoneyService** | Smart money tracking |
|
|
161
|
+
| **ArbitrageService** | Arbitrage detection & execution |
|
|
162
|
+
| **DipArbService** | Dip arbitrage for 15m crypto markets |
|
|
79
163
|
|
|
80
|
-
|
|
81
|
-
// Get wallet positions
|
|
82
|
-
const positions = await sdk.dataApi.getPositions('0x...');
|
|
83
|
-
|
|
84
|
-
// Get recent trades
|
|
85
|
-
const trades = await sdk.dataApi.getTrades('0x...');
|
|
164
|
+
---
|
|
86
165
|
|
|
87
|
-
|
|
88
|
-
const leaderboard = await sdk.dataApi.getLeaderboard();
|
|
89
|
-
```
|
|
166
|
+
## Quick Start
|
|
90
167
|
|
|
91
|
-
###
|
|
168
|
+
### Basic Usage (Read-Only)
|
|
92
169
|
|
|
93
170
|
```typescript
|
|
94
|
-
|
|
95
|
-
const markets = await sdk.gammaApi.searchMarkets({ query: 'bitcoin' });
|
|
96
|
-
|
|
97
|
-
// Get trending markets
|
|
98
|
-
const trending = await sdk.gammaApi.getTrendingMarkets(10);
|
|
99
|
-
|
|
100
|
-
// Get events
|
|
101
|
-
const events = await sdk.gammaApi.getEvents({ limit: 20 });
|
|
102
|
-
```
|
|
171
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
103
172
|
|
|
104
|
-
|
|
173
|
+
// No authentication needed for read operations
|
|
174
|
+
const sdk = new PolymarketSDK();
|
|
105
175
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
176
|
+
// Get market by slug or condition ID
|
|
177
|
+
const market = await sdk.getMarket('will-trump-win-2024');
|
|
178
|
+
console.log(`${market.question}`);
|
|
179
|
+
console.log(`YES: ${market.tokens.find(t => t.outcome === 'Yes')?.price}`);
|
|
180
|
+
console.log(`NO: ${market.tokens.find(t => t.outcome === 'No')?.price}`);
|
|
109
181
|
|
|
110
182
|
// Get processed orderbook with analytics
|
|
111
|
-
const
|
|
112
|
-
console.log(
|
|
113
|
-
console.log(
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## Services
|
|
117
|
-
|
|
118
|
-
### WalletService - Smart Money Analysis
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// Get top traders
|
|
122
|
-
const traders = await sdk.wallets.getTopTraders(10);
|
|
123
|
-
|
|
124
|
-
// Get wallet profile with smart score
|
|
125
|
-
const profile = await sdk.wallets.getWalletProfile('0x...');
|
|
126
|
-
console.log(profile.smartScore); // 0-100
|
|
183
|
+
const orderbook = await sdk.getOrderbook(market.conditionId);
|
|
184
|
+
console.log(`Long Arb Profit: ${orderbook.summary.longArbProfit}`);
|
|
185
|
+
console.log(`Short Arb Profit: ${orderbook.summary.shortArbProfit}`);
|
|
127
186
|
|
|
128
|
-
// Detect
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
);
|
|
134
|
-
if (sellResult.isSelling) {
|
|
135
|
-
console.log(`Sold ${sellResult.percentageSold}%`);
|
|
187
|
+
// Detect arbitrage opportunities
|
|
188
|
+
const arb = await sdk.detectArbitrage(market.conditionId);
|
|
189
|
+
if (arb) {
|
|
190
|
+
console.log(`${arb.type.toUpperCase()} ARB: ${(arb.profit * 100).toFixed(2)}% profit`);
|
|
191
|
+
console.log(arb.action);
|
|
136
192
|
}
|
|
137
|
-
|
|
138
|
-
// Track group sell ratio
|
|
139
|
-
const groupSell = await sdk.wallets.trackGroupSellRatio(
|
|
140
|
-
['0x...', '0x...'],
|
|
141
|
-
conditionId,
|
|
142
|
-
peakValue,
|
|
143
|
-
sinceTimestamp
|
|
144
|
-
);
|
|
145
193
|
```
|
|
146
194
|
|
|
147
|
-
###
|
|
195
|
+
### With Authentication (Trading)
|
|
148
196
|
|
|
149
197
|
```typescript
|
|
150
|
-
|
|
151
|
-
const klines = await sdk.markets.getKLines(conditionId, '1h', { limit: 100 });
|
|
152
|
-
|
|
153
|
-
// Get dual K-Lines (YES + NO) with spread analysis
|
|
154
|
-
const dual = await sdk.markets.getDualKLines(conditionId, '1h');
|
|
155
|
-
console.log(dual.yes); // YES token candles
|
|
156
|
-
console.log(dual.no); // NO token candles
|
|
157
|
-
|
|
158
|
-
// Historical spread (from trade close prices) - for backtesting
|
|
159
|
-
console.log(dual.spreadAnalysis); // SpreadDataPoint[]
|
|
160
|
-
for (const point of dual.spreadAnalysis) {
|
|
161
|
-
console.log(`${point.timestamp}: priceSum=${point.priceSum}, spread=${point.priceSpread}`);
|
|
162
|
-
if (point.arbOpportunity) {
|
|
163
|
-
console.log(` Historical ${point.arbOpportunity} signal`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
198
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
166
199
|
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (rt.arbOpportunity) {
|
|
173
|
-
console.log(`🎯 ${rt.arbOpportunity} ARB: ${rt.arbProfitPercent.toFixed(2)}% profit`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
200
|
+
// Recommended: Use static factory method (one line to get started)
|
|
201
|
+
const sdk = await PolymarketSDK.create({
|
|
202
|
+
privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
|
|
203
|
+
});
|
|
204
|
+
// Ready to trade - SDK is initialized and WebSocket connected
|
|
176
205
|
|
|
177
|
-
//
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
206
|
+
// Place a limit order
|
|
207
|
+
const order = await sdk.tradingService.createLimitOrder({
|
|
208
|
+
tokenId: yesTokenId,
|
|
209
|
+
side: 'BUY',
|
|
210
|
+
price: 0.45,
|
|
211
|
+
size: 10,
|
|
212
|
+
orderType: 'GTC',
|
|
213
|
+
});
|
|
214
|
+
console.log(`Order placed: ${order.id}`);
|
|
182
215
|
|
|
183
|
-
//
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
console.log(`${signal.type}: ${signal.severity}`);
|
|
187
|
-
}
|
|
216
|
+
// Get open orders
|
|
217
|
+
const openOrders = await sdk.tradingService.getOpenOrders();
|
|
218
|
+
console.log(`Open orders: ${openOrders.length}`);
|
|
188
219
|
|
|
189
|
-
//
|
|
190
|
-
|
|
220
|
+
// Clean up when done
|
|
221
|
+
sdk.stop();
|
|
191
222
|
```
|
|
192
223
|
|
|
193
|
-
|
|
224
|
+
---
|
|
194
225
|
|
|
195
|
-
|
|
226
|
+
## Services Guide
|
|
196
227
|
|
|
197
|
-
|
|
228
|
+
### PolymarketSDK (Entry Point)
|
|
198
229
|
|
|
199
|
-
|
|
200
|
-
买 YES @ P = 卖 NO @ (1-P)
|
|
201
|
-
```
|
|
230
|
+
The main SDK class that integrates all services.
|
|
202
231
|
|
|
203
|
-
这意味着**同一订单会在两个订单簿中出现**。例如,一个 "Sell NO @ 0.50" 订单
|
|
204
|
-
会同时作为 "Buy YES @ 0.50" 出现在 YES 订单簿中。
|
|
205
|
-
|
|
206
|
-
**常见误解:**
|
|
207
232
|
```typescript
|
|
208
|
-
|
|
209
|
-
const askSum = YES.ask + NO.ask; // ≈ 1.998-1.999,而非 ≈ 1.0
|
|
210
|
-
const bidSum = YES.bid + NO.bid; // ≈ 0.001-0.002,而非 ≈ 1.0
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**正确做法:使用有效价格 (Effective Prices)**
|
|
214
|
-
```typescript
|
|
215
|
-
import { getEffectivePrices, checkArbitrage } from '@catalyst-team/poly-sdk';
|
|
216
|
-
|
|
217
|
-
// 计算考虑镜像后的最优价格
|
|
218
|
-
const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
|
|
233
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
219
234
|
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
235
|
+
// ===== Method 1: Static Factory (Recommended) =====
|
|
236
|
+
// One line: new + initialize + connect + waitForConnection
|
|
237
|
+
const sdk = await PolymarketSDK.create({
|
|
238
|
+
privateKey: '0x...', // Optional: for trading
|
|
239
|
+
chainId: 137, // Optional: Polygon mainnet (default)
|
|
240
|
+
});
|
|
224
241
|
|
|
225
|
-
//
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
|
|
229
|
-
console.log(arb.description);
|
|
230
|
-
}
|
|
231
|
-
```
|
|
242
|
+
// ===== Method 2: Using start() =====
|
|
243
|
+
// const sdk = new PolymarketSDK({ privateKey: '0x...' });
|
|
244
|
+
// await sdk.start(); // initialize + connect + waitForConnection
|
|
232
245
|
|
|
233
|
-
|
|
246
|
+
// ===== Method 3: Manual Step-by-Step (Full Control) =====
|
|
247
|
+
// const sdk = new PolymarketSDK({ privateKey: '0x...' });
|
|
248
|
+
// await sdk.initialize(); // Initialize trading service
|
|
249
|
+
// sdk.connect(); // Connect WebSocket
|
|
250
|
+
// await sdk.waitForConnection(); // Wait for connection
|
|
234
251
|
|
|
235
|
-
|
|
252
|
+
// Access services
|
|
253
|
+
sdk.tradingService // Trading operations
|
|
254
|
+
sdk.markets // Market data
|
|
255
|
+
sdk.wallets // Wallet analysis
|
|
256
|
+
sdk.realtime // WebSocket real-time data
|
|
257
|
+
sdk.smartMoney // Smart money tracking & copy trading
|
|
258
|
+
sdk.dipArb // Dip arbitrage for 15m crypto markets
|
|
259
|
+
sdk.dataApi // Direct Data API access
|
|
260
|
+
sdk.gammaApi // Direct Gamma API access
|
|
261
|
+
sdk.subgraph // On-chain data via Goldsky
|
|
236
262
|
|
|
237
|
-
|
|
263
|
+
// Convenience methods
|
|
264
|
+
await sdk.getMarket(identifier); // Get unified market
|
|
265
|
+
await sdk.getOrderbook(conditionId); // Get processed orderbook
|
|
266
|
+
await sdk.detectArbitrage(conditionId); // Detect arb opportunity
|
|
238
267
|
|
|
268
|
+
// Clean up
|
|
269
|
+
sdk.stop(); // Disconnect all services
|
|
239
270
|
```
|
|
240
|
-
┌─────────────────────────────────────────────────────────────────────────┐
|
|
241
|
-
│ spreadAnalysis (历史分析) │ realtimeSpread (实时分析) │
|
|
242
|
-
├─────────────────────────────────────────────────────────────────────────┤
|
|
243
|
-
│ 数据源: 成交记录的收盘价 │ 数据源: 订单簿的最优 bid/ask │
|
|
244
|
-
│ YES_close + NO_close │ 使用有效价格 (考虑镜像订单) │
|
|
245
|
-
├─────────────────────────────────────────────────────────────────────────┤
|
|
246
|
-
│ ✅ 可构建历史曲线 │ ❌ 无法构建历史曲线* │
|
|
247
|
-
│ ✅ Polymarket 保留成交历史 │ ❌ Polymarket 不保留盘口历史 │
|
|
248
|
-
│ ✅ 适合回测、模式识别 │ ✅ 适合实盘交易、套利执行 │
|
|
249
|
-
│ ⚠️ 套利信号仅供参考 │ ✅ 套利利润计算准确 │
|
|
250
|
-
└─────────────────────────────────────────────────────────────────────────┘
|
|
251
|
-
|
|
252
|
-
* 如需构建实时 Spread 的历史曲线,必须自行存储盘口快照数据
|
|
253
|
-
参考: apps/api/src/services/spread-sampler.ts
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
**核心区别:**
|
|
257
271
|
|
|
258
|
-
|
|
259
|
-
- 成交价 (close): 过去某时刻实际成交的价格
|
|
260
|
-
- 盘口价 (bid/ask): 当前市场上的最优挂单价格
|
|
261
|
-
- 例: YES 最后成交 0.52,但当前 bid=0.50, ask=0.54
|
|
272
|
+
---
|
|
262
273
|
|
|
263
|
-
|
|
264
|
-
- 同一订单在 YES 和 NO 订单簿中都有镜像
|
|
265
|
-
- 简单的 `YES.ask + NO.ask` 会重复计算
|
|
266
|
-
- 必须用 `min(YES.ask, 1-NO.bid)` 等公式消除重复
|
|
274
|
+
### TradingService
|
|
267
275
|
|
|
268
|
-
|
|
269
|
-
- Polymarket CLOB API 不保存历史盘口数据
|
|
270
|
-
- 只有成交记录 (trades) 有历史
|
|
271
|
-
- 除非你自己运行 spread-sampler 持续采样盘口
|
|
276
|
+
Order management using `@polymarket/clob-client`.
|
|
272
277
|
|
|
273
278
|
```typescript
|
|
274
|
-
|
|
275
|
-
interface SpreadDataPoint {
|
|
276
|
-
timestamp: number;
|
|
277
|
-
yesPrice: number; // YES 收盘价 (来自成交记录)
|
|
278
|
-
noPrice: number; // NO 收盘价
|
|
279
|
-
priceSum: number; // YES + NO
|
|
280
|
-
priceSpread: number; // priceSum - 1 (偏离均衡程度)
|
|
281
|
-
arbOpportunity: 'LONG' | 'SHORT' | ''; // 参考信号
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// ProcessedOrderbook.summary (实时分析 - 使用有效价格)
|
|
285
|
-
interface OrderbookSummary {
|
|
286
|
-
// 有效价格 (考虑镜像订单)
|
|
287
|
-
effectivePrices: {
|
|
288
|
-
effectiveBuyYes: number; // min(YES.ask, 1 - NO.bid)
|
|
289
|
-
effectiveBuyNo: number; // min(NO.ask, 1 - YES.bid)
|
|
290
|
-
effectiveSellYes: number; // max(YES.bid, 1 - NO.ask)
|
|
291
|
-
effectiveSellNo: number; // max(NO.bid, 1 - YES.ask)
|
|
292
|
-
};
|
|
293
|
-
// 套利成本/收入
|
|
294
|
-
effectiveLongCost: number; // effectiveBuyYes + effectiveBuyNo
|
|
295
|
-
effectiveShortRevenue: number; // effectiveSellYes + effectiveSellNo
|
|
296
|
-
// 套利利润
|
|
297
|
-
longArbProfit: number; // 1 - effectiveLongCost (> 0 可套利)
|
|
298
|
-
shortArbProfit: number; // effectiveShortRevenue - 1 (> 0 可套利)
|
|
299
|
-
yesSpread: number; // YES.ask - YES.bid (市场效率指标)
|
|
300
|
-
}
|
|
301
|
-
```
|
|
279
|
+
import { TradingService } from '@catalyst-team/poly-sdk';
|
|
302
280
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
import { TradingClient, RateLimiter } from '@catalyst-team/poly-sdk';
|
|
307
|
-
|
|
308
|
-
const rateLimiter = new RateLimiter();
|
|
309
|
-
const tradingClient = new TradingClient(rateLimiter, {
|
|
281
|
+
const trading = new TradingService(rateLimiter, cache, {
|
|
310
282
|
privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
|
|
311
283
|
});
|
|
284
|
+
await trading.initialize();
|
|
312
285
|
|
|
313
|
-
|
|
314
|
-
console.log(`Wallet: ${tradingClient.getAddress()}`);
|
|
286
|
+
// ===== Limit Orders =====
|
|
315
287
|
|
|
316
|
-
// GTC
|
|
317
|
-
const
|
|
288
|
+
// GTC: Good Till Cancelled
|
|
289
|
+
const gtcOrder = await trading.createLimitOrder({
|
|
318
290
|
tokenId: yesTokenId,
|
|
319
291
|
side: 'BUY',
|
|
320
292
|
price: 0.45,
|
|
@@ -322,8 +294,8 @@ const order = await tradingClient.createOrder({
|
|
|
322
294
|
orderType: 'GTC',
|
|
323
295
|
});
|
|
324
296
|
|
|
325
|
-
// GTD
|
|
326
|
-
const gtdOrder = await
|
|
297
|
+
// GTD: Good Till Date (expires at timestamp)
|
|
298
|
+
const gtdOrder = await trading.createLimitOrder({
|
|
327
299
|
tokenId: yesTokenId,
|
|
328
300
|
side: 'BUY',
|
|
329
301
|
price: 0.45,
|
|
@@ -332,406 +304,297 @@ const gtdOrder = await tradingClient.createOrder({
|
|
|
332
304
|
expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour
|
|
333
305
|
});
|
|
334
306
|
|
|
335
|
-
//
|
|
336
|
-
|
|
307
|
+
// ===== Market Orders =====
|
|
308
|
+
|
|
309
|
+
// FOK: Fill Or Kill (fill entirely or cancel)
|
|
310
|
+
const fokOrder = await trading.createMarketOrder({
|
|
337
311
|
tokenId: yesTokenId,
|
|
338
312
|
side: 'BUY',
|
|
339
313
|
amount: 10, // $10 USDC
|
|
340
314
|
orderType: 'FOK',
|
|
341
315
|
});
|
|
342
316
|
|
|
343
|
-
// FAK
|
|
344
|
-
const fakOrder = await
|
|
317
|
+
// FAK: Fill And Kill (partial fill ok)
|
|
318
|
+
const fakOrder = await trading.createMarketOrder({
|
|
345
319
|
tokenId: yesTokenId,
|
|
346
320
|
side: 'SELL',
|
|
347
321
|
amount: 10, // 10 shares
|
|
348
322
|
orderType: 'FAK',
|
|
349
323
|
});
|
|
350
324
|
|
|
351
|
-
// Order
|
|
352
|
-
const openOrders = await
|
|
353
|
-
await
|
|
354
|
-
await
|
|
325
|
+
// ===== Order Management =====
|
|
326
|
+
const openOrders = await trading.getOpenOrders();
|
|
327
|
+
await trading.cancelOrder(orderId);
|
|
328
|
+
await trading.cancelAllOrders();
|
|
355
329
|
|
|
356
|
-
//
|
|
357
|
-
const
|
|
330
|
+
// ===== Rewards (Market Making Incentives) =====
|
|
331
|
+
const isScoring = await trading.isOrderScoring(orderId);
|
|
332
|
+
const rewards = await trading.getCurrentRewards();
|
|
333
|
+
const earnings = await trading.getEarnings('2024-12-07');
|
|
358
334
|
```
|
|
359
335
|
|
|
360
|
-
|
|
336
|
+
---
|
|
361
337
|
|
|
362
|
-
|
|
363
|
-
// Check if your orders are earning rewards
|
|
364
|
-
const isScoring = await tradingClient.isOrderScoring(orderId);
|
|
365
|
-
|
|
366
|
-
// Get markets with active reward programs
|
|
367
|
-
const rewards = await tradingClient.getCurrentRewards();
|
|
368
|
-
for (const reward of rewards) {
|
|
369
|
-
console.log(`${reward.question}`);
|
|
370
|
-
console.log(` Max Spread: ${reward.rewardsMaxSpread}`);
|
|
371
|
-
console.log(` Min Size: ${reward.rewardsMinSize}`);
|
|
372
|
-
}
|
|
338
|
+
### MarketService
|
|
373
339
|
|
|
374
|
-
|
|
375
|
-
const earnings = await tradingClient.getTotalEarningsForDay('2024-12-07');
|
|
376
|
-
console.log(`Total earned: $${earnings.totalEarnings}`);
|
|
340
|
+
Market data, K-lines, orderbook analysis.
|
|
377
341
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
console.log(`USDC Balance: ${balance.balance}`);
|
|
381
|
-
```
|
|
342
|
+
```typescript
|
|
343
|
+
import { MarketService } from '@catalyst-team/poly-sdk';
|
|
382
344
|
|
|
383
|
-
|
|
345
|
+
// Get unified market
|
|
346
|
+
const market = await sdk.markets.getMarket('btc-100k-2024');
|
|
384
347
|
|
|
385
|
-
|
|
348
|
+
// Get K-Lines
|
|
349
|
+
const klines = await sdk.markets.getKLines(conditionId, '1h', { limit: 100 });
|
|
386
350
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
351
|
+
// Get dual K-Lines (YES + NO) with spread analysis
|
|
352
|
+
const dual = await sdk.markets.getDualKLines(conditionId, '1h');
|
|
353
|
+
console.log(dual.yes); // YES token candles
|
|
354
|
+
console.log(dual.no); // NO token candles
|
|
355
|
+
console.log(dual.spreadAnalysis); // Historical spread (trade prices)
|
|
356
|
+
console.log(dual.realtimeSpread); // Real-time spread (orderbook)
|
|
390
357
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
- **asks**: 升序排列 (最低价在前 = 最佳卖价)
|
|
358
|
+
// Get processed orderbook
|
|
359
|
+
const orderbook = await sdk.markets.getProcessedOrderbook(conditionId);
|
|
394
360
|
|
|
395
|
-
|
|
361
|
+
// Quick real-time spread check
|
|
362
|
+
const spread = await sdk.markets.getRealtimeSpread(conditionId);
|
|
363
|
+
if (spread.longArbProfit > 0.005) {
|
|
364
|
+
console.log(`Long arb: buy YES@${spread.yesAsk} + NO@${spread.noAsk}`);
|
|
365
|
+
}
|
|
396
366
|
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
const bestBid = book.bids[0]?.price; // ✅ 最高买价 (最佳 bid)
|
|
400
|
-
const bestAsk = book.asks[0]?.price; // ✅ 最低卖价 (最佳 ask)
|
|
401
|
-
|
|
402
|
-
// WebSocket 更新同样自动排序
|
|
403
|
-
wsManager.on('bookUpdate', (update) => {
|
|
404
|
-
const bestBid = update.bids[0]?.price; // ✅ 已排序
|
|
405
|
-
const bestAsk = update.asks[0]?.price; // ✅ 已排序
|
|
406
|
-
});
|
|
367
|
+
// Detect market signals
|
|
368
|
+
const signals = await sdk.markets.detectMarketSignals(conditionId);
|
|
407
369
|
```
|
|
408
370
|
|
|
409
|
-
|
|
410
|
-
import { WebSocketManager, RealtimeService } from '@catalyst-team/poly-sdk';
|
|
371
|
+
#### Understanding Polymarket Orderbook
|
|
411
372
|
|
|
412
|
-
|
|
413
|
-
const realtime = new RealtimeService(wsManager);
|
|
373
|
+
**Important**: Polymarket orderbooks have a mirror property:
|
|
414
374
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
console.log(`${update.assetId}: ${update.price}`);
|
|
419
|
-
},
|
|
420
|
-
onBookUpdate: (update) => {
|
|
421
|
-
console.log(`Best bid: ${update.bids[0]?.price}`);
|
|
422
|
-
},
|
|
423
|
-
onLastTrade: (trade) => {
|
|
424
|
-
console.log(`Trade: ${trade.side} ${trade.size} @ ${trade.price}`);
|
|
425
|
-
},
|
|
426
|
-
onPairUpdate: (update) => {
|
|
427
|
-
console.log(`YES + NO = ${update.spread}`);
|
|
428
|
-
if (update.spread < 0.99) console.log('ARB opportunity!');
|
|
429
|
-
},
|
|
430
|
-
});
|
|
375
|
+
```
|
|
376
|
+
Buy YES @ P = Sell NO @ (1-P)
|
|
377
|
+
```
|
|
431
378
|
|
|
432
|
-
|
|
433
|
-
const price = realtime.getPrice(yesTokenId);
|
|
379
|
+
This means the **same order appears in both orderbooks**. Simple addition causes double-counting:
|
|
434
380
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
381
|
+
```typescript
|
|
382
|
+
// WRONG: Double counts mirror orders
|
|
383
|
+
const askSum = YES.ask + NO.ask; // ~1.998, not ~1.0
|
|
438
384
|
|
|
439
|
-
|
|
385
|
+
// CORRECT: Use effective prices
|
|
386
|
+
import { getEffectivePrices, checkArbitrage } from '@catalyst-team/poly-sdk';
|
|
440
387
|
|
|
441
|
-
|
|
388
|
+
const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
|
|
389
|
+
// effective.effectiveBuyYes = min(YES.ask, 1 - NO.bid)
|
|
390
|
+
// effective.effectiveBuyNo = min(NO.ask, 1 - YES.bid)
|
|
442
391
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
│ 操作 │ 功能 │ 典型场景 │
|
|
448
|
-
├──────────────┼────────────────────────┼──────────────────────────────────────┤
|
|
449
|
-
│ Split │ USDC → YES + NO │ 市场做市:创建代币库存 │
|
|
450
|
-
│ Merge │ YES + NO → USDC │ 套利:买入双边后合并获利 │
|
|
451
|
-
│ Redeem │ 胜出代币 → USDC │ 结算:市场结束后兑换获胜代币 │
|
|
452
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
392
|
+
const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
|
|
393
|
+
if (arb) {
|
|
394
|
+
console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
|
|
395
|
+
}
|
|
453
396
|
```
|
|
454
397
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
### OnchainService
|
|
401
|
+
|
|
402
|
+
Unified interface for all on-chain operations: CTF + Approvals + Swaps.
|
|
459
403
|
|
|
460
404
|
```typescript
|
|
461
|
-
import {
|
|
405
|
+
import { OnchainService } from '@catalyst-team/poly-sdk';
|
|
462
406
|
|
|
463
|
-
const
|
|
407
|
+
const onchain = new OnchainService({
|
|
464
408
|
privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
|
|
465
409
|
rpcUrl: 'https://polygon-rpc.com', // optional
|
|
466
410
|
});
|
|
467
411
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
```typescript
|
|
475
|
-
// Split 100 USDC into 100 YES + 100 NO tokens
|
|
476
|
-
const splitResult = await ctf.split(conditionId, '100');
|
|
477
|
-
console.log(`TX: ${splitResult.txHash}`);
|
|
478
|
-
console.log(`Created ${splitResult.yesTokens} YES + ${splitResult.noTokens} NO`);
|
|
479
|
-
```
|
|
412
|
+
// Check if ready for CTF trading
|
|
413
|
+
const status = await onchain.checkReadyForCTF('100');
|
|
414
|
+
if (!status.ready) {
|
|
415
|
+
console.log('Issues:', status.issues);
|
|
416
|
+
await onchain.approveAll();
|
|
417
|
+
}
|
|
480
418
|
|
|
481
|
-
|
|
419
|
+
// ===== CTF Operations =====
|
|
482
420
|
|
|
483
|
-
|
|
421
|
+
// Split: USDC -> YES + NO tokens
|
|
422
|
+
const splitResult = await onchain.split(conditionId, '100');
|
|
484
423
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
| `mergeByTokenIds()` | **Polymarket CLOB 市场** | ✅ 推荐 |
|
|
488
|
-
| `merge()` | 标准 Gnosis CTF 市场 | ❌ Polymarket 慎用 |
|
|
424
|
+
// Merge: YES + NO -> USDC (for arbitrage)
|
|
425
|
+
const mergeResult = await onchain.mergeByTokenIds(conditionId, tokenIds, '100');
|
|
489
426
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const tokenIds = {
|
|
493
|
-
yesTokenId: market.tokens[0].tokenId, // 从 CLOB API 获取
|
|
494
|
-
noTokenId: market.tokens[1].tokenId,
|
|
495
|
-
};
|
|
496
|
-
const mergeResult = await ctf.mergeByTokenIds(conditionId, tokenIds, '100');
|
|
497
|
-
console.log(`TX: ${mergeResult.txHash}`);
|
|
498
|
-
console.log(`Received ${mergeResult.usdcReceived} USDC`);
|
|
499
|
-
|
|
500
|
-
// ⚠️ 标准 CTF 方法(可能无法正确检查 Polymarket 余额)
|
|
501
|
-
// const mergeResult = await ctf.merge(conditionId, '100');
|
|
502
|
-
```
|
|
427
|
+
// Redeem: Winning tokens -> USDC (after resolution)
|
|
428
|
+
const redeemResult = await onchain.redeemByTokenIds(conditionId, tokenIds);
|
|
503
429
|
|
|
504
|
-
|
|
430
|
+
// ===== DEX Swaps (QuickSwap V3) =====
|
|
505
431
|
|
|
506
|
-
|
|
432
|
+
// Swap MATIC to USDC.e (required for CTF)
|
|
433
|
+
await onchain.swap('MATIC', 'USDC_E', '50');
|
|
507
434
|
|
|
508
|
-
|
|
435
|
+
// Get balances
|
|
436
|
+
const balances = await onchain.getBalances();
|
|
437
|
+
console.log(`USDC.e: ${balances.usdcE}`);
|
|
438
|
+
```
|
|
509
439
|
|
|
510
|
-
|
|
511
|
-
|------|----------|---------------|
|
|
512
|
-
| `redeemByTokenIds()` | **Polymarket CLOB 市场** ✅ | CLOB API 返回的 tokenId |
|
|
513
|
-
| `redeem()` | 标准 Gnosis CTF 市场 | `keccak256(collectionId, conditionId, indexSet)` |
|
|
440
|
+
**Note**: Polymarket CTF requires **USDC.e** (0x2791...), not native USDC.
|
|
514
441
|
|
|
515
|
-
|
|
516
|
-
// ✅ 推荐:Polymarket 市场使用 redeemByTokenIds
|
|
517
|
-
const tokenIds = {
|
|
518
|
-
yesTokenId: '25064375110792967023484002819116042931016336431092144471807003884255851454283',
|
|
519
|
-
noTokenId: '98190367690492181203391990709979106077460946443309150166954079213761598385827',
|
|
520
|
-
};
|
|
521
|
-
const result = await ctf.redeemByTokenIds(conditionId, tokenIds);
|
|
522
|
-
console.log(`Redeemed ${result.tokensRedeemed} ${result.outcome} tokens`);
|
|
523
|
-
console.log(`Received ${result.usdcReceived} USDC`);
|
|
524
|
-
|
|
525
|
-
// ❌ 不要用于 Polymarket:redeem() 使用计算的 position ID
|
|
526
|
-
// const result = await ctf.redeem(conditionId); // 可能找不到余额
|
|
527
|
-
```
|
|
442
|
+
---
|
|
528
443
|
|
|
529
|
-
|
|
530
|
-
- Polymarket 在 CTF 之上包装了一层 ERC-1155 tokens
|
|
531
|
-
- CLOB API 返回的 `tokenId` (如 `"25064375..."`) 与标准 CTF 计算的 position ID 不同
|
|
532
|
-
- 必须使用 CLOB API 的 token ID 才能正确查询余额和 redeem
|
|
444
|
+
### RealtimeServiceV2
|
|
533
445
|
|
|
534
|
-
|
|
446
|
+
WebSocket real-time data using `@polymarket/real-time-data-client`.
|
|
535
447
|
|
|
536
448
|
```typescript
|
|
537
|
-
|
|
538
|
-
const balances = await ctf.getPositionBalance(conditionId);
|
|
539
|
-
console.log(`YES: ${balances.yesBalance}, NO: ${balances.noBalance}`);
|
|
540
|
-
|
|
541
|
-
// Check if market is resolved
|
|
542
|
-
const resolution = await ctf.getMarketResolution(conditionId);
|
|
543
|
-
if (resolution.isResolved) {
|
|
544
|
-
console.log(`Winner: ${resolution.winningOutcome}`);
|
|
545
|
-
}
|
|
449
|
+
import { RealtimeServiceV2 } from '@catalyst-team/poly-sdk';
|
|
546
450
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
451
|
+
const realtime = new RealtimeServiceV2({
|
|
452
|
+
autoReconnect: true,
|
|
453
|
+
pingInterval: 5000,
|
|
454
|
+
});
|
|
551
455
|
|
|
552
|
-
|
|
456
|
+
// Connect and subscribe
|
|
457
|
+
realtime.connect();
|
|
458
|
+
realtime.subscribeMarket([yesTokenId, noTokenId]);
|
|
553
459
|
|
|
554
|
-
|
|
460
|
+
// Event-based API
|
|
461
|
+
realtime.on('priceUpdate', (update) => {
|
|
462
|
+
console.log(`${update.assetId}: ${update.price}`);
|
|
463
|
+
console.log(`Midpoint: ${update.midpoint}, Spread: ${update.spread}`);
|
|
464
|
+
});
|
|
555
465
|
|
|
556
|
-
|
|
466
|
+
realtime.on('bookUpdate', (update) => {
|
|
467
|
+
// Orderbook is auto-normalized:
|
|
468
|
+
// bids: descending (best first), asks: ascending (best first)
|
|
469
|
+
console.log(`Best bid: ${update.bids[0]?.price}`);
|
|
470
|
+
console.log(`Best ask: ${update.asks[0]?.price}`);
|
|
471
|
+
});
|
|
557
472
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
│ 有效买入成本: │
|
|
562
|
-
│ effectiveBuyYes = min(YES.ask, 1 - NO.bid) │
|
|
563
|
-
│ effectiveBuyNo = min(NO.ask, 1 - YES.bid) │
|
|
564
|
-
│ 操作: │
|
|
565
|
-
│ 1. 用有效价格买入 YES + NO │
|
|
566
|
-
│ 2. CTF Merge → $1 USDC │
|
|
567
|
-
│ 3. Profit = 1 - effectiveLongCost │
|
|
568
|
-
├─────────────────────────────────────────────────────────────┤
|
|
569
|
-
│ SHORT ARB (effectiveShortRevenue > $1): │
|
|
570
|
-
│ 有效卖出收入: │
|
|
571
|
-
│ effectiveSellYes = max(YES.bid, 1 - NO.ask) │
|
|
572
|
-
│ effectiveSellNo = max(NO.bid, 1 - YES.ask) │
|
|
573
|
-
│ 操作: │
|
|
574
|
-
│ 1. CTF Split $1 → 1 YES + 1 NO │
|
|
575
|
-
│ 2. 用有效价格卖出 YES + NO │
|
|
576
|
-
│ 3. Profit = effectiveShortRevenue - 1 │
|
|
577
|
-
└─────────────────────────────────────────────────────────────┘
|
|
578
|
-
```
|
|
473
|
+
realtime.on('lastTrade', (trade) => {
|
|
474
|
+
console.log(`Trade: ${trade.side} ${trade.size} @ ${trade.price}`);
|
|
475
|
+
});
|
|
579
476
|
|
|
580
|
-
|
|
581
|
-
|
|
477
|
+
// Get cached prices
|
|
478
|
+
const price = realtime.getPrice(yesTokenId);
|
|
479
|
+
const book = realtime.getBook(yesTokenId);
|
|
582
480
|
|
|
583
|
-
//
|
|
584
|
-
|
|
585
|
-
if (arb?.type === 'long') {
|
|
586
|
-
console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
|
|
587
|
-
// Buy both tokens at effective prices, then merge
|
|
588
|
-
await tradingClient.createMarketOrder({ tokenId: yesTokenId, side: 'BUY', amount: 100 });
|
|
589
|
-
await tradingClient.createMarketOrder({ tokenId: noTokenId, side: 'BUY', amount: 100 });
|
|
590
|
-
await ctf.merge(conditionId, '100');
|
|
591
|
-
}
|
|
481
|
+
// Cleanup
|
|
482
|
+
realtime.disconnect();
|
|
592
483
|
```
|
|
593
484
|
|
|
594
|
-
|
|
485
|
+
---
|
|
595
486
|
|
|
596
|
-
|
|
487
|
+
### WalletService
|
|
597
488
|
|
|
598
|
-
|
|
599
|
-
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
600
|
-
│ 跨链充值流程 │
|
|
601
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
602
|
-
│ 1. 获取充值地址 → 2. 发送资产到地址 → 3. 自动桥接 → 4. USDC.e 到账 │
|
|
603
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
604
|
-
```
|
|
489
|
+
Wallet analysis and smart money scoring.
|
|
605
490
|
|
|
606
491
|
```typescript
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
SUPPORTED_CHAINS,
|
|
610
|
-
depositUsdc,
|
|
611
|
-
swapAndDeposit,
|
|
612
|
-
} from '@catalyst-team/poly-sdk';
|
|
492
|
+
// Get top traders
|
|
493
|
+
const traders = await sdk.wallets.getTopTraders(10);
|
|
613
494
|
|
|
614
|
-
// Get
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
console.log(`
|
|
618
|
-
console.log(`
|
|
619
|
-
console.log(`Bitcoin: ${addresses.address.btc}`);
|
|
620
|
-
|
|
621
|
-
// Get supported assets
|
|
622
|
-
const assets = await bridge.getSupportedAssets();
|
|
623
|
-
for (const asset of assets) {
|
|
624
|
-
console.log(`${asset.chainName} ${asset.tokenSymbol}: min ${asset.minDepositUsd} USD`);
|
|
625
|
-
}
|
|
495
|
+
// Get wallet profile with smart score
|
|
496
|
+
const profile = await sdk.wallets.getWalletProfile('0x...');
|
|
497
|
+
console.log(`Smart Score: ${profile.smartScore}/100`);
|
|
498
|
+
console.log(`Win Rate: ${profile.winRate}%`);
|
|
499
|
+
console.log(`Total PnL: $${profile.totalPnL}`);
|
|
626
500
|
|
|
627
|
-
//
|
|
628
|
-
const
|
|
629
|
-
|
|
501
|
+
// Detect sell activity (for follow-wallet strategy)
|
|
502
|
+
const sellResult = await sdk.wallets.detectSellActivity(
|
|
503
|
+
'0x...',
|
|
504
|
+
conditionId,
|
|
505
|
+
Date.now() - 24 * 60 * 60 * 1000 // since 24h ago
|
|
506
|
+
);
|
|
507
|
+
if (sellResult.isSelling) {
|
|
508
|
+
console.log(`Sold ${sellResult.percentageSold}%`);
|
|
509
|
+
}
|
|
630
510
|
|
|
631
|
-
//
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
511
|
+
// Track group sell ratio
|
|
512
|
+
const groupSell = await sdk.wallets.trackGroupSellRatio(
|
|
513
|
+
['0x...', '0x...'],
|
|
514
|
+
conditionId,
|
|
515
|
+
peakValue,
|
|
516
|
+
sinceTimestamp
|
|
517
|
+
);
|
|
638
518
|
```
|
|
639
519
|
|
|
640
|
-
|
|
520
|
+
---
|
|
641
521
|
|
|
642
|
-
|
|
522
|
+
### SmartMoneyService
|
|
643
523
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
| Token | Address | Polymarket CTF |
|
|
647
|
-
|-------|---------|----------------|
|
|
648
|
-
| USDC.e | `0x2791...` | ✅ **Required** |
|
|
649
|
-
| USDC (Native) | `0x3c49...` | ❌ Not accepted |
|
|
524
|
+
Smart money detection and **real-time auto copy trading**.
|
|
650
525
|
|
|
651
526
|
```typescript
|
|
652
|
-
import {
|
|
527
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
653
528
|
|
|
654
|
-
|
|
529
|
+
// One line to get started (recommended)
|
|
530
|
+
const sdk = await PolymarketSDK.create({ privateKey: '0x...' });
|
|
531
|
+
// SDK is initialized and WebSocket connected
|
|
655
532
|
|
|
656
|
-
//
|
|
657
|
-
const
|
|
658
|
-
for (const b of balances) {
|
|
659
|
-
console.log(`${b.symbol}: ${b.balance}`);
|
|
660
|
-
}
|
|
533
|
+
// Get smart money wallets
|
|
534
|
+
const wallets = await sdk.smartMoney.getSmartMoneyList(50);
|
|
661
535
|
|
|
662
|
-
//
|
|
663
|
-
const
|
|
664
|
-
console.log(`Swapped: ${swapResult.amountOut} USDC.e`);
|
|
536
|
+
// Check if address is smart money
|
|
537
|
+
const isSmartMoney = await sdk.smartMoney.isSmartMoney('0x...');
|
|
665
538
|
|
|
666
|
-
//
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
539
|
+
// Subscribe to smart money trades
|
|
540
|
+
const sub = sdk.smartMoney.subscribeSmartMoneyTrades(
|
|
541
|
+
(trade) => {
|
|
542
|
+
console.log(`${trade.traderName} ${trade.side} ${trade.outcome} @ $${trade.price}`);
|
|
543
|
+
},
|
|
544
|
+
{ filterAddresses: ['0x...'], minSize: 10 }
|
|
545
|
+
);
|
|
672
546
|
|
|
673
|
-
//
|
|
674
|
-
|
|
675
|
-
```
|
|
547
|
+
// ===== Auto Copy Trading =====
|
|
548
|
+
// Real-time copy trading - when smart money trades, copy immediately
|
|
676
549
|
|
|
677
|
-
|
|
550
|
+
const subscription = await sdk.smartMoney.startAutoCopyTrading({
|
|
551
|
+
// Target selection
|
|
552
|
+
topN: 50, // Follow top 50 traders from leaderboard
|
|
553
|
+
// targetAddresses: ['0x...'], // Or specify addresses directly
|
|
678
554
|
|
|
679
|
-
|
|
555
|
+
// Order settings
|
|
556
|
+
sizeScale: 0.1, // Copy 10% of their trade size
|
|
557
|
+
maxSizePerTrade: 10, // Max $10 per trade
|
|
558
|
+
maxSlippage: 0.03, // 3% slippage tolerance
|
|
559
|
+
orderType: 'FOK', // FOK or FAK
|
|
680
560
|
|
|
681
|
-
|
|
682
|
-
|
|
561
|
+
// Filters
|
|
562
|
+
minTradeSize: 5, // Only copy trades > $5
|
|
563
|
+
sideFilter: 'BUY', // Only copy BUY trades (optional)
|
|
683
564
|
|
|
684
|
-
|
|
565
|
+
// Testing
|
|
566
|
+
dryRun: true, // Set false for real trades
|
|
685
567
|
|
|
686
|
-
//
|
|
687
|
-
|
|
688
|
-
console.log(`
|
|
689
|
-
|
|
690
|
-
|
|
568
|
+
// Callbacks
|
|
569
|
+
onTrade: (trade, result) => {
|
|
570
|
+
console.log(`Copied ${trade.traderName}: ${result.success ? '✅' : '❌'}`);
|
|
571
|
+
},
|
|
572
|
+
onError: (error) => console.error(error),
|
|
573
|
+
});
|
|
691
574
|
|
|
692
|
-
|
|
693
|
-
console.log('Issues:', status.issues);
|
|
575
|
+
console.log(`Tracking ${subscription.targetAddresses.length} wallets`);
|
|
694
576
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
}
|
|
577
|
+
// Get stats
|
|
578
|
+
const stats = subscription.getStats();
|
|
579
|
+
console.log(`Detected: ${stats.tradesDetected}, Executed: ${stats.tradesExecuted}`);
|
|
699
580
|
|
|
700
|
-
//
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
}
|
|
581
|
+
// Stop
|
|
582
|
+
subscription.stop();
|
|
583
|
+
sdk.stop();
|
|
704
584
|
```
|
|
705
585
|
|
|
706
|
-
|
|
586
|
+
> **Note**: Polymarket minimum order size is **$1**. Orders below $1 will be automatically skipped.
|
|
707
587
|
|
|
708
|
-
|
|
588
|
+
📁 **Full examples**: See [scripts/smart-money/](scripts/smart-money/) for complete working scripts:
|
|
589
|
+
- `04-auto-copy-trading.ts` - Full-featured auto copy trading
|
|
590
|
+
- `05-auto-copy-simple.ts` - Simplified SDK usage
|
|
591
|
+
- `06-real-copy-test.ts` - Real trading test
|
|
709
592
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
714
|
-
│ • scanMarkets() - 扫描市场找套利机会 │
|
|
715
|
-
│ • start(market) - 启动实时监控 + 自动执行 │
|
|
716
|
-
│ • clearPositions() - 智能清仓 (活跃市场卖出, 已结算市场 redeem) │
|
|
717
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
718
|
-
│ 自动再平衡 (Rebalancer) │
|
|
719
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
720
|
-
│ 套利需要 USDC + YES/NO Token,Rebalancer 自动维持资金比例: │
|
|
721
|
-
│ • USDC 比例 < 20% → 自动 Merge (YES+NO → USDC) │
|
|
722
|
-
│ • USDC 比例 > 80% → 自动 Split (USDC → YES+NO) │
|
|
723
|
-
│ • 冷却机制:两次操作间隔 ≥ 30s,检测间隔 10s │
|
|
724
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
725
|
-
│ 执行安全 (Partial Fill Protection) │
|
|
726
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
727
|
-
│ 套利需要同时买入 YES 和 NO,但订单可能部分成交: │
|
|
728
|
-
│ • sizeSafetyFactor=0.8 → 只使用 80% 的盘口深度,降低滑点风险 │
|
|
729
|
-
│ • autoFixImbalance=true → 如果只成交一侧,自动卖出多余的 token │
|
|
730
|
-
│ • imbalanceThreshold=5 → YES-NO 差额超过 $5 时触发修复 │
|
|
731
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
732
|
-
```
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
### ArbitrageService
|
|
733
596
|
|
|
734
|
-
|
|
597
|
+
Real-time arbitrage detection, execution, and position management.
|
|
735
598
|
|
|
736
599
|
```typescript
|
|
737
600
|
import { ArbitrageService } from '@catalyst-team/poly-sdk';
|
|
@@ -741,20 +604,17 @@ const arbService = new ArbitrageService({
|
|
|
741
604
|
profitThreshold: 0.005, // 0.5% minimum profit
|
|
742
605
|
minTradeSize: 5, // $5 minimum
|
|
743
606
|
maxTradeSize: 100, // $100 maximum
|
|
744
|
-
autoExecute: true, //
|
|
745
|
-
|
|
746
|
-
// Rebalancer
|
|
747
|
-
enableRebalancer: true,
|
|
748
|
-
minUsdcRatio: 0.2, // Min 20% USDC
|
|
749
|
-
maxUsdcRatio: 0.8, // Max 80% USDC
|
|
750
|
-
targetUsdcRatio: 0.5, // Target
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
rebalanceCooldown: 30000, // Min 30s between actions
|
|
754
|
-
|
|
755
|
-
// Execution safety (prevents YES ≠ NO from partial fills)
|
|
607
|
+
autoExecute: true, // Auto-execute opportunities
|
|
608
|
+
|
|
609
|
+
// Rebalancer: auto-maintain USDC/token ratio
|
|
610
|
+
enableRebalancer: true,
|
|
611
|
+
minUsdcRatio: 0.2, // Min 20% USDC
|
|
612
|
+
maxUsdcRatio: 0.8, // Max 80% USDC
|
|
613
|
+
targetUsdcRatio: 0.5, // Target when rebalancing
|
|
614
|
+
|
|
615
|
+
// Execution safety
|
|
756
616
|
sizeSafetyFactor: 0.8, // Use 80% of orderbook depth
|
|
757
|
-
autoFixImbalance: true, // Auto-
|
|
617
|
+
autoFixImbalance: true, // Auto-fix partial fills
|
|
758
618
|
});
|
|
759
619
|
|
|
760
620
|
// Listen for events
|
|
@@ -764,320 +624,318 @@ arbService.on('opportunity', (opp) => {
|
|
|
764
624
|
|
|
765
625
|
arbService.on('execution', (result) => {
|
|
766
626
|
if (result.success) {
|
|
767
|
-
console.log(
|
|
627
|
+
console.log(`Executed: $${result.profit.toFixed(2)} profit`);
|
|
768
628
|
}
|
|
769
629
|
});
|
|
770
630
|
|
|
771
|
-
|
|
772
|
-
console.log(`🔄 Rebalance: ${result.action.type} ${result.action.amount}`);
|
|
773
|
-
});
|
|
631
|
+
// ===== Workflow =====
|
|
774
632
|
|
|
775
|
-
//
|
|
633
|
+
// 1. Scan markets for opportunities
|
|
776
634
|
const results = await arbService.scanMarkets({ minVolume24h: 5000 }, 0.005);
|
|
777
|
-
console.log(`Found ${results.filter(r => r.arbType !== 'none').length} opportunities`);
|
|
778
635
|
|
|
779
|
-
//
|
|
636
|
+
// 2. Start monitoring best market
|
|
780
637
|
const best = await arbService.findAndStart(0.005);
|
|
781
|
-
|
|
782
|
-
console.log('No arbitrage opportunities found');
|
|
783
|
-
process.exit(0);
|
|
784
|
-
}
|
|
785
|
-
console.log(`🎯 Started: ${best.market.name} (+${best.profitPercent.toFixed(2)}%)`);
|
|
638
|
+
console.log(`Started: ${best.market.name} (+${best.profitPercent.toFixed(2)}%)`);
|
|
786
639
|
|
|
787
|
-
//
|
|
788
|
-
//
|
|
789
|
-
// 运行一段时间后:
|
|
790
|
-
await new Promise(resolve => setTimeout(resolve, 60 * 60 * 1000)); // 1 hour
|
|
640
|
+
// 3. Run for a while...
|
|
641
|
+
await new Promise(r => setTimeout(r, 60 * 60 * 1000)); // 1 hour
|
|
791
642
|
|
|
792
|
-
//
|
|
643
|
+
// 4. Stop and clear positions
|
|
793
644
|
await arbService.stop();
|
|
794
|
-
console.log('Stats:', arbService.getStats());
|
|
795
|
-
|
|
796
|
-
// 智能清仓: 活跃市场 merge+sell, 已结算市场 redeem
|
|
797
645
|
const clearResult = await arbService.clearPositions(best.market, true);
|
|
798
|
-
console.log(
|
|
646
|
+
console.log(`Recovered: $${clearResult.totalUsdcRecovered.toFixed(2)}`);
|
|
799
647
|
```
|
|
800
648
|
|
|
801
|
-
|
|
649
|
+
---
|
|
802
650
|
|
|
803
|
-
|
|
804
|
-
// 如果不用 scanMarkets,可以手动构建 market config
|
|
805
|
-
const market = {
|
|
806
|
-
name: 'Will BTC reach $100k?',
|
|
807
|
-
conditionId: '0x...',
|
|
808
|
-
yesTokenId: '12345...',
|
|
809
|
-
noTokenId: '67890...',
|
|
810
|
-
outcomes: ['Yes', 'No'] as [string, string],
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
await arbService.start(market);
|
|
814
|
-
```
|
|
651
|
+
### DipArbService
|
|
815
652
|
|
|
816
|
-
|
|
653
|
+
**Dip Arbitrage** for Polymarket 15-minute crypto UP/DOWN markets (BTC, ETH, SOL, XRP).
|
|
817
654
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
655
|
+
**Strategy**: Detect sudden price dips → Buy dipped side (Leg1) → Wait for opposite to drop → Buy opposite (Leg2) → Lock profit (UP + DOWN = $1)
|
|
656
|
+
|
|
657
|
+
#### Quick Start
|
|
658
|
+
|
|
659
|
+
```bash
|
|
660
|
+
# One command to start auto trading
|
|
661
|
+
PRIVATE_KEY=0x... npx tsx scripts/dip-arb/auto-trade.ts
|
|
824
662
|
```
|
|
825
663
|
|
|
826
|
-
####
|
|
664
|
+
#### Features
|
|
665
|
+
|
|
666
|
+
| Feature | Description |
|
|
667
|
+
|---------|-------------|
|
|
668
|
+
| **Dip Detection** | Detects 15%+ price drops within 10s sliding window |
|
|
669
|
+
| **Two-Leg Execution** | Leg1 (buy dip) + Leg2 (buy opposite when cost < target) |
|
|
670
|
+
| **Auto-Rotate** | Automatically switches to next market when current ends |
|
|
671
|
+
| **Background Redeem** | Waits for Oracle resolution (~5min) then redeems winning positions |
|
|
672
|
+
| **WebSocket Reconnect** | Auto re-subscribes on disconnect |
|
|
673
|
+
|
|
674
|
+
#### Programmatic Usage
|
|
827
675
|
|
|
828
676
|
```typescript
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
677
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
678
|
+
|
|
679
|
+
const sdk = new PolymarketSDK({ privateKey: '0x...' });
|
|
680
|
+
|
|
681
|
+
// Configure strategy
|
|
682
|
+
sdk.dipArb.updateConfig({
|
|
683
|
+
shares: 10, // Shares per trade
|
|
684
|
+
sumTarget: 0.9, // Leg2 triggers when cost ≤ 0.9 (11% profit)
|
|
685
|
+
dipThreshold: 0.15, // 15% dip triggers Leg1
|
|
686
|
+
windowMinutes: 14, // Trade window after round start
|
|
687
|
+
autoExecute: true, // Auto-execute signals
|
|
833
688
|
});
|
|
834
689
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
console.log(
|
|
838
|
-
|
|
690
|
+
// Listen to events
|
|
691
|
+
sdk.dipArb.on('signal', (signal) => {
|
|
692
|
+
console.log(`${signal.type}: ${signal.side} @ ${signal.price}`);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
sdk.dipArb.on('execution', (result) => {
|
|
696
|
+
console.log(`${result.leg} ${result.success ? '✅' : '❌'}`);
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
sdk.dipArb.on('roundComplete', (result) => {
|
|
700
|
+
console.log(`Profit: $${result.profit?.toFixed(2)}`);
|
|
839
701
|
});
|
|
840
702
|
|
|
841
|
-
|
|
703
|
+
// Find and start monitoring
|
|
704
|
+
const market = await sdk.dipArb.findAndStart({
|
|
705
|
+
coin: 'ETH',
|
|
706
|
+
preferDuration: '15m',
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// Enable auto-rotate with redemption
|
|
710
|
+
sdk.dipArb.enableAutoRotate({
|
|
711
|
+
enabled: true,
|
|
712
|
+
underlyings: ['ETH'],
|
|
713
|
+
duration: '15m',
|
|
714
|
+
settleStrategy: 'redeem',
|
|
715
|
+
redeemWaitMinutes: 5,
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// Get stats
|
|
719
|
+
const stats = sdk.dipArb.getStats();
|
|
720
|
+
console.log(`Signals: ${stats.signalsDetected}, L1: ${stats.leg1Filled}, L2: ${stats.leg2Filled}`);
|
|
721
|
+
|
|
722
|
+
// Cleanup
|
|
723
|
+
await sdk.dipArb.stop();
|
|
724
|
+
sdk.stop();
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
#### Events
|
|
728
|
+
|
|
729
|
+
| Event | Data | Description |
|
|
730
|
+
|-------|------|-------------|
|
|
731
|
+
| `started` | `DipArbMarketConfig` | Started monitoring market |
|
|
732
|
+
| `stopped` | - | Stopped monitoring |
|
|
733
|
+
| `newRound` | `{ roundId, upOpen, downOpen }` | New trading round |
|
|
734
|
+
| `signal` | `DipArbSignalEvent` | Leg1/Leg2 signal detected |
|
|
735
|
+
| `execution` | `DipArbExecutionResult` | Trade execution result |
|
|
736
|
+
| `roundComplete` | `{ profit, profitRate }` | Round finished |
|
|
737
|
+
| `rotate` | `{ reason, newMarket }` | Switched to new market |
|
|
738
|
+
| `settled` | `{ success, amountReceived }` | Position redeemed |
|
|
739
|
+
|
|
740
|
+
#### Scripts
|
|
741
|
+
|
|
742
|
+
```bash
|
|
743
|
+
# Auto trading (monitors + trades)
|
|
744
|
+
PRIVATE_KEY=0x... npx tsx scripts/dip-arb/auto-trade.ts
|
|
745
|
+
|
|
746
|
+
# Redeem ended positions
|
|
747
|
+
PRIVATE_KEY=0x... npx tsx scripts/dip-arb/redeem-positions.ts
|
|
842
748
|
```
|
|
843
749
|
|
|
844
|
-
|
|
750
|
+
---
|
|
751
|
+
|
|
752
|
+
## Low-Level Clients
|
|
753
|
+
|
|
754
|
+
For advanced users who need direct API access:
|
|
845
755
|
|
|
846
756
|
```typescript
|
|
847
757
|
import {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
calculatePnL,
|
|
855
|
-
type TickSize,
|
|
758
|
+
DataApiClient, // Positions, trades, leaderboard
|
|
759
|
+
GammaApiClient, // Markets, events, search
|
|
760
|
+
SubgraphClient, // On-chain data via Goldsky
|
|
761
|
+
CTFClient, // CTF contract operations
|
|
762
|
+
BridgeClient, // Cross-chain deposits
|
|
763
|
+
SwapService, // DEX swaps on Polygon
|
|
856
764
|
} from '@catalyst-team/poly-sdk';
|
|
857
765
|
|
|
858
|
-
//
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
766
|
+
// Data API
|
|
767
|
+
const positions = await sdk.dataApi.getPositions('0x...');
|
|
768
|
+
const trades = await sdk.dataApi.getTrades('0x...');
|
|
769
|
+
const leaderboard = await sdk.dataApi.getLeaderboard();
|
|
862
770
|
|
|
863
|
-
//
|
|
864
|
-
const
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
}
|
|
771
|
+
// Gamma API
|
|
772
|
+
const markets = await sdk.gammaApi.searchMarkets({ query: 'bitcoin' });
|
|
773
|
+
const trending = await sdk.gammaApi.getTrendingMarkets(10);
|
|
774
|
+
const events = await sdk.gammaApi.getEvents({ limit: 20 });
|
|
868
775
|
|
|
869
|
-
//
|
|
870
|
-
const
|
|
871
|
-
|
|
776
|
+
// Subgraph (on-chain data)
|
|
777
|
+
const userPositions = await sdk.subgraph.getUserPositions(address);
|
|
778
|
+
const isResolved = await sdk.subgraph.isConditionResolved(conditionId);
|
|
779
|
+
const globalOI = await sdk.subgraph.getGlobalOpenInterest();
|
|
780
|
+
```
|
|
872
781
|
|
|
873
|
-
|
|
874
|
-
const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
|
|
875
|
-
console.log(`Effective buy YES: ${effective.effectiveBuyYes}`); // min(YES.ask, 1 - NO.bid)
|
|
876
|
-
console.log(`Effective buy NO: ${effective.effectiveBuyNo}`); // min(NO.ask, 1 - YES.bid)
|
|
782
|
+
---
|
|
877
783
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
yesBid, noBid // Bid prices
|
|
882
|
-
);
|
|
883
|
-
if (arb) {
|
|
884
|
-
console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
|
|
885
|
-
console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
|
|
886
|
-
}
|
|
784
|
+
## Breaking Changes (v0.3.0)
|
|
785
|
+
|
|
786
|
+
### `UnifiedMarket.tokens` is now an Array
|
|
887
787
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
788
|
+
**Before (v0.2.x)**:
|
|
789
|
+
```typescript
|
|
790
|
+
// Object with yes/no properties
|
|
791
|
+
const yesPrice = market.tokens.yes.price;
|
|
792
|
+
const noPrice = market.tokens.no.price;
|
|
891
793
|
```
|
|
892
794
|
|
|
893
|
-
|
|
795
|
+
**After (v0.3.0)**:
|
|
796
|
+
```typescript
|
|
797
|
+
// Array of MarketToken objects
|
|
798
|
+
const yesToken = market.tokens.find(t => t.outcome === 'Yes');
|
|
799
|
+
const noToken = market.tokens.find(t => t.outcome === 'No');
|
|
894
800
|
|
|
895
|
-
|
|
801
|
+
const yesPrice = yesToken?.price;
|
|
802
|
+
const noPrice = noToken?.price;
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Migration Guide
|
|
896
806
|
|
|
897
807
|
```typescript
|
|
898
|
-
|
|
808
|
+
// Helper function for migration
|
|
809
|
+
function getTokenPrice(market: UnifiedMarket, outcome: 'Yes' | 'No'): number {
|
|
810
|
+
return market.tokens.find(t => t.outcome === outcome)?.price ?? 0;
|
|
811
|
+
}
|
|
899
812
|
|
|
900
|
-
|
|
901
|
-
const
|
|
813
|
+
// Usage
|
|
814
|
+
const yesPrice = getTokenPrice(market, 'Yes');
|
|
815
|
+
const noPrice = getTokenPrice(market, 'No');
|
|
902
816
|
```
|
|
903
817
|
|
|
904
|
-
|
|
818
|
+
**Why the change?** The array format better supports multi-outcome markets and is more consistent with the Polymarket API response format.
|
|
819
|
+
|
|
820
|
+
---
|
|
821
|
+
|
|
822
|
+
## Examples
|
|
823
|
+
|
|
824
|
+
Run examples with:
|
|
825
|
+
|
|
826
|
+
```bash
|
|
827
|
+
pnpm example:basic # Basic usage
|
|
828
|
+
pnpm example:smart-money # Smart money analysis
|
|
829
|
+
pnpm example:trading # Trading orders
|
|
830
|
+
pnpm example:realtime # WebSocket feeds
|
|
831
|
+
pnpm example:arb-service # Arbitrage service
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
| Example | Description |
|
|
835
|
+
|---------|-------------|
|
|
836
|
+
| [01-basic-usage.ts](examples/01-basic-usage.ts) | Get markets, orderbooks, detect arbitrage |
|
|
837
|
+
| [02-smart-money.ts](examples/02-smart-money.ts) | Top traders, wallet profiles, smart scores |
|
|
838
|
+
| [03-market-analysis.ts](examples/03-market-analysis.ts) | Market signals, volume analysis |
|
|
839
|
+
| [04-kline-aggregation.ts](examples/04-kline-aggregation.ts) | Build OHLCV candles from trades |
|
|
840
|
+
| [05-follow-wallet-strategy.ts](examples/05-follow-wallet-strategy.ts) | Track smart money, detect exits |
|
|
841
|
+
| [06-services-demo.ts](examples/06-services-demo.ts) | All SDK services in action |
|
|
842
|
+
| [07-realtime-websocket.ts](examples/07-realtime-websocket.ts) | Live price feeds, orderbook updates |
|
|
843
|
+
| [08-trading-orders.ts](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types |
|
|
844
|
+
| [09-rewards-tracking.ts](examples/09-rewards-tracking.ts) | Market maker incentives, earnings |
|
|
845
|
+
| [10-ctf-operations.ts](examples/10-ctf-operations.ts) | Split, merge, redeem tokens |
|
|
846
|
+
| [11-live-arbitrage-scan.ts](examples/11-live-arbitrage-scan.ts) | Scan markets for opportunities |
|
|
847
|
+
| [12-trending-arb-monitor.ts](examples/12-trending-arb-monitor.ts) | Real-time trending monitor |
|
|
848
|
+
| [13-arbitrage-service.ts](examples/13-arbitrage-service.ts) | Full arbitrage workflow |
|
|
849
|
+
| [14-dip-arb-service.ts](examples/14-dip-arb-service.ts) | Dip arbitrage for 15m crypto |
|
|
850
|
+
|
|
851
|
+
**DipArb Scripts** (in `scripts/dip-arb/`):
|
|
852
|
+
| Script | Description |
|
|
853
|
+
|--------|-------------|
|
|
854
|
+
| [auto-trade.ts](scripts/dip-arb/auto-trade.ts) | One-click auto trading with rotation |
|
|
855
|
+
| [redeem-positions.ts](scripts/dip-arb/redeem-positions.ts) | Redeem ended market positions |
|
|
856
|
+
|
|
857
|
+
---
|
|
858
|
+
|
|
859
|
+
## API Reference
|
|
860
|
+
|
|
861
|
+
For detailed API documentation, see:
|
|
862
|
+
|
|
863
|
+
- [docs/00-design.md](docs/00-design.md) - Architecture design
|
|
864
|
+
- [docs/02-API.md](docs/02-API.md) - Complete API reference
|
|
865
|
+
- [docs/01-polymarket-orderbook-arbitrage.md](docs/01-polymarket-orderbook-arbitrage.md) - Orderbook mirror & arbitrage
|
|
866
|
+
|
|
867
|
+
### Type Exports
|
|
905
868
|
|
|
906
869
|
```typescript
|
|
907
870
|
import type {
|
|
908
|
-
// Core
|
|
871
|
+
// Core types
|
|
909
872
|
UnifiedMarket,
|
|
910
|
-
|
|
911
|
-
BookUpdate,
|
|
873
|
+
MarketToken,
|
|
912
874
|
ProcessedOrderbook,
|
|
913
875
|
ArbitrageOpportunity,
|
|
914
|
-
EffectivePrices,
|
|
876
|
+
EffectivePrices,
|
|
877
|
+
|
|
878
|
+
// Trading
|
|
879
|
+
Side,
|
|
880
|
+
OrderType,
|
|
881
|
+
Order,
|
|
882
|
+
OrderResult,
|
|
883
|
+
LimitOrderParams,
|
|
884
|
+
MarketOrderParams,
|
|
915
885
|
|
|
916
|
-
// K-Lines
|
|
886
|
+
// K-Lines
|
|
917
887
|
KLineInterval,
|
|
918
888
|
KLineCandle,
|
|
919
889
|
DualKLineData,
|
|
920
|
-
SpreadDataPoint,
|
|
890
|
+
SpreadDataPoint,
|
|
891
|
+
|
|
892
|
+
// WebSocket
|
|
893
|
+
PriceUpdate,
|
|
894
|
+
BookUpdate,
|
|
895
|
+
OrderbookSnapshot,
|
|
921
896
|
|
|
922
897
|
// Wallet
|
|
923
898
|
WalletProfile,
|
|
924
899
|
SellActivityResult,
|
|
925
900
|
|
|
926
|
-
//
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
OrderResult,
|
|
933
|
-
TradeInfo,
|
|
934
|
-
|
|
935
|
-
// Rewards
|
|
936
|
-
UserEarning,
|
|
937
|
-
MarketReward,
|
|
901
|
+
// Smart Money
|
|
902
|
+
SmartMoneyWallet,
|
|
903
|
+
SmartMoneyTrade,
|
|
904
|
+
AutoCopyTradingOptions,
|
|
905
|
+
AutoCopyTradingStats,
|
|
906
|
+
AutoCopyTradingSubscription,
|
|
938
907
|
|
|
939
908
|
// CTF
|
|
940
|
-
CTFConfig,
|
|
941
909
|
SplitResult,
|
|
942
910
|
MergeResult,
|
|
943
911
|
RedeemResult,
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
TokenIds,
|
|
947
|
-
|
|
948
|
-
// Bridge
|
|
949
|
-
BridgeSupportedAsset,
|
|
950
|
-
DepositAddress,
|
|
951
|
-
DepositStatus,
|
|
952
|
-
DepositResult,
|
|
953
|
-
SwapAndDepositResult,
|
|
954
|
-
|
|
955
|
-
// Swap
|
|
956
|
-
SupportedToken,
|
|
957
|
-
SwapQuote,
|
|
958
|
-
SwapResult,
|
|
959
|
-
TokenBalance,
|
|
960
|
-
|
|
961
|
-
// Authorization
|
|
962
|
-
AllowanceInfo,
|
|
963
|
-
AllowancesResult,
|
|
964
|
-
ApprovalTxResult,
|
|
965
|
-
|
|
966
|
-
// ArbitrageService
|
|
912
|
+
|
|
913
|
+
// Arbitrage
|
|
967
914
|
ArbitrageMarketConfig,
|
|
968
915
|
ArbitrageServiceConfig,
|
|
969
|
-
ArbitrageServiceOpportunity,
|
|
970
|
-
ArbitrageExecutionResult,
|
|
971
|
-
OrderbookState,
|
|
972
|
-
BalanceState,
|
|
973
|
-
RebalanceAction,
|
|
974
|
-
RebalanceResult,
|
|
975
|
-
SettleResult,
|
|
976
|
-
// ArbitrageService - Scanning
|
|
977
|
-
ScanCriteria,
|
|
978
916
|
ScanResult,
|
|
979
|
-
// ArbitrageService - Smart clearing
|
|
980
917
|
ClearPositionResult,
|
|
981
|
-
ClearAction,
|
|
982
|
-
|
|
983
|
-
// Price Utils
|
|
984
|
-
TickSize,
|
|
985
|
-
|
|
986
|
-
// API types
|
|
987
|
-
Position,
|
|
988
|
-
Trade,
|
|
989
|
-
LeaderboardEntry,
|
|
990
|
-
GammaMarket,
|
|
991
|
-
ClobMarket,
|
|
992
|
-
Orderbook,
|
|
993
|
-
} from '@catalyst-team/poly-sdk';
|
|
994
|
-
```
|
|
995
|
-
|
|
996
|
-
## Error Handling
|
|
997
|
-
|
|
998
|
-
```typescript
|
|
999
|
-
import { PolymarketError, ErrorCode, withRetry } from '@catalyst-team/poly-sdk';
|
|
1000
|
-
|
|
1001
|
-
try {
|
|
1002
|
-
const market = await sdk.getMarket('invalid-slug');
|
|
1003
|
-
} catch (error) {
|
|
1004
|
-
if (error instanceof PolymarketError) {
|
|
1005
|
-
if (error.code === ErrorCode.MARKET_NOT_FOUND) {
|
|
1006
|
-
console.log('Market not found');
|
|
1007
|
-
} else if (error.code === ErrorCode.RATE_LIMITED) {
|
|
1008
|
-
console.log('Rate limited, retry later');
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
918
|
|
|
1013
|
-
//
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
Built-in rate limiting per API type:
|
|
1023
|
-
- Data API: 10 req/sec
|
|
1024
|
-
- Gamma API: 10 req/sec
|
|
1025
|
-
- CLOB API: 5 req/sec
|
|
1026
|
-
|
|
1027
|
-
```typescript
|
|
1028
|
-
import { RateLimiter, ApiType } from '@catalyst-team/poly-sdk';
|
|
1029
|
-
|
|
1030
|
-
// Custom rate limiter
|
|
1031
|
-
const limiter = new RateLimiter({
|
|
1032
|
-
[ApiType.DATA]: { maxConcurrent: 5, minTime: 200 },
|
|
1033
|
-
[ApiType.GAMMA]: { maxConcurrent: 5, minTime: 200 },
|
|
1034
|
-
[ApiType.CLOB]: { maxConcurrent: 2, minTime: 500 },
|
|
1035
|
-
});
|
|
1036
|
-
```
|
|
1037
|
-
|
|
1038
|
-
## Caching
|
|
1039
|
-
|
|
1040
|
-
Built-in TTL-based caching:
|
|
1041
|
-
|
|
1042
|
-
```typescript
|
|
1043
|
-
// Clear all cache
|
|
1044
|
-
sdk.clearCache();
|
|
1045
|
-
|
|
1046
|
-
// Invalidate specific market
|
|
1047
|
-
sdk.invalidateMarketCache(conditionId);
|
|
919
|
+
// DipArb
|
|
920
|
+
DipArbServiceConfig,
|
|
921
|
+
DipArbMarketConfig,
|
|
922
|
+
DipArbSignalEvent,
|
|
923
|
+
DipArbExecutionResult,
|
|
924
|
+
DipArbRoundState,
|
|
925
|
+
DipArbStats,
|
|
926
|
+
} from '@catalyst-team/poly-sdk';
|
|
1048
927
|
```
|
|
1049
928
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
| Example | Description | Source |
|
|
1053
|
-
|---------|-------------|--------|
|
|
1054
|
-
| [Basic Usage](examples/01-basic-usage.ts) | Get markets, orderbooks, detect arbitrage | `pnpm example:basic` |
|
|
1055
|
-
| [Smart Money](examples/02-smart-money.ts) | Top traders, wallet profiles, smart scores | `pnpm example:smart-money` |
|
|
1056
|
-
| [Market Analysis](examples/03-market-analysis.ts) | Market signals, volume analysis | `pnpm example:market-analysis` |
|
|
1057
|
-
| [K-Line Aggregation](examples/04-kline-aggregation.ts) | Build OHLCV candles from trades | `pnpm example:kline` |
|
|
1058
|
-
| [Follow Wallet](examples/05-follow-wallet-strategy.ts) | Track smart money positions, detect exits | `pnpm example:follow-wallet` |
|
|
1059
|
-
| [Services Demo](examples/06-services-demo.ts) | All SDK services in action | `pnpm example:services` |
|
|
1060
|
-
| [Realtime WebSocket](examples/07-realtime-websocket.ts) | Live price feeds, orderbook updates | `pnpm example:realtime` |
|
|
1061
|
-
| [Trading Orders](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types | `pnpm example:trading` |
|
|
1062
|
-
| [Rewards Tracking](examples/09-rewards-tracking.ts) | Market maker incentives, earnings | `pnpm example:rewards` |
|
|
1063
|
-
| [CTF Operations](examples/10-ctf-operations.ts) | Split, merge, redeem tokens | `pnpm example:ctf` |
|
|
1064
|
-
| [Live Arbitrage Scan](examples/11-live-arbitrage-scan.ts) | Scan real markets for opportunities | `pnpm example:live-arb` |
|
|
1065
|
-
| [Trending Arb Monitor](examples/12-trending-arb-monitor.ts) | Real-time trending markets monitor | `pnpm example:trending-arb` |
|
|
1066
|
-
|
|
1067
|
-
Run any example:
|
|
1068
|
-
|
|
1069
|
-
```bash
|
|
1070
|
-
pnpm example:basic
|
|
1071
|
-
pnpm example:smart-money
|
|
1072
|
-
pnpm example:trading
|
|
1073
|
-
# etc.
|
|
1074
|
-
```
|
|
929
|
+
---
|
|
1075
930
|
|
|
1076
931
|
## Dependencies
|
|
1077
932
|
|
|
1078
|
-
- `@
|
|
933
|
+
- `@polymarket/clob-client` - Official CLOB trading client
|
|
934
|
+
- `@polymarket/real-time-data-client` - Official WebSocket client
|
|
935
|
+
- `ethers@5` - Blockchain interactions
|
|
1079
936
|
- `bottleneck` - Rate limiting
|
|
1080
|
-
|
|
937
|
+
|
|
938
|
+
---
|
|
1081
939
|
|
|
1082
940
|
## License
|
|
1083
941
|
|