@catalyst-team/poly-sdk 0.1.0 → 0.2.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/LICENSE +21 -0
- package/README.en.md +538 -0
- package/README.md +357 -78
- package/docs/00-design.md +1 -1
- package/docs/02-API.md +21 -21
- package/docs/arb/test-plan.md +387 -0
- package/docs/arb/test-results.md +336 -0
- package/docs/arbitrage.md +754 -0
- package/docs/reports/smart-money-analysis-2025-12-23-cn.md +840 -0
- package/examples/13-arbitrage-service.ts +211 -0
- package/examples/README.md +1 -1
- package/package.json +19 -19
- package/scripts/arb/faze-bo3-arb.ts +385 -0
- package/scripts/arb/settle-position.ts +190 -0
- package/scripts/arb/token-rebalancer.ts +420 -0
- package/scripts/arb-tests/01-unit-tests.ts +495 -0
- package/scripts/arb-tests/02-integration-tests.ts +412 -0
- package/scripts/arb-tests/03-e2e-tests.ts +503 -0
- package/scripts/arb-tests/README.md +109 -0
- package/scripts/verify/verify-all-apis.ts +1 -1
- package/src/clients/clob-api.ts +1 -1
- package/src/clients/gamma-api.ts +1 -1
- package/src/core/cache-adapter-bridge.ts +1 -1
- package/src/core/types.ts +3 -3
- package/src/core/unified-cache.ts +1 -1
- package/src/index.ts +25 -19
- package/src/services/arbitrage-service.ts +1807 -0
- package/.env +0 -0
- package/dist/__tests__/clob-api.test.d.ts +0 -5
- package/dist/__tests__/clob-api.test.d.ts.map +0 -1
- package/dist/__tests__/clob-api.test.js +0 -240
- package/dist/__tests__/clob-api.test.js.map +0 -1
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts +0 -11
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/bridge-client.integration.test.js +0 -260
- package/dist/__tests__/integration/bridge-client.integration.test.js.map +0 -1
- package/dist/__tests__/integration/clob-api.integration.test.d.ts +0 -13
- package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/clob-api.integration.test.js +0 -170
- package/dist/__tests__/integration/clob-api.integration.test.js.map +0 -1
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts +0 -17
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/ctf-client.integration.test.js +0 -234
- package/dist/__tests__/integration/ctf-client.integration.test.js.map +0 -1
- package/dist/__tests__/integration/data-api.integration.test.d.ts +0 -9
- package/dist/__tests__/integration/data-api.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/data-api.integration.test.js +0 -161
- package/dist/__tests__/integration/data-api.integration.test.js.map +0 -1
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts +0 -9
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +0 -1
- package/dist/__tests__/integration/gamma-api.integration.test.js +0 -170
- package/dist/__tests__/integration/gamma-api.integration.test.js.map +0 -1
- package/dist/__tests__/test-utils.d.ts +0 -92
- package/dist/__tests__/test-utils.d.ts.map +0 -1
- package/dist/__tests__/test-utils.js +0 -143
- package/dist/__tests__/test-utils.js.map +0 -1
- package/dist/clients/bridge-client.d.ts +0 -388
- package/dist/clients/bridge-client.d.ts.map +0 -1
- package/dist/clients/bridge-client.js +0 -587
- package/dist/clients/bridge-client.js.map +0 -1
- package/dist/clients/clob-api.d.ts +0 -318
- package/dist/clients/clob-api.d.ts.map +0 -1
- package/dist/clients/clob-api.js +0 -388
- package/dist/clients/clob-api.js.map +0 -1
- package/dist/clients/ctf-client.d.ts +0 -473
- package/dist/clients/ctf-client.d.ts.map +0 -1
- package/dist/clients/ctf-client.js +0 -915
- package/dist/clients/ctf-client.js.map +0 -1
- package/dist/clients/data-api.d.ts +0 -134
- package/dist/clients/data-api.d.ts.map +0 -1
- package/dist/clients/data-api.js +0 -265
- package/dist/clients/data-api.js.map +0 -1
- package/dist/clients/gamma-api.d.ts +0 -401
- package/dist/clients/gamma-api.d.ts.map +0 -1
- package/dist/clients/gamma-api.js +0 -352
- package/dist/clients/gamma-api.js.map +0 -1
- package/dist/clients/trading-client.d.ts +0 -252
- package/dist/clients/trading-client.d.ts.map +0 -1
- package/dist/clients/trading-client.js +0 -543
- package/dist/clients/trading-client.js.map +0 -1
- package/dist/clients/websocket-manager.d.ts +0 -100
- package/dist/clients/websocket-manager.d.ts.map +0 -1
- package/dist/clients/websocket-manager.js +0 -193
- package/dist/clients/websocket-manager.js.map +0 -1
- package/dist/core/cache-adapter-bridge.d.ts +0 -36
- package/dist/core/cache-adapter-bridge.d.ts.map +0 -1
- package/dist/core/cache-adapter-bridge.js +0 -81
- package/dist/core/cache-adapter-bridge.js.map +0 -1
- package/dist/core/cache.d.ts +0 -40
- package/dist/core/cache.d.ts.map +0 -1
- package/dist/core/cache.js +0 -71
- package/dist/core/cache.js.map +0 -1
- package/dist/core/errors.d.ts +0 -38
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/errors.js +0 -84
- package/dist/core/errors.js.map +0 -1
- package/dist/core/rate-limiter.d.ts +0 -31
- package/dist/core/rate-limiter.d.ts.map +0 -1
- package/dist/core/rate-limiter.js +0 -70
- package/dist/core/rate-limiter.js.map +0 -1
- package/dist/core/types.d.ts +0 -314
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -19
- package/dist/core/types.js.map +0 -1
- package/dist/core/unified-cache.d.ts +0 -63
- package/dist/core/unified-cache.d.ts.map +0 -1
- package/dist/core/unified-cache.js +0 -114
- package/dist/core/unified-cache.js.map +0 -1
- package/dist/index.d.ts +0 -94
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -258
- package/dist/index.js.map +0 -1
- package/dist/mcp/errors.d.ts +0 -33
- package/dist/mcp/errors.d.ts.map +0 -1
- package/dist/mcp/errors.js +0 -86
- package/dist/mcp/errors.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -62
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -173
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -17
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -155
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/tools/guide.d.ts +0 -12
- package/dist/mcp/tools/guide.d.ts.map +0 -1
- package/dist/mcp/tools/guide.js +0 -801
- package/dist/mcp/tools/guide.js.map +0 -1
- package/dist/mcp/tools/index.d.ts +0 -11
- package/dist/mcp/tools/index.d.ts.map +0 -1
- package/dist/mcp/tools/index.js +0 -27
- package/dist/mcp/tools/index.js.map +0 -1
- package/dist/mcp/tools/market.d.ts +0 -11
- package/dist/mcp/tools/market.d.ts.map +0 -1
- package/dist/mcp/tools/market.js +0 -314
- package/dist/mcp/tools/market.js.map +0 -1
- package/dist/mcp/tools/order.d.ts +0 -10
- package/dist/mcp/tools/order.d.ts.map +0 -1
- package/dist/mcp/tools/order.js +0 -258
- package/dist/mcp/tools/order.js.map +0 -1
- package/dist/mcp/tools/trade.d.ts +0 -38
- package/dist/mcp/tools/trade.d.ts.map +0 -1
- package/dist/mcp/tools/trade.js +0 -314
- package/dist/mcp/tools/trade.js.map +0 -1
- package/dist/mcp/tools/trader.d.ts +0 -11
- package/dist/mcp/tools/trader.d.ts.map +0 -1
- package/dist/mcp/tools/trader.js +0 -277
- package/dist/mcp/tools/trader.js.map +0 -1
- package/dist/mcp/tools/wallet.d.ts +0 -274
- package/dist/mcp/tools/wallet.d.ts.map +0 -1
- package/dist/mcp/tools/wallet.js +0 -579
- package/dist/mcp/tools/wallet.js.map +0 -1
- package/dist/mcp/types.d.ts +0 -413
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js +0 -5
- package/dist/mcp/types.js.map +0 -1
- package/dist/services/authorization-service.d.ts +0 -97
- package/dist/services/authorization-service.d.ts.map +0 -1
- package/dist/services/authorization-service.js +0 -279
- package/dist/services/authorization-service.js.map +0 -1
- package/dist/services/market-service.d.ts +0 -108
- package/dist/services/market-service.d.ts.map +0 -1
- package/dist/services/market-service.js +0 -458
- package/dist/services/market-service.js.map +0 -1
- package/dist/services/realtime-service.d.ts +0 -82
- package/dist/services/realtime-service.d.ts.map +0 -1
- package/dist/services/realtime-service.js +0 -150
- package/dist/services/realtime-service.js.map +0 -1
- package/dist/services/swap-service.d.ts +0 -217
- package/dist/services/swap-service.d.ts.map +0 -1
- package/dist/services/swap-service.js +0 -695
- package/dist/services/swap-service.js.map +0 -1
- package/dist/services/wallet-service.d.ts +0 -94
- package/dist/services/wallet-service.d.ts.map +0 -1
- package/dist/services/wallet-service.js +0 -173
- package/dist/services/wallet-service.js.map +0 -1
- package/dist/utils/price-utils.d.ts +0 -153
- package/dist/utils/price-utils.d.ts.map +0 -1
- package/dist/utils/price-utils.js +0 -236
- package/dist/utils/price-utils.js.map +0 -1
- package/docs/01-mcp.md +0 -2041
- package/docs/e2e/01-trader-tools.md +0 -159
- package/docs/e2e/02-market-tools.md +0 -180
- package/docs/e2e/03-order-tools.md +0 -166
- package/docs/e2e/04-wallet-tools.md +0 -224
- package/docs/e2e/05-trading-tools.md +0 -327
- package/docs/e2e/06-integration-scenarios.md +0 -481
- package/docs/e2e/coordinator.md +0 -376
- package/scripts/truth.md +0 -440
- package/src/mcp/README.md +0 -380
- package/src/mcp/errors.ts +0 -124
- package/src/mcp/index.ts +0 -309
- package/src/mcp/server.ts +0 -183
- package/src/mcp/tools/guide.ts +0 -821
- package/src/mcp/tools/index.ts +0 -73
- package/src/mcp/tools/market.ts +0 -363
- package/src/mcp/tools/order.ts +0 -326
- package/src/mcp/tools/trade.ts +0 -417
- package/src/mcp/tools/trader.ts +0 -322
- package/src/mcp/tools/wallet.ts +0 -683
- package/src/mcp/types.ts +0 -472
package/README.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @catalyst-team/poly-sdk
|
|
2
2
|
|
|
3
3
|
Unified SDK for Polymarket APIs - Data API, Gamma API, CLOB API, and WebSocket real-time updates.
|
|
4
4
|
|
|
5
|
+
**Builder**: [@hhhx402](https://x.com/hhhx402)
|
|
6
|
+
**Project**: [Catalyst.fun](https://x.com/catalystdotfun)
|
|
7
|
+
|
|
5
8
|
## Installation
|
|
6
9
|
|
|
7
10
|
```bash
|
|
8
|
-
pnpm add @
|
|
11
|
+
pnpm add @catalyst-team/poly-sdk
|
|
9
12
|
```
|
|
10
13
|
|
|
11
14
|
## Quick Start
|
|
12
15
|
|
|
13
16
|
```typescript
|
|
14
|
-
import { PolymarketSDK } from '@
|
|
17
|
+
import { PolymarketSDK } from '@catalyst-team/poly-sdk';
|
|
15
18
|
|
|
16
19
|
const sdk = new PolymarketSDK();
|
|
17
20
|
|
|
@@ -33,29 +36,39 @@ if (arb) {
|
|
|
33
36
|
## Architecture
|
|
34
37
|
|
|
35
38
|
```
|
|
36
|
-
|
|
37
|
-
│
|
|
38
|
-
|
|
39
|
-
│ Layer 3: Services
|
|
40
|
-
│ ┌─────────────┐
|
|
41
|
-
│ │WalletService│
|
|
42
|
-
│ │ - profiles │
|
|
43
|
-
│ │ - sell det. │
|
|
44
|
-
│ └─────────────┘
|
|
45
|
-
|
|
46
|
-
│
|
|
47
|
-
│
|
|
48
|
-
│
|
|
49
|
-
│ │
|
|
50
|
-
│
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
│
|
|
54
|
-
│
|
|
55
|
-
│ │
|
|
56
|
-
│ │
|
|
57
|
-
│
|
|
58
|
-
|
|
39
|
+
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
40
|
+
│ PolymarketSDK │
|
|
41
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
42
|
+
│ Layer 3: Services │
|
|
43
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ ┌─────────────────────────┐│
|
|
44
|
+
│ │WalletService│ │MarketService│ │RealtimeService│ │ AuthorizationService ││
|
|
45
|
+
│ │ - profiles │ │ - K-Lines │ │- subscriptions│ │ - ERC20 approvals ││
|
|
46
|
+
│ │ - sell det. │ │ - signals │ │- price cache │ │ - ERC1155 approvals ││
|
|
47
|
+
│ └─────────────┘ └─────────────┘ └───────────────┘ └─────────────────────────┘│
|
|
48
|
+
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
|
49
|
+
│ │ ArbitrageService: Real-time arbitrage detection, rebalancer, settlement │ │
|
|
50
|
+
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
|
51
|
+
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
|
52
|
+
│ │ SwapService: DEX swaps on Polygon (QuickSwap V3, USDC/USDC.e conversion)│ │
|
|
53
|
+
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
|
54
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
55
|
+
│ Layer 2: API Clients │
|
|
56
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌────────────────────┐ │
|
|
57
|
+
│ │ DataAPI │ │ GammaAPI │ │ CLOB API │ │ WebSocket │ │ BridgeClient │ │
|
|
58
|
+
│ │positions │ │ markets │ │ orderbook│ │ real-time │ │ cross-chain │ │
|
|
59
|
+
│ │ trades │ │ events │ │ trading │ │ prices │ │ deposits │ │
|
|
60
|
+
│ └──────────┘ └──────────┘ └──────────┘ └───────────┘ └────────────────────┘ │
|
|
61
|
+
│ ┌──────────────────────────────────────┐ ┌────────────────────────────────┐ │
|
|
62
|
+
│ │ TradingClient: Order execution │ │ CTFClient: On-chain operations │ │
|
|
63
|
+
│ │ GTC/GTD/FOK/FAK, rewards, balances │ │ Split / Merge / Redeem tokens │ │
|
|
64
|
+
│ └──────────────────────────────────────┘ └────────────────────────────────┘ │
|
|
65
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
66
|
+
│ Layer 1: Infrastructure │
|
|
67
|
+
│ ┌────────────┐ ┌─────────┐ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │
|
|
68
|
+
│ │RateLimiter │ │ Cache │ │ Errors │ │ Types │ │ Price Utils │ │
|
|
69
|
+
│ │per-API │ │TTL-based│ │ retry │ │ unified │ │ arb detect │ │
|
|
70
|
+
│ └────────────┘ └─────────┘ └──────────┘ └────────────┘ └──────────────┘ │
|
|
71
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
59
72
|
```
|
|
60
73
|
|
|
61
74
|
## API Clients
|
|
@@ -197,7 +210,7 @@ const bidSum = YES.bid + NO.bid; // ≈ 0.001-0.002,而非 ≈ 1.0
|
|
|
197
210
|
|
|
198
211
|
**正确做法:使用有效价格 (Effective Prices)**
|
|
199
212
|
```typescript
|
|
200
|
-
import { getEffectivePrices, checkArbitrage } from '@
|
|
213
|
+
import { getEffectivePrices, checkArbitrage } from '@catalyst-team/poly-sdk';
|
|
201
214
|
|
|
202
215
|
// 计算考虑镜像后的最优价格
|
|
203
216
|
const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
|
|
@@ -288,7 +301,7 @@ interface OrderbookSummary {
|
|
|
288
301
|
### TradingClient - Order Execution
|
|
289
302
|
|
|
290
303
|
```typescript
|
|
291
|
-
import { TradingClient, RateLimiter } from '@
|
|
304
|
+
import { TradingClient, RateLimiter } from '@catalyst-team/poly-sdk';
|
|
292
305
|
|
|
293
306
|
const rateLimiter = new RateLimiter();
|
|
294
307
|
const tradingClient = new TradingClient(rateLimiter, {
|
|
@@ -392,7 +405,7 @@ wsManager.on('bookUpdate', (update) => {
|
|
|
392
405
|
```
|
|
393
406
|
|
|
394
407
|
```typescript
|
|
395
|
-
import { WebSocketManager, RealtimeService } from '@
|
|
408
|
+
import { WebSocketManager, RealtimeService } from '@catalyst-team/poly-sdk';
|
|
396
409
|
|
|
397
410
|
const wsManager = new WebSocketManager();
|
|
398
411
|
const realtime = new RealtimeService(wsManager);
|
|
@@ -421,15 +434,29 @@ const price = realtime.getPrice(yesTokenId);
|
|
|
421
434
|
await subscription.unsubscribe();
|
|
422
435
|
```
|
|
423
436
|
|
|
424
|
-
### CTFClient - On-Chain Token Operations
|
|
437
|
+
### CTFClient - On-Chain Token Operations (Split/Merge/Redeem)
|
|
425
438
|
|
|
426
|
-
The CTF (Conditional Token Framework) client enables on-chain operations for Polymarket's conditional tokens.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
439
|
+
The CTF (Conditional Token Framework) client enables on-chain operations for Polymarket's conditional tokens.
|
|
440
|
+
|
|
441
|
+
```
|
|
442
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
443
|
+
│ CTF 核心操作快速参考 │
|
|
444
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
445
|
+
│ 操作 │ 功能 │ 典型场景 │
|
|
446
|
+
├──────────────┼────────────────────────┼──────────────────────────────────────┤
|
|
447
|
+
│ Split │ USDC → YES + NO │ 市场做市:创建代币库存 │
|
|
448
|
+
│ Merge │ YES + NO → USDC │ 套利:买入双边后合并获利 │
|
|
449
|
+
│ Redeem │ 胜出代币 → USDC │ 结算:市场结束后兑换获胜代币 │
|
|
450
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**核心用途:**
|
|
454
|
+
- **Arbitrage (套利)**: 当 YES + NO 买入成本 < $1 时,Merge 获利
|
|
455
|
+
- **Market Making (做市)**: Split USDC 创建代币库存进行双边报价
|
|
456
|
+
- **Redemption (结算)**: 市场结束后 Redeem 胜出代币获取 USDC
|
|
430
457
|
|
|
431
458
|
```typescript
|
|
432
|
-
import { CTFClient, CTF_CONTRACT, USDC_CONTRACT } from '@
|
|
459
|
+
import { CTFClient, CTF_CONTRACT, USDC_CONTRACT } from '@catalyst-team/poly-sdk';
|
|
433
460
|
|
|
434
461
|
const ctf = new CTFClient({
|
|
435
462
|
privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
|
|
@@ -451,11 +478,25 @@ console.log(`Created ${splitResult.yesTokens} YES + ${splitResult.noTokens} NO`)
|
|
|
451
478
|
|
|
452
479
|
#### Merge: YES + NO → USDC
|
|
453
480
|
|
|
481
|
+
⚠️ **重要:两种 Merge 方法**
|
|
482
|
+
|
|
483
|
+
| 方法 | 适用场景 | 推荐 |
|
|
484
|
+
|------|----------|------|
|
|
485
|
+
| `mergeByTokenIds()` | **Polymarket CLOB 市场** | ✅ 推荐 |
|
|
486
|
+
| `merge()` | 标准 Gnosis CTF 市场 | ❌ Polymarket 慎用 |
|
|
487
|
+
|
|
454
488
|
```typescript
|
|
455
|
-
//
|
|
456
|
-
const
|
|
489
|
+
// ✅ 推荐:Polymarket 市场使用 mergeByTokenIds
|
|
490
|
+
const tokenIds = {
|
|
491
|
+
yesTokenId: market.tokens[0].tokenId, // 从 CLOB API 获取
|
|
492
|
+
noTokenId: market.tokens[1].tokenId,
|
|
493
|
+
};
|
|
494
|
+
const mergeResult = await ctf.mergeByTokenIds(conditionId, tokenIds, '100');
|
|
457
495
|
console.log(`TX: ${mergeResult.txHash}`);
|
|
458
496
|
console.log(`Received ${mergeResult.usdcReceived} USDC`);
|
|
497
|
+
|
|
498
|
+
// ⚠️ 标准 CTF 方法(可能无法正确检查 Polymarket 余额)
|
|
499
|
+
// const mergeResult = await ctf.merge(conditionId, '100');
|
|
459
500
|
```
|
|
460
501
|
|
|
461
502
|
#### Redeem: Winning Tokens → USDC
|
|
@@ -535,7 +576,7 @@ const mergeGas = await ctf.estimateMergeGas(conditionId, '100');
|
|
|
535
576
|
```
|
|
536
577
|
|
|
537
578
|
```typescript
|
|
538
|
-
import { checkArbitrage, getEffectivePrices } from '@
|
|
579
|
+
import { checkArbitrage, getEffectivePrices } from '@catalyst-team/poly-sdk';
|
|
539
580
|
|
|
540
581
|
// checkArbitrage 内部使用有效价格计算
|
|
541
582
|
const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
|
|
@@ -548,44 +589,254 @@ if (arb?.type === 'long') {
|
|
|
548
589
|
}
|
|
549
590
|
```
|
|
550
591
|
|
|
551
|
-
###
|
|
592
|
+
### BridgeClient - Cross-Chain Deposits
|
|
552
593
|
|
|
553
|
-
|
|
594
|
+
Bridge assets from multiple chains (Ethereum, Solana, Bitcoin) to Polygon USDC.e for Polymarket trading.
|
|
554
595
|
|
|
555
|
-
|
|
596
|
+
```
|
|
597
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
598
|
+
│ 跨链充值流程 │
|
|
599
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
600
|
+
│ 1. 获取充值地址 → 2. 发送资产到地址 → 3. 自动桥接 → 4. USDC.e 到账 │
|
|
601
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
602
|
+
```
|
|
556
603
|
|
|
557
|
-
|
|
604
|
+
```typescript
|
|
605
|
+
import {
|
|
606
|
+
BridgeClient,
|
|
607
|
+
SUPPORTED_CHAINS,
|
|
608
|
+
depositUsdc,
|
|
609
|
+
swapAndDeposit,
|
|
610
|
+
} from '@catalyst-team/poly-sdk';
|
|
611
|
+
|
|
612
|
+
// Get deposit addresses for your wallet
|
|
613
|
+
const bridge = new BridgeClient();
|
|
614
|
+
const addresses = await bridge.createDepositAddresses(walletAddress);
|
|
615
|
+
console.log(`EVM chains: ${addresses.address.evm}`);
|
|
616
|
+
console.log(`Solana: ${addresses.address.svm}`);
|
|
617
|
+
console.log(`Bitcoin: ${addresses.address.btc}`);
|
|
618
|
+
|
|
619
|
+
// Get supported assets
|
|
620
|
+
const assets = await bridge.getSupportedAssets();
|
|
621
|
+
for (const asset of assets) {
|
|
622
|
+
console.log(`${asset.chainName} ${asset.tokenSymbol}: min ${asset.minDepositUsd} USD`);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Direct USDC deposit from Ethereum
|
|
626
|
+
const depositResult = await depositUsdc(signer, '100', walletAddress);
|
|
627
|
+
console.log(`Deposited: ${depositResult.txHash}`);
|
|
628
|
+
|
|
629
|
+
// Swap ETH to USDC and deposit
|
|
630
|
+
const swapResult = await swapAndDeposit(signer, {
|
|
631
|
+
tokenIn: 'ETH',
|
|
632
|
+
amountIn: '0.1',
|
|
633
|
+
targetAddress: walletAddress,
|
|
634
|
+
});
|
|
635
|
+
console.log(`Swapped & deposited: ${swapResult.usdcAmount}`);
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### SwapService - DEX Swaps on Polygon
|
|
639
|
+
|
|
640
|
+
Swap tokens on Polygon using QuickSwap V3. Essential for converting tokens to USDC.e for CTF operations.
|
|
641
|
+
|
|
642
|
+
⚠️ **USDC vs USDC.e for Polymarket CTF**
|
|
643
|
+
|
|
644
|
+
| Token | Address | Polymarket CTF |
|
|
645
|
+
|-------|---------|----------------|
|
|
646
|
+
| USDC.e | `0x2791...` | ✅ **Required** |
|
|
647
|
+
| USDC (Native) | `0x3c49...` | ❌ Not accepted |
|
|
558
648
|
|
|
559
649
|
```typescript
|
|
560
|
-
import {
|
|
650
|
+
import { SwapService, POLYGON_TOKENS } from '@catalyst-team/poly-sdk';
|
|
561
651
|
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const
|
|
652
|
+
const swapService = new SwapService(signer);
|
|
653
|
+
|
|
654
|
+
// Check balances
|
|
655
|
+
const balances = await swapService.getBalances();
|
|
656
|
+
for (const b of balances) {
|
|
657
|
+
console.log(`${b.symbol}: ${b.balance}`);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Swap native USDC to USDC.e for CTF operations
|
|
661
|
+
const swapResult = await swapService.swap('USDC', 'USDC_E', '100');
|
|
662
|
+
console.log(`Swapped: ${swapResult.amountOut} USDC.e`);
|
|
663
|
+
|
|
664
|
+
// Swap MATIC to USDC.e
|
|
665
|
+
const maticSwap = await swapService.swap('MATIC', 'USDC_E', '50');
|
|
666
|
+
|
|
667
|
+
// Get quote before swapping
|
|
668
|
+
const quote = await swapService.getQuote('WETH', 'USDC_E', '0.1');
|
|
669
|
+
console.log(`Expected output: ${quote.estimatedAmountOut} USDC.e`);
|
|
670
|
+
|
|
671
|
+
// Transfer USDC.e (for CTF operations)
|
|
672
|
+
await swapService.transferUsdcE(recipientAddress, '100');
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### AuthorizationService - Trading Approvals
|
|
676
|
+
|
|
677
|
+
Manage ERC20 and ERC1155 approvals required for trading on Polymarket.
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
import { AuthorizationService } from '@catalyst-team/poly-sdk';
|
|
681
|
+
|
|
682
|
+
const authService = new AuthorizationService(signer);
|
|
683
|
+
|
|
684
|
+
// Check all allowances
|
|
685
|
+
const status = await authService.checkAllowances();
|
|
686
|
+
console.log(`Wallet: ${status.wallet}`);
|
|
687
|
+
console.log(`USDC Balance: ${status.usdcBalance}`);
|
|
688
|
+
console.log(`Trading Ready: ${status.tradingReady}`);
|
|
566
689
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
690
|
+
if (!status.tradingReady) {
|
|
691
|
+
console.log('Issues:', status.issues);
|
|
692
|
+
|
|
693
|
+
// Set up all required approvals
|
|
694
|
+
const result = await authService.approveAll();
|
|
695
|
+
console.log(result.summary);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Check individual allowances
|
|
699
|
+
for (const allowance of status.erc20Allowances) {
|
|
700
|
+
console.log(`${allowance.contract}: ${allowance.approved ? '✅' : '❌'}`);
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### ArbitrageService - 套利服务
|
|
705
|
+
|
|
706
|
+
实时套利检测与执行,支持市场扫描、自动再平衡、智能清仓。
|
|
707
|
+
|
|
708
|
+
```
|
|
709
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
710
|
+
│ 核心功能 │
|
|
711
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
712
|
+
│ • scanMarkets() - 扫描市场找套利机会 │
|
|
713
|
+
│ • start(market) - 启动实时监控 + 自动执行 │
|
|
714
|
+
│ • clearPositions() - 智能清仓 (活跃市场卖出, 已结算市场 redeem) │
|
|
715
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
716
|
+
│ 自动再平衡 (Rebalancer) │
|
|
717
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
718
|
+
│ 套利需要 USDC + YES/NO Token,Rebalancer 自动维持资金比例: │
|
|
719
|
+
│ • USDC 比例 < 20% → 自动 Merge (YES+NO → USDC) │
|
|
720
|
+
│ • USDC 比例 > 80% → 自动 Split (USDC → YES+NO) │
|
|
721
|
+
│ • 冷却机制:两次操作间隔 ≥ 30s,检测间隔 10s │
|
|
722
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
723
|
+
│ 执行安全 (Partial Fill Protection) │
|
|
724
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
725
|
+
│ 套利需要同时买入 YES 和 NO,但订单可能部分成交: │
|
|
726
|
+
│ • sizeSafetyFactor=0.8 → 只使用 80% 的盘口深度,降低滑点风险 │
|
|
727
|
+
│ • autoFixImbalance=true → 如果只成交一侧,自动卖出多余的 token │
|
|
728
|
+
│ • imbalanceThreshold=5 → YES-NO 差额超过 $5 时触发修复 │
|
|
729
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
#### 完整工作流
|
|
733
|
+
|
|
734
|
+
```typescript
|
|
735
|
+
import { ArbitrageService } from '@catalyst-team/poly-sdk';
|
|
736
|
+
|
|
737
|
+
const arbService = new ArbitrageService({
|
|
738
|
+
privateKey: process.env.POLY_PRIVKEY,
|
|
739
|
+
profitThreshold: 0.005, // 0.5% minimum profit
|
|
740
|
+
minTradeSize: 5, // $5 minimum
|
|
741
|
+
maxTradeSize: 100, // $100 maximum
|
|
742
|
+
autoExecute: true, // Automatically execute opportunities
|
|
743
|
+
|
|
744
|
+
// Rebalancer config
|
|
745
|
+
enableRebalancer: true, // Auto-rebalance position
|
|
746
|
+
minUsdcRatio: 0.2, // Min 20% USDC (Split if below)
|
|
747
|
+
maxUsdcRatio: 0.8, // Max 80% USDC (Merge if above)
|
|
748
|
+
targetUsdcRatio: 0.5, // Target 50% when rebalancing
|
|
749
|
+
imbalanceThreshold: 5, // Max YES-NO difference before fix
|
|
750
|
+
rebalanceInterval: 10000, // Check every 10s
|
|
751
|
+
rebalanceCooldown: 30000, // Min 30s between actions
|
|
752
|
+
|
|
753
|
+
// Execution safety (prevents YES ≠ NO from partial fills)
|
|
754
|
+
sizeSafetyFactor: 0.8, // Use 80% of orderbook depth
|
|
755
|
+
autoFixImbalance: true, // Auto-sell excess if one side fails
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
// Listen for events
|
|
759
|
+
arbService.on('opportunity', (opp) => {
|
|
760
|
+
console.log(`${opp.type.toUpperCase()} ARB: ${opp.profitPercent.toFixed(2)}%`);
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
arbService.on('execution', (result) => {
|
|
764
|
+
if (result.success) {
|
|
765
|
+
console.log(`✅ Executed: $${result.profit.toFixed(2)} profit`);
|
|
766
|
+
}
|
|
571
767
|
});
|
|
572
768
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
769
|
+
arbService.on('rebalance', (result) => {
|
|
770
|
+
console.log(`🔄 Rebalance: ${result.action.type} ${result.action.amount}`);
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
// ========== Step 1: 扫描市场 ==========
|
|
774
|
+
const results = await arbService.scanMarkets({ minVolume24h: 5000 }, 0.005);
|
|
775
|
+
console.log(`Found ${results.filter(r => r.arbType !== 'none').length} opportunities`);
|
|
776
|
+
|
|
777
|
+
// 或者一键扫描+启动最佳市场
|
|
778
|
+
const best = await arbService.findAndStart(0.005);
|
|
779
|
+
if (!best) {
|
|
780
|
+
console.log('No arbitrage opportunities found');
|
|
781
|
+
process.exit(0);
|
|
578
782
|
}
|
|
783
|
+
console.log(`🎯 Started: ${best.market.name} (+${best.profitPercent.toFixed(2)}%)`);
|
|
579
784
|
|
|
580
|
-
//
|
|
581
|
-
|
|
785
|
+
// ========== Step 2: 运行套利 ==========
|
|
786
|
+
// 服务现在自动监控并执行套利...
|
|
787
|
+
// 运行一段时间后:
|
|
788
|
+
await new Promise(resolve => setTimeout(resolve, 60 * 60 * 1000)); // 1 hour
|
|
582
789
|
|
|
583
|
-
//
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
790
|
+
// ========== Step 3: 停止并清算 ==========
|
|
791
|
+
await arbService.stop();
|
|
792
|
+
console.log('Stats:', arbService.getStats());
|
|
793
|
+
|
|
794
|
+
// 智能清仓: 活跃市场 merge+sell, 已结算市场 redeem
|
|
795
|
+
const clearResult = await arbService.clearPositions(best.market, true);
|
|
796
|
+
console.log(`✅ Recovered: $${clearResult.totalUsdcRecovered.toFixed(2)}`);
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
#### 手动选择市场
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
// 如果不用 scanMarkets,可以手动构建 market config
|
|
803
|
+
const market = {
|
|
804
|
+
name: 'Will BTC reach $100k?',
|
|
805
|
+
conditionId: '0x...',
|
|
806
|
+
yesTokenId: '12345...',
|
|
807
|
+
noTokenId: '67890...',
|
|
808
|
+
outcomes: ['Yes', 'No'] as [string, string],
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
await arbService.start(market);
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
#### 批量清仓
|
|
815
|
+
|
|
816
|
+
```typescript
|
|
817
|
+
// 多个市场一起清仓
|
|
818
|
+
const markets = [market1, market2, market3];
|
|
819
|
+
const results = await arbService.clearAllPositions(markets, true);
|
|
820
|
+
const total = results.reduce((sum, r) => sum + r.totalUsdcRecovered, 0);
|
|
821
|
+
console.log(`Total recovered: $${total.toFixed(2)}`);
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
#### 仅监控模式
|
|
825
|
+
|
|
826
|
+
```typescript
|
|
827
|
+
// No private key = monitoring only, no execution
|
|
828
|
+
const arbService = new ArbitrageService({
|
|
829
|
+
profitThreshold: 0.003,
|
|
830
|
+
enableLogging: true,
|
|
587
831
|
});
|
|
588
|
-
|
|
832
|
+
|
|
833
|
+
arbService.on('opportunity', (opp) => {
|
|
834
|
+
// Log opportunities for analysis without executing
|
|
835
|
+
console.log(`Found ${opp.type} arb: ${opp.profitPercent.toFixed(2)}%`);
|
|
836
|
+
console.log(` ${opp.description}`);
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
await arbService.start(market);
|
|
589
840
|
```
|
|
590
841
|
|
|
591
842
|
## Price Utilities
|
|
@@ -600,7 +851,7 @@ import {
|
|
|
600
851
|
formatUSDC,
|
|
601
852
|
calculatePnL,
|
|
602
853
|
type TickSize,
|
|
603
|
-
} from '@
|
|
854
|
+
} from '@catalyst-team/poly-sdk';
|
|
604
855
|
|
|
605
856
|
// Round price to tick size
|
|
606
857
|
const tickSize: TickSize = '0.01';
|
|
@@ -642,7 +893,7 @@ console.log(`PnL: ${formatUSDC(pnl.pnl)} (${pnl.pnlPercent.toFixed(1)}%)`);
|
|
|
642
893
|
Supported intervals: `30s`, `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`
|
|
643
894
|
|
|
644
895
|
```typescript
|
|
645
|
-
import type { KLineInterval } from '@
|
|
896
|
+
import type { KLineInterval } from '@catalyst-team/poly-sdk';
|
|
646
897
|
|
|
647
898
|
const interval: KLineInterval = '1h';
|
|
648
899
|
const candles = await sdk.markets.getKLines(conditionId, interval);
|
|
@@ -690,13 +941,42 @@ import type {
|
|
|
690
941
|
RedeemResult,
|
|
691
942
|
PositionBalance,
|
|
692
943
|
MarketResolution,
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
944
|
+
TokenIds,
|
|
945
|
+
|
|
946
|
+
// Bridge
|
|
947
|
+
BridgeSupportedAsset,
|
|
948
|
+
DepositAddress,
|
|
949
|
+
DepositStatus,
|
|
950
|
+
DepositResult,
|
|
951
|
+
SwapAndDepositResult,
|
|
952
|
+
|
|
953
|
+
// Swap
|
|
954
|
+
SupportedToken,
|
|
955
|
+
SwapQuote,
|
|
956
|
+
SwapResult,
|
|
957
|
+
TokenBalance,
|
|
958
|
+
|
|
959
|
+
// Authorization
|
|
960
|
+
AllowanceInfo,
|
|
961
|
+
AllowancesResult,
|
|
962
|
+
ApprovalTxResult,
|
|
963
|
+
|
|
964
|
+
// ArbitrageService
|
|
965
|
+
ArbitrageMarketConfig,
|
|
966
|
+
ArbitrageServiceConfig,
|
|
967
|
+
ArbitrageServiceOpportunity,
|
|
968
|
+
ArbitrageExecutionResult,
|
|
969
|
+
OrderbookState,
|
|
970
|
+
BalanceState,
|
|
971
|
+
RebalanceAction,
|
|
972
|
+
RebalanceResult,
|
|
973
|
+
SettleResult,
|
|
974
|
+
// ArbitrageService - Scanning
|
|
975
|
+
ScanCriteria,
|
|
976
|
+
ScanResult,
|
|
977
|
+
// ArbitrageService - Smart clearing
|
|
978
|
+
ClearPositionResult,
|
|
979
|
+
ClearAction,
|
|
700
980
|
|
|
701
981
|
// Price Utils
|
|
702
982
|
TickSize,
|
|
@@ -708,13 +988,13 @@ import type {
|
|
|
708
988
|
GammaMarket,
|
|
709
989
|
ClobMarket,
|
|
710
990
|
Orderbook,
|
|
711
|
-
} from '@
|
|
991
|
+
} from '@catalyst-team/poly-sdk';
|
|
712
992
|
```
|
|
713
993
|
|
|
714
994
|
## Error Handling
|
|
715
995
|
|
|
716
996
|
```typescript
|
|
717
|
-
import { PolymarketError, ErrorCode, withRetry } from '@
|
|
997
|
+
import { PolymarketError, ErrorCode, withRetry } from '@catalyst-team/poly-sdk';
|
|
718
998
|
|
|
719
999
|
try {
|
|
720
1000
|
const market = await sdk.getMarket('invalid-slug');
|
|
@@ -743,7 +1023,7 @@ Built-in rate limiting per API type:
|
|
|
743
1023
|
- CLOB API: 5 req/sec
|
|
744
1024
|
|
|
745
1025
|
```typescript
|
|
746
|
-
import { RateLimiter, ApiType } from '@
|
|
1026
|
+
import { RateLimiter, ApiType } from '@catalyst-team/poly-sdk';
|
|
747
1027
|
|
|
748
1028
|
// Custom rate limiter
|
|
749
1029
|
const limiter = new RateLimiter({
|
|
@@ -779,9 +1059,8 @@ sdk.invalidateMarketCache(conditionId);
|
|
|
779
1059
|
| [Trading Orders](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types | `pnpm example:trading` |
|
|
780
1060
|
| [Rewards Tracking](examples/09-rewards-tracking.ts) | Market maker incentives, earnings | `pnpm example:rewards` |
|
|
781
1061
|
| [CTF Operations](examples/10-ctf-operations.ts) | Split, merge, redeem tokens | `pnpm example:ctf` |
|
|
782
|
-
| [Arbitrage
|
|
783
|
-
| [
|
|
784
|
-
| [Trending Arb Monitor](examples/13-trending-arb-monitor.ts) | Real-time trending markets monitor | `pnpm example:trending-arb` |
|
|
1062
|
+
| [Live Arbitrage Scan](examples/11-live-arbitrage-scan.ts) | Scan real markets for opportunities | `pnpm example:live-arb` |
|
|
1063
|
+
| [Trending Arb Monitor](examples/12-trending-arb-monitor.ts) | Real-time trending markets monitor | `pnpm example:trending-arb` |
|
|
785
1064
|
|
|
786
1065
|
Run any example:
|
|
787
1066
|
|
package/docs/00-design.md
CHANGED
|
@@ -176,7 +176,7 @@ await swapService.transferUsdcE(sessionWallet, '100');
|
|
|
176
176
|
The `swapAndDeposit()` function combines swap and deposit in one operation:
|
|
177
177
|
|
|
178
178
|
```typescript
|
|
179
|
-
import { swapAndDeposit } from '@
|
|
179
|
+
import { swapAndDeposit } from '@catalyst-team/poly-sdk';
|
|
180
180
|
|
|
181
181
|
// Swap MATIC to USDC and deposit to Polymarket
|
|
182
182
|
const result = await swapAndDeposit(signer, 'MATIC', '100', {
|