@catalyst-team/poly-sdk 0.1.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.
Files changed (244) hide show
  1. package/.env +0 -0
  2. package/README.md +803 -0
  3. package/dist/__tests__/clob-api.test.d.ts +5 -0
  4. package/dist/__tests__/clob-api.test.d.ts.map +1 -0
  5. package/dist/__tests__/clob-api.test.js +240 -0
  6. package/dist/__tests__/clob-api.test.js.map +1 -0
  7. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  8. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  9. package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
  10. package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  11. package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
  12. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
  14. package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
  15. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  16. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  17. package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
  18. package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  19. package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
  20. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  21. package/dist/__tests__/integration/data-api.integration.test.js +161 -0
  22. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
  23. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  24. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
  26. package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  27. package/dist/__tests__/test-utils.d.ts +92 -0
  28. package/dist/__tests__/test-utils.d.ts.map +1 -0
  29. package/dist/__tests__/test-utils.js +143 -0
  30. package/dist/__tests__/test-utils.js.map +1 -0
  31. package/dist/clients/bridge-client.d.ts +388 -0
  32. package/dist/clients/bridge-client.d.ts.map +1 -0
  33. package/dist/clients/bridge-client.js +587 -0
  34. package/dist/clients/bridge-client.js.map +1 -0
  35. package/dist/clients/clob-api.d.ts +318 -0
  36. package/dist/clients/clob-api.d.ts.map +1 -0
  37. package/dist/clients/clob-api.js +388 -0
  38. package/dist/clients/clob-api.js.map +1 -0
  39. package/dist/clients/ctf-client.d.ts +473 -0
  40. package/dist/clients/ctf-client.d.ts.map +1 -0
  41. package/dist/clients/ctf-client.js +915 -0
  42. package/dist/clients/ctf-client.js.map +1 -0
  43. package/dist/clients/data-api.d.ts +134 -0
  44. package/dist/clients/data-api.d.ts.map +1 -0
  45. package/dist/clients/data-api.js +265 -0
  46. package/dist/clients/data-api.js.map +1 -0
  47. package/dist/clients/gamma-api.d.ts +401 -0
  48. package/dist/clients/gamma-api.d.ts.map +1 -0
  49. package/dist/clients/gamma-api.js +352 -0
  50. package/dist/clients/gamma-api.js.map +1 -0
  51. package/dist/clients/trading-client.d.ts +252 -0
  52. package/dist/clients/trading-client.d.ts.map +1 -0
  53. package/dist/clients/trading-client.js +543 -0
  54. package/dist/clients/trading-client.js.map +1 -0
  55. package/dist/clients/websocket-manager.d.ts +100 -0
  56. package/dist/clients/websocket-manager.d.ts.map +1 -0
  57. package/dist/clients/websocket-manager.js +193 -0
  58. package/dist/clients/websocket-manager.js.map +1 -0
  59. package/dist/core/cache-adapter-bridge.d.ts +36 -0
  60. package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
  61. package/dist/core/cache-adapter-bridge.js +81 -0
  62. package/dist/core/cache-adapter-bridge.js.map +1 -0
  63. package/dist/core/cache.d.ts +40 -0
  64. package/dist/core/cache.d.ts.map +1 -0
  65. package/dist/core/cache.js +71 -0
  66. package/dist/core/cache.js.map +1 -0
  67. package/dist/core/errors.d.ts +38 -0
  68. package/dist/core/errors.d.ts.map +1 -0
  69. package/dist/core/errors.js +84 -0
  70. package/dist/core/errors.js.map +1 -0
  71. package/dist/core/rate-limiter.d.ts +31 -0
  72. package/dist/core/rate-limiter.d.ts.map +1 -0
  73. package/dist/core/rate-limiter.js +70 -0
  74. package/dist/core/rate-limiter.js.map +1 -0
  75. package/dist/core/types.d.ts +314 -0
  76. package/dist/core/types.d.ts.map +1 -0
  77. package/dist/core/types.js +19 -0
  78. package/dist/core/types.js.map +1 -0
  79. package/dist/core/unified-cache.d.ts +63 -0
  80. package/dist/core/unified-cache.d.ts.map +1 -0
  81. package/dist/core/unified-cache.js +114 -0
  82. package/dist/core/unified-cache.js.map +1 -0
  83. package/dist/index.d.ts +94 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +258 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/mcp/errors.d.ts +33 -0
  88. package/dist/mcp/errors.d.ts.map +1 -0
  89. package/dist/mcp/errors.js +86 -0
  90. package/dist/mcp/errors.js.map +1 -0
  91. package/dist/mcp/index.d.ts +62 -0
  92. package/dist/mcp/index.d.ts.map +1 -0
  93. package/dist/mcp/index.js +173 -0
  94. package/dist/mcp/index.js.map +1 -0
  95. package/dist/mcp/server.d.ts +17 -0
  96. package/dist/mcp/server.d.ts.map +1 -0
  97. package/dist/mcp/server.js +155 -0
  98. package/dist/mcp/server.js.map +1 -0
  99. package/dist/mcp/tools/guide.d.ts +12 -0
  100. package/dist/mcp/tools/guide.d.ts.map +1 -0
  101. package/dist/mcp/tools/guide.js +801 -0
  102. package/dist/mcp/tools/guide.js.map +1 -0
  103. package/dist/mcp/tools/index.d.ts +11 -0
  104. package/dist/mcp/tools/index.d.ts.map +1 -0
  105. package/dist/mcp/tools/index.js +27 -0
  106. package/dist/mcp/tools/index.js.map +1 -0
  107. package/dist/mcp/tools/market.d.ts +11 -0
  108. package/dist/mcp/tools/market.d.ts.map +1 -0
  109. package/dist/mcp/tools/market.js +314 -0
  110. package/dist/mcp/tools/market.js.map +1 -0
  111. package/dist/mcp/tools/order.d.ts +10 -0
  112. package/dist/mcp/tools/order.d.ts.map +1 -0
  113. package/dist/mcp/tools/order.js +258 -0
  114. package/dist/mcp/tools/order.js.map +1 -0
  115. package/dist/mcp/tools/trade.d.ts +38 -0
  116. package/dist/mcp/tools/trade.d.ts.map +1 -0
  117. package/dist/mcp/tools/trade.js +314 -0
  118. package/dist/mcp/tools/trade.js.map +1 -0
  119. package/dist/mcp/tools/trader.d.ts +11 -0
  120. package/dist/mcp/tools/trader.d.ts.map +1 -0
  121. package/dist/mcp/tools/trader.js +277 -0
  122. package/dist/mcp/tools/trader.js.map +1 -0
  123. package/dist/mcp/tools/wallet.d.ts +274 -0
  124. package/dist/mcp/tools/wallet.d.ts.map +1 -0
  125. package/dist/mcp/tools/wallet.js +579 -0
  126. package/dist/mcp/tools/wallet.js.map +1 -0
  127. package/dist/mcp/types.d.ts +413 -0
  128. package/dist/mcp/types.d.ts.map +1 -0
  129. package/dist/mcp/types.js +5 -0
  130. package/dist/mcp/types.js.map +1 -0
  131. package/dist/services/authorization-service.d.ts +97 -0
  132. package/dist/services/authorization-service.d.ts.map +1 -0
  133. package/dist/services/authorization-service.js +279 -0
  134. package/dist/services/authorization-service.js.map +1 -0
  135. package/dist/services/market-service.d.ts +108 -0
  136. package/dist/services/market-service.d.ts.map +1 -0
  137. package/dist/services/market-service.js +458 -0
  138. package/dist/services/market-service.js.map +1 -0
  139. package/dist/services/realtime-service.d.ts +82 -0
  140. package/dist/services/realtime-service.d.ts.map +1 -0
  141. package/dist/services/realtime-service.js +150 -0
  142. package/dist/services/realtime-service.js.map +1 -0
  143. package/dist/services/swap-service.d.ts +217 -0
  144. package/dist/services/swap-service.d.ts.map +1 -0
  145. package/dist/services/swap-service.js +695 -0
  146. package/dist/services/swap-service.js.map +1 -0
  147. package/dist/services/wallet-service.d.ts +94 -0
  148. package/dist/services/wallet-service.d.ts.map +1 -0
  149. package/dist/services/wallet-service.js +173 -0
  150. package/dist/services/wallet-service.js.map +1 -0
  151. package/dist/utils/price-utils.d.ts +153 -0
  152. package/dist/utils/price-utils.d.ts.map +1 -0
  153. package/dist/utils/price-utils.js +236 -0
  154. package/dist/utils/price-utils.js.map +1 -0
  155. package/docs/00-design.md +760 -0
  156. package/docs/01-mcp.md +2041 -0
  157. package/docs/02-API.md +1148 -0
  158. package/docs/e2e/01-trader-tools.md +159 -0
  159. package/docs/e2e/02-market-tools.md +180 -0
  160. package/docs/e2e/03-order-tools.md +166 -0
  161. package/docs/e2e/04-wallet-tools.md +224 -0
  162. package/docs/e2e/05-trading-tools.md +327 -0
  163. package/docs/e2e/06-integration-scenarios.md +481 -0
  164. package/docs/e2e/coordinator.md +376 -0
  165. package/examples/01-basic-usage.ts +68 -0
  166. package/examples/02-smart-money.ts +95 -0
  167. package/examples/03-market-analysis.ts +108 -0
  168. package/examples/04-kline-aggregation.ts +158 -0
  169. package/examples/05-follow-wallet-strategy.ts +156 -0
  170. package/examples/06-services-demo.ts +124 -0
  171. package/examples/07-realtime-websocket.ts +117 -0
  172. package/examples/08-trading-orders.ts +278 -0
  173. package/examples/09-rewards-tracking.ts +187 -0
  174. package/examples/10-ctf-operations.ts +336 -0
  175. package/examples/11-live-arbitrage-scan.ts +221 -0
  176. package/examples/12-trending-arb-monitor.ts +406 -0
  177. package/examples/README.md +179 -0
  178. package/package.json +62 -0
  179. package/scripts/README.md +163 -0
  180. package/scripts/approvals/approve-erc1155.ts +129 -0
  181. package/scripts/approvals/approve-neg-risk-erc1155.ts +149 -0
  182. package/scripts/approvals/approve-neg-risk.ts +102 -0
  183. package/scripts/approvals/check-all-allowances.ts +150 -0
  184. package/scripts/approvals/check-allowance.ts +129 -0
  185. package/scripts/approvals/check-ctf-approval.ts +158 -0
  186. package/scripts/datas/001-report.md +486 -0
  187. package/scripts/datas/clone-modal-screenshot.png +0 -0
  188. package/scripts/deposit/deposit-native-usdc.ts +179 -0
  189. package/scripts/deposit/deposit-usdc.ts +155 -0
  190. package/scripts/deposit/swap-usdc-to-usdce.ts +375 -0
  191. package/scripts/research/research-markets.ts +166 -0
  192. package/scripts/trading/check-orders.ts +50 -0
  193. package/scripts/trading/sell-nvidia-positions.ts +206 -0
  194. package/scripts/trading/test-order.ts +172 -0
  195. package/scripts/truth.md +440 -0
  196. package/scripts/verify/test-approve-trading.ts +98 -0
  197. package/scripts/verify/test-provider-fix.ts +43 -0
  198. package/scripts/verify/test-search-mcp.ts +113 -0
  199. package/scripts/verify/verify-all-apis.ts +160 -0
  200. package/scripts/wallet/check-wallet-balances.ts +75 -0
  201. package/scripts/wallet/test-wallet-operations.ts +191 -0
  202. package/scripts/wallet/verify-wallet-tools.ts +124 -0
  203. package/src/__tests__/clob-api.test.ts +301 -0
  204. package/src/__tests__/integration/bridge-client.integration.test.ts +314 -0
  205. package/src/__tests__/integration/clob-api.integration.test.ts +218 -0
  206. package/src/__tests__/integration/ctf-client.integration.test.ts +331 -0
  207. package/src/__tests__/integration/data-api.integration.test.ts +194 -0
  208. package/src/__tests__/integration/gamma-api.integration.test.ts +206 -0
  209. package/src/__tests__/test-utils.ts +170 -0
  210. package/src/clients/bridge-client.ts +841 -0
  211. package/src/clients/clob-api.ts +629 -0
  212. package/src/clients/ctf-client.ts +1216 -0
  213. package/src/clients/data-api.ts +469 -0
  214. package/src/clients/gamma-api.ts +597 -0
  215. package/src/clients/trading-client.ts +749 -0
  216. package/src/clients/websocket-manager.ts +267 -0
  217. package/src/core/cache-adapter-bridge.ts +94 -0
  218. package/src/core/cache.ts +85 -0
  219. package/src/core/errors.ts +117 -0
  220. package/src/core/rate-limiter.ts +74 -0
  221. package/src/core/types.ts +360 -0
  222. package/src/core/unified-cache.ts +153 -0
  223. package/src/index.ts +455 -0
  224. package/src/mcp/README.md +380 -0
  225. package/src/mcp/errors.ts +124 -0
  226. package/src/mcp/index.ts +309 -0
  227. package/src/mcp/server.ts +183 -0
  228. package/src/mcp/tools/guide.ts +821 -0
  229. package/src/mcp/tools/index.ts +73 -0
  230. package/src/mcp/tools/market.ts +363 -0
  231. package/src/mcp/tools/order.ts +326 -0
  232. package/src/mcp/tools/trade.ts +417 -0
  233. package/src/mcp/tools/trader.ts +322 -0
  234. package/src/mcp/tools/wallet.ts +683 -0
  235. package/src/mcp/types.ts +472 -0
  236. package/src/services/authorization-service.ts +357 -0
  237. package/src/services/market-service.ts +544 -0
  238. package/src/services/realtime-service.ts +196 -0
  239. package/src/services/swap-service.ts +896 -0
  240. package/src/services/wallet-service.ts +259 -0
  241. package/src/utils/price-utils.ts +307 -0
  242. package/tsconfig.json +8 -0
  243. package/vitest.config.ts +19 -0
  244. package/vitest.integration.config.ts +18 -0
package/src/index.ts ADDED
@@ -0,0 +1,455 @@
1
+ /**
2
+ * @prediction-router/poly-sdk
3
+ *
4
+ * Unified SDK for Polymarket APIs
5
+ * - Data API (positions, activity, trades, leaderboard)
6
+ * - Gamma API (markets, events, trending)
7
+ * - CLOB API (orderbook, market info, trading)
8
+ * - Services (WalletService, MarketService)
9
+ */
10
+
11
+ // Core infrastructure
12
+ export { RateLimiter, ApiType } from './core/rate-limiter.js';
13
+ export { Cache, CACHE_TTL } from './core/cache.js';
14
+ export { PolymarketError, ErrorCode, withRetry } from './core/errors.js';
15
+ export * from './core/types.js';
16
+
17
+ // Cache integration (new)
18
+ export type { UnifiedCache } from './core/unified-cache.js';
19
+ export { createUnifiedCache } from './core/unified-cache.js';
20
+
21
+ // API Clients
22
+ export { DataApiClient } from './clients/data-api.js';
23
+ export type {
24
+ Position,
25
+ Activity,
26
+ Trade,
27
+ LeaderboardEntry,
28
+ LeaderboardPage,
29
+ } from './clients/data-api.js';
30
+
31
+ export { GammaApiClient } from './clients/gamma-api.js';
32
+ export type {
33
+ GammaMarket,
34
+ GammaEvent,
35
+ MarketSearchParams,
36
+ } from './clients/gamma-api.js';
37
+
38
+ export { ClobApiClient } from './clients/clob-api.js';
39
+ export type {
40
+ ClobMarket,
41
+ ClobToken,
42
+ Orderbook,
43
+ OrderbookLevel,
44
+ } from './clients/clob-api.js';
45
+
46
+ // Services
47
+ export { WalletService } from './services/wallet-service.js';
48
+ export type {
49
+ WalletProfile,
50
+ WalletActivitySummary,
51
+ SellActivityResult,
52
+ } from './services/wallet-service.js';
53
+
54
+ export { MarketService, getIntervalMs as getIntervalMsService } from './services/market-service.js';
55
+
56
+ // Real-time
57
+ export { WebSocketManager } from './clients/websocket-manager.js';
58
+ export type { WebSocketManagerConfig, WebSocketManagerEvents } from './clients/websocket-manager.js';
59
+
60
+ export { RealtimeService } from './services/realtime-service.js';
61
+ export type { Subscription, MarketSubscriptionHandlers } from './services/realtime-service.js';
62
+
63
+ // NOTE: ArbitrageService has been moved to @prediction-router/arb package
64
+ // See packages/arb/src/services/arbitrage-service.ts
65
+
66
+ // Trading
67
+ export { TradingClient, POLYGON_MAINNET, POLYGON_AMOY } from './clients/trading-client.js';
68
+ export type {
69
+ Side,
70
+ OrderType,
71
+ ApiCredentials,
72
+ OrderParams,
73
+ MarketOrderParams,
74
+ Order,
75
+ OrderResult,
76
+ TradeInfo,
77
+ TradingClientConfig,
78
+ // Rewards types
79
+ UserEarning,
80
+ MarketReward,
81
+ OrderScoring,
82
+ } from './clients/trading-client.js';
83
+
84
+ // CTF (Conditional Token Framework)
85
+ // NOTE: USDC_CONTRACT is USDC.e (bridged), required for Polymarket CTF
86
+ // NATIVE_USDC_CONTRACT is native USDC, NOT compatible with CTF
87
+ export {
88
+ CTFClient,
89
+ CTF_CONTRACT,
90
+ USDC_CONTRACT, // USDC.e (0x2791...) - Required for CTF
91
+ NATIVE_USDC_CONTRACT, // Native USDC (0x3c49...) - NOT for CTF
92
+ NEG_RISK_CTF_EXCHANGE,
93
+ NEG_RISK_ADAPTER,
94
+ USDC_DECIMALS,
95
+ calculateConditionId,
96
+ parseUsdc,
97
+ formatUsdc,
98
+ } from './clients/ctf-client.js';
99
+ export type {
100
+ CTFConfig,
101
+ SplitResult,
102
+ MergeResult,
103
+ RedeemResult,
104
+ PositionBalance,
105
+ MarketResolution,
106
+ GasEstimate,
107
+ TransactionStatus,
108
+ TokenIds,
109
+ } from './clients/ctf-client.js';
110
+ export { RevertReason } from './clients/ctf-client.js';
111
+
112
+ // Bridge (Cross-chain Deposits)
113
+ export {
114
+ BridgeClient,
115
+ SUPPORTED_CHAINS,
116
+ BRIDGE_TOKENS,
117
+ estimateBridgeOutput,
118
+ getExplorerUrl,
119
+ depositUsdc,
120
+ swapAndDeposit,
121
+ getSupportedDepositTokens,
122
+ } from './clients/bridge-client.js';
123
+ export type {
124
+ BridgeSupportedAsset,
125
+ DepositAddress,
126
+ CreateDepositResponse,
127
+ DepositStatus,
128
+ BridgeConfig,
129
+ DepositResult,
130
+ DepositOptions,
131
+ SwapAndDepositOptions,
132
+ SwapAndDepositResult,
133
+ } from './clients/bridge-client.js';
134
+
135
+ // Swap Service (DEX swaps on Polygon)
136
+ export {
137
+ SwapService,
138
+ QUICKSWAP_ROUTER,
139
+ POLYGON_TOKENS,
140
+ TOKEN_DECIMALS,
141
+ } from './services/swap-service.js';
142
+ export type {
143
+ SupportedToken,
144
+ SwapQuote,
145
+ SwapResult,
146
+ TokenBalance,
147
+ TransferResult,
148
+ } from './services/swap-service.js';
149
+
150
+ // Authorization (ERC20/ERC1155 Approvals)
151
+ export { AuthorizationService } from './services/authorization-service.js';
152
+ export type {
153
+ AllowanceInfo,
154
+ AllowancesResult,
155
+ ApprovalTxResult,
156
+ ApprovalsResult,
157
+ AuthorizationServiceConfig,
158
+ } from './services/authorization-service.js';
159
+
160
+ // Price Utilities
161
+ export {
162
+ roundPrice,
163
+ roundSize,
164
+ validatePrice,
165
+ validateSize,
166
+ calculateBuyAmount,
167
+ calculateSellPayout,
168
+ calculateSharesForAmount,
169
+ calculateSpread,
170
+ calculateMidpoint,
171
+ formatPrice,
172
+ formatUSDC,
173
+ calculatePnL,
174
+ checkArbitrage,
175
+ getEffectivePrices,
176
+ ROUNDING_CONFIG,
177
+ } from './utils/price-utils.js';
178
+ export type { TickSize } from './utils/price-utils.js';
179
+
180
+ // NOTE: ArbitrageService has been moved to @prediction-router/arb package
181
+ // See packages/arb/src/services/arbitrage-service.ts
182
+
183
+ // MCP (Model Context Protocol) Tools
184
+ export {
185
+ createMcpHandler,
186
+ registerMcpTools,
187
+ getToolDefinitions,
188
+ allToolDefinitions,
189
+ } from './mcp/index.js';
190
+ export type {
191
+ ToolHandler,
192
+ ToolDefinition,
193
+ McpErrorResponse,
194
+ } from './mcp/index.js';
195
+ export { McpToolError, ErrorCode as McpErrorCode } from './mcp/errors.js';
196
+
197
+ // ===== Main SDK Class =====
198
+
199
+ import { RateLimiter } from './core/rate-limiter.js';
200
+ import { DataApiClient } from './clients/data-api.js';
201
+ import { GammaApiClient } from './clients/gamma-api.js';
202
+ import { ClobApiClient } from './clients/clob-api.js';
203
+ import { WalletService } from './services/wallet-service.js';
204
+ import { MarketService } from './services/market-service.js';
205
+ import type { UnifiedMarket, ProcessedOrderbook, ArbitrageOpportunity, KLineInterval, KLineCandle, DualKLineData, PolySDKOptions } from './core/types.js';
206
+ import { PolymarketError, ErrorCode } from './core/errors.js';
207
+ import { createUnifiedCache, type UnifiedCache } from './core/unified-cache.js';
208
+
209
+ // Re-export for backward compatibility
210
+ export interface PolymarketSDKConfig extends PolySDKOptions {}
211
+
212
+ export class PolymarketSDK {
213
+ // Infrastructure
214
+ private rateLimiter: RateLimiter;
215
+ private cache: UnifiedCache;
216
+
217
+ // API Clients
218
+ public readonly dataApi: DataApiClient;
219
+ public readonly gammaApi: GammaApiClient;
220
+ public readonly clobApi: ClobApiClient;
221
+
222
+ // Services
223
+ public readonly wallets: WalletService;
224
+ public readonly markets: MarketService;
225
+
226
+ constructor(config: PolymarketSDKConfig = {}) {
227
+ // Initialize infrastructure
228
+ this.rateLimiter = new RateLimiter();
229
+
230
+ // Create unified cache (supports both legacy Cache and CacheAdapter)
231
+ this.cache = createUnifiedCache(config.cache);
232
+
233
+ // Initialize API clients
234
+ this.dataApi = new DataApiClient(this.rateLimiter, this.cache);
235
+ this.gammaApi = new GammaApiClient(this.rateLimiter, this.cache);
236
+ this.clobApi = new ClobApiClient(this.rateLimiter, this.cache, {
237
+ chainId: config.chainId,
238
+ signer: config.signer,
239
+ creds: config.creds,
240
+ });
241
+
242
+ // Initialize services
243
+ this.wallets = new WalletService(this.dataApi, this.cache);
244
+ this.markets = new MarketService(this.gammaApi, this.clobApi, this.dataApi, this.cache);
245
+ }
246
+
247
+ // ===== Unified Market Access =====
248
+
249
+ /**
250
+ * Get market by slug or condition ID
251
+ * Uses Gamma for slug, CLOB for conditionId
252
+ */
253
+ async getMarket(identifier: string): Promise<UnifiedMarket> {
254
+ const isConditionId =
255
+ identifier.startsWith('0x') || /^\d+$/.test(identifier);
256
+
257
+ if (isConditionId) {
258
+ return this.getMarketByConditionId(identifier);
259
+ } else {
260
+ return this.getMarketBySlug(identifier);
261
+ }
262
+ }
263
+
264
+ private async getMarketBySlug(slug: string): Promise<UnifiedMarket> {
265
+ // Gamma as primary source for slug
266
+ const gammaMarket = await this.gammaApi.getMarketBySlug(slug);
267
+ if (!gammaMarket) {
268
+ throw new PolymarketError(
269
+ ErrorCode.MARKET_NOT_FOUND,
270
+ `Market not found: ${slug}`
271
+ );
272
+ }
273
+
274
+ // Enrich with CLOB data
275
+ try {
276
+ const clobMarket = await this.clobApi.getMarket(gammaMarket.conditionId);
277
+ return this.mergeMarkets(gammaMarket, clobMarket);
278
+ } catch {
279
+ return this.fromGammaMarket(gammaMarket);
280
+ }
281
+ }
282
+
283
+ private async getMarketByConditionId(
284
+ conditionId: string
285
+ ): Promise<UnifiedMarket> {
286
+ // CLOB as primary source for conditionId (more reliable)
287
+ try {
288
+ const clobMarket = await this.clobApi.getMarket(conditionId);
289
+
290
+ // Try to enrich with Gamma data
291
+ try {
292
+ const gammaMarket =
293
+ await this.gammaApi.getMarketByConditionId(conditionId);
294
+ if (gammaMarket) {
295
+ return this.mergeMarkets(gammaMarket, clobMarket);
296
+ }
297
+ } catch {
298
+ // Gamma enrichment failed, use CLOB only
299
+ }
300
+
301
+ return this.fromClobMarket(clobMarket);
302
+ } catch {
303
+ throw new PolymarketError(
304
+ ErrorCode.MARKET_NOT_FOUND,
305
+ `Market not found: ${conditionId}`
306
+ );
307
+ }
308
+ }
309
+
310
+ // ===== Orderbook Analysis =====
311
+
312
+ /**
313
+ * Get processed orderbook with analytics
314
+ */
315
+ async getOrderbook(conditionId: string): Promise<ProcessedOrderbook> {
316
+ return this.clobApi.getProcessedOrderbook(conditionId);
317
+ }
318
+
319
+ /**
320
+ * Detect arbitrage opportunity
321
+ *
322
+ * 使用有效价格计算套利机会(正确考虑镜像订单)
323
+ * 详细文档见: docs/01-polymarket-orderbook-arbitrage.md
324
+ */
325
+ async detectArbitrage(
326
+ conditionId: string,
327
+ threshold = 0.005
328
+ ): Promise<ArbitrageOpportunity | null> {
329
+ const orderbook = await this.getOrderbook(conditionId);
330
+ const { effectivePrices, longArbProfit, shortArbProfit } = orderbook.summary;
331
+
332
+ if (longArbProfit > threshold) {
333
+ return {
334
+ type: 'long',
335
+ profit: longArbProfit,
336
+ action: `Buy YES @ ${effectivePrices.effectiveBuyYes.toFixed(4)} + Buy NO @ ${effectivePrices.effectiveBuyNo.toFixed(4)}, merge for 1 USDC`,
337
+ expectedProfit: longArbProfit,
338
+ };
339
+ }
340
+
341
+ if (shortArbProfit > threshold) {
342
+ return {
343
+ type: 'short',
344
+ profit: shortArbProfit,
345
+ action: `Split 1 USDC, Sell YES @ ${effectivePrices.effectiveSellYes.toFixed(4)} + Sell NO @ ${effectivePrices.effectiveSellNo.toFixed(4)}`,
346
+ expectedProfit: shortArbProfit,
347
+ };
348
+ }
349
+
350
+ return null;
351
+ }
352
+
353
+ // ===== Helper Methods =====
354
+
355
+ private mergeMarkets(
356
+ gamma: import('./clients/gamma-api.js').GammaMarket,
357
+ clob: import('./clients/clob-api.js').ClobMarket
358
+ ): UnifiedMarket {
359
+ const yesToken = clob.tokens.find((t) => t.outcome === 'Yes');
360
+ const noToken = clob.tokens.find((t) => t.outcome === 'No');
361
+
362
+ return {
363
+ conditionId: clob.conditionId,
364
+ slug: gamma.slug,
365
+ question: clob.question,
366
+ description: clob.description || gamma.description,
367
+ tokens: {
368
+ yes: {
369
+ tokenId: yesToken?.tokenId || '',
370
+ price: yesToken?.price || gamma.outcomePrices[0] || 0.5,
371
+ },
372
+ no: {
373
+ tokenId: noToken?.tokenId || '',
374
+ price: noToken?.price || gamma.outcomePrices[1] || 0.5,
375
+ },
376
+ },
377
+ volume: gamma.volume,
378
+ volume24hr: gamma.volume24hr,
379
+ liquidity: gamma.liquidity,
380
+ spread: gamma.spread,
381
+ active: clob.active,
382
+ closed: clob.closed,
383
+ acceptingOrders: clob.acceptingOrders,
384
+ endDate: clob.endDateIso ? new Date(clob.endDateIso) : new Date(),
385
+ source: 'merged',
386
+ };
387
+ }
388
+
389
+ private fromGammaMarket(
390
+ gamma: import('./clients/gamma-api.js').GammaMarket
391
+ ): UnifiedMarket {
392
+ return {
393
+ conditionId: gamma.conditionId,
394
+ slug: gamma.slug,
395
+ question: gamma.question,
396
+ description: gamma.description,
397
+ tokens: {
398
+ yes: { tokenId: '', price: gamma.outcomePrices[0] || 0.5 },
399
+ no: { tokenId: '', price: gamma.outcomePrices[1] || 0.5 },
400
+ },
401
+ volume: gamma.volume,
402
+ volume24hr: gamma.volume24hr,
403
+ liquidity: gamma.liquidity,
404
+ spread: gamma.spread,
405
+ active: gamma.active,
406
+ closed: gamma.closed,
407
+ acceptingOrders: !gamma.closed,
408
+ endDate: gamma.endDate,
409
+ source: 'gamma',
410
+ };
411
+ }
412
+
413
+ private fromClobMarket(
414
+ clob: import('./clients/clob-api.js').ClobMarket
415
+ ): UnifiedMarket {
416
+ const yesToken = clob.tokens.find((t) => t.outcome === 'Yes');
417
+ const noToken = clob.tokens.find((t) => t.outcome === 'No');
418
+
419
+ return {
420
+ conditionId: clob.conditionId,
421
+ slug: clob.marketSlug,
422
+ question: clob.question,
423
+ description: clob.description,
424
+ tokens: {
425
+ yes: { tokenId: yesToken?.tokenId || '', price: yesToken?.price || 0.5 },
426
+ no: { tokenId: noToken?.tokenId || '', price: noToken?.price || 0.5 },
427
+ },
428
+ volume: 0, // CLOB doesn't have volume
429
+ volume24hr: undefined,
430
+ liquidity: 0,
431
+ spread: undefined,
432
+ active: clob.active,
433
+ closed: clob.closed,
434
+ acceptingOrders: clob.acceptingOrders,
435
+ endDate: clob.endDateIso ? new Date(clob.endDateIso) : new Date(),
436
+ source: 'clob',
437
+ };
438
+ }
439
+
440
+ // ===== Cache Management =====
441
+
442
+ /**
443
+ * Clear all cached data
444
+ */
445
+ clearCache(): void {
446
+ this.cache.clear();
447
+ }
448
+
449
+ /**
450
+ * Invalidate cache for a specific market
451
+ */
452
+ invalidateMarketCache(conditionId: string): void {
453
+ this.cache.invalidate(conditionId);
454
+ }
455
+ }