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