@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.
Files changed (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +354 -78
  3. package/docs/00-design.md +1 -1
  4. package/docs/02-API.md +21 -21
  5. package/docs/arbitrage.md +754 -0
  6. package/docs/reports/smart-money-analysis-2025-12-23-cn.md +840 -0
  7. package/examples/13-arbitrage-service.ts +211 -0
  8. package/examples/README.md +1 -1
  9. package/package.json +19 -19
  10. package/scripts/arb/faze-bo3-arb.ts +385 -0
  11. package/scripts/arb/settle-position.ts +190 -0
  12. package/scripts/arb/token-rebalancer.ts +420 -0
  13. package/scripts/verify/verify-all-apis.ts +1 -1
  14. package/src/clients/clob-api.ts +1 -1
  15. package/src/clients/gamma-api.ts +1 -1
  16. package/src/core/cache-adapter-bridge.ts +1 -1
  17. package/src/core/types.ts +3 -3
  18. package/src/core/unified-cache.ts +1 -1
  19. package/src/index.ts +25 -19
  20. package/src/services/arbitrage-service.ts +1807 -0
  21. package/.env +0 -0
  22. package/dist/__tests__/clob-api.test.d.ts +0 -5
  23. package/dist/__tests__/clob-api.test.d.ts.map +0 -1
  24. package/dist/__tests__/clob-api.test.js +0 -240
  25. package/dist/__tests__/clob-api.test.js.map +0 -1
  26. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +0 -11
  27. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +0 -1
  28. package/dist/__tests__/integration/bridge-client.integration.test.js +0 -260
  29. package/dist/__tests__/integration/bridge-client.integration.test.js.map +0 -1
  30. package/dist/__tests__/integration/clob-api.integration.test.d.ts +0 -13
  31. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +0 -1
  32. package/dist/__tests__/integration/clob-api.integration.test.js +0 -170
  33. package/dist/__tests__/integration/clob-api.integration.test.js.map +0 -1
  34. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +0 -17
  35. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +0 -1
  36. package/dist/__tests__/integration/ctf-client.integration.test.js +0 -234
  37. package/dist/__tests__/integration/ctf-client.integration.test.js.map +0 -1
  38. package/dist/__tests__/integration/data-api.integration.test.d.ts +0 -9
  39. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +0 -1
  40. package/dist/__tests__/integration/data-api.integration.test.js +0 -161
  41. package/dist/__tests__/integration/data-api.integration.test.js.map +0 -1
  42. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +0 -9
  43. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +0 -1
  44. package/dist/__tests__/integration/gamma-api.integration.test.js +0 -170
  45. package/dist/__tests__/integration/gamma-api.integration.test.js.map +0 -1
  46. package/dist/__tests__/test-utils.d.ts +0 -92
  47. package/dist/__tests__/test-utils.d.ts.map +0 -1
  48. package/dist/__tests__/test-utils.js +0 -143
  49. package/dist/__tests__/test-utils.js.map +0 -1
  50. package/dist/clients/bridge-client.d.ts +0 -388
  51. package/dist/clients/bridge-client.d.ts.map +0 -1
  52. package/dist/clients/bridge-client.js +0 -587
  53. package/dist/clients/bridge-client.js.map +0 -1
  54. package/dist/clients/clob-api.d.ts +0 -318
  55. package/dist/clients/clob-api.d.ts.map +0 -1
  56. package/dist/clients/clob-api.js +0 -388
  57. package/dist/clients/clob-api.js.map +0 -1
  58. package/dist/clients/ctf-client.d.ts +0 -473
  59. package/dist/clients/ctf-client.d.ts.map +0 -1
  60. package/dist/clients/ctf-client.js +0 -915
  61. package/dist/clients/ctf-client.js.map +0 -1
  62. package/dist/clients/data-api.d.ts +0 -134
  63. package/dist/clients/data-api.d.ts.map +0 -1
  64. package/dist/clients/data-api.js +0 -265
  65. package/dist/clients/data-api.js.map +0 -1
  66. package/dist/clients/gamma-api.d.ts +0 -401
  67. package/dist/clients/gamma-api.d.ts.map +0 -1
  68. package/dist/clients/gamma-api.js +0 -352
  69. package/dist/clients/gamma-api.js.map +0 -1
  70. package/dist/clients/trading-client.d.ts +0 -252
  71. package/dist/clients/trading-client.d.ts.map +0 -1
  72. package/dist/clients/trading-client.js +0 -543
  73. package/dist/clients/trading-client.js.map +0 -1
  74. package/dist/clients/websocket-manager.d.ts +0 -100
  75. package/dist/clients/websocket-manager.d.ts.map +0 -1
  76. package/dist/clients/websocket-manager.js +0 -193
  77. package/dist/clients/websocket-manager.js.map +0 -1
  78. package/dist/core/cache-adapter-bridge.d.ts +0 -36
  79. package/dist/core/cache-adapter-bridge.d.ts.map +0 -1
  80. package/dist/core/cache-adapter-bridge.js +0 -81
  81. package/dist/core/cache-adapter-bridge.js.map +0 -1
  82. package/dist/core/cache.d.ts +0 -40
  83. package/dist/core/cache.d.ts.map +0 -1
  84. package/dist/core/cache.js +0 -71
  85. package/dist/core/cache.js.map +0 -1
  86. package/dist/core/errors.d.ts +0 -38
  87. package/dist/core/errors.d.ts.map +0 -1
  88. package/dist/core/errors.js +0 -84
  89. package/dist/core/errors.js.map +0 -1
  90. package/dist/core/rate-limiter.d.ts +0 -31
  91. package/dist/core/rate-limiter.d.ts.map +0 -1
  92. package/dist/core/rate-limiter.js +0 -70
  93. package/dist/core/rate-limiter.js.map +0 -1
  94. package/dist/core/types.d.ts +0 -314
  95. package/dist/core/types.d.ts.map +0 -1
  96. package/dist/core/types.js +0 -19
  97. package/dist/core/types.js.map +0 -1
  98. package/dist/core/unified-cache.d.ts +0 -63
  99. package/dist/core/unified-cache.d.ts.map +0 -1
  100. package/dist/core/unified-cache.js +0 -114
  101. package/dist/core/unified-cache.js.map +0 -1
  102. package/dist/index.d.ts +0 -94
  103. package/dist/index.d.ts.map +0 -1
  104. package/dist/index.js +0 -258
  105. package/dist/index.js.map +0 -1
  106. package/dist/mcp/errors.d.ts +0 -33
  107. package/dist/mcp/errors.d.ts.map +0 -1
  108. package/dist/mcp/errors.js +0 -86
  109. package/dist/mcp/errors.js.map +0 -1
  110. package/dist/mcp/index.d.ts +0 -62
  111. package/dist/mcp/index.d.ts.map +0 -1
  112. package/dist/mcp/index.js +0 -173
  113. package/dist/mcp/index.js.map +0 -1
  114. package/dist/mcp/server.d.ts +0 -17
  115. package/dist/mcp/server.d.ts.map +0 -1
  116. package/dist/mcp/server.js +0 -155
  117. package/dist/mcp/server.js.map +0 -1
  118. package/dist/mcp/tools/guide.d.ts +0 -12
  119. package/dist/mcp/tools/guide.d.ts.map +0 -1
  120. package/dist/mcp/tools/guide.js +0 -801
  121. package/dist/mcp/tools/guide.js.map +0 -1
  122. package/dist/mcp/tools/index.d.ts +0 -11
  123. package/dist/mcp/tools/index.d.ts.map +0 -1
  124. package/dist/mcp/tools/index.js +0 -27
  125. package/dist/mcp/tools/index.js.map +0 -1
  126. package/dist/mcp/tools/market.d.ts +0 -11
  127. package/dist/mcp/tools/market.d.ts.map +0 -1
  128. package/dist/mcp/tools/market.js +0 -314
  129. package/dist/mcp/tools/market.js.map +0 -1
  130. package/dist/mcp/tools/order.d.ts +0 -10
  131. package/dist/mcp/tools/order.d.ts.map +0 -1
  132. package/dist/mcp/tools/order.js +0 -258
  133. package/dist/mcp/tools/order.js.map +0 -1
  134. package/dist/mcp/tools/trade.d.ts +0 -38
  135. package/dist/mcp/tools/trade.d.ts.map +0 -1
  136. package/dist/mcp/tools/trade.js +0 -314
  137. package/dist/mcp/tools/trade.js.map +0 -1
  138. package/dist/mcp/tools/trader.d.ts +0 -11
  139. package/dist/mcp/tools/trader.d.ts.map +0 -1
  140. package/dist/mcp/tools/trader.js +0 -277
  141. package/dist/mcp/tools/trader.js.map +0 -1
  142. package/dist/mcp/tools/wallet.d.ts +0 -274
  143. package/dist/mcp/tools/wallet.d.ts.map +0 -1
  144. package/dist/mcp/tools/wallet.js +0 -579
  145. package/dist/mcp/tools/wallet.js.map +0 -1
  146. package/dist/mcp/types.d.ts +0 -413
  147. package/dist/mcp/types.d.ts.map +0 -1
  148. package/dist/mcp/types.js +0 -5
  149. package/dist/mcp/types.js.map +0 -1
  150. package/dist/services/authorization-service.d.ts +0 -97
  151. package/dist/services/authorization-service.d.ts.map +0 -1
  152. package/dist/services/authorization-service.js +0 -279
  153. package/dist/services/authorization-service.js.map +0 -1
  154. package/dist/services/market-service.d.ts +0 -108
  155. package/dist/services/market-service.d.ts.map +0 -1
  156. package/dist/services/market-service.js +0 -458
  157. package/dist/services/market-service.js.map +0 -1
  158. package/dist/services/realtime-service.d.ts +0 -82
  159. package/dist/services/realtime-service.d.ts.map +0 -1
  160. package/dist/services/realtime-service.js +0 -150
  161. package/dist/services/realtime-service.js.map +0 -1
  162. package/dist/services/swap-service.d.ts +0 -217
  163. package/dist/services/swap-service.d.ts.map +0 -1
  164. package/dist/services/swap-service.js +0 -695
  165. package/dist/services/swap-service.js.map +0 -1
  166. package/dist/services/wallet-service.d.ts +0 -94
  167. package/dist/services/wallet-service.d.ts.map +0 -1
  168. package/dist/services/wallet-service.js +0 -173
  169. package/dist/services/wallet-service.js.map +0 -1
  170. package/dist/utils/price-utils.d.ts +0 -153
  171. package/dist/utils/price-utils.d.ts.map +0 -1
  172. package/dist/utils/price-utils.js +0 -236
  173. package/dist/utils/price-utils.js.map +0 -1
  174. package/docs/01-mcp.md +0 -2041
  175. package/docs/e2e/01-trader-tools.md +0 -159
  176. package/docs/e2e/02-market-tools.md +0 -180
  177. package/docs/e2e/03-order-tools.md +0 -166
  178. package/docs/e2e/04-wallet-tools.md +0 -224
  179. package/docs/e2e/05-trading-tools.md +0 -327
  180. package/docs/e2e/06-integration-scenarios.md +0 -481
  181. package/docs/e2e/coordinator.md +0 -376
  182. package/scripts/truth.md +0 -440
  183. package/src/mcp/README.md +0 -380
  184. package/src/mcp/errors.ts +0 -124
  185. package/src/mcp/index.ts +0 -309
  186. package/src/mcp/server.ts +0 -183
  187. package/src/mcp/tools/guide.ts +0 -821
  188. package/src/mcp/tools/index.ts +0 -73
  189. package/src/mcp/tools/market.ts +0 -363
  190. package/src/mcp/tools/order.ts +0 -326
  191. package/src/mcp/tools/trade.ts +0 -417
  192. package/src/mcp/tools/trader.ts +0 -322
  193. package/src/mcp/tools/wallet.ts +0 -683
  194. package/src/mcp/types.ts +0 -472
@@ -1,322 +0,0 @@
1
- /**
2
- * Trader Tools - MCP tools for trader/wallet analysis
3
- */
4
-
5
- import type { PolymarketSDK } from '../../index.js';
6
- import type {
7
- ToolDefinition,
8
- GetTraderPositionsInput,
9
- GetTraderPositionsOutput,
10
- GetTraderTradesInput,
11
- GetTraderTradesOutput,
12
- GetTraderProfileInput,
13
- GetTraderProfileOutput,
14
- GetLeaderboardInput,
15
- GetLeaderboardOutput,
16
- } from '../types.js';
17
- import { validateAddress, wrapError } from '../errors.js';
18
-
19
- export const traderToolDefinitions: ToolDefinition[] = [
20
- {
21
- name: 'get_trader_positions',
22
- description: 'Get all positions held by a trader with PnL breakdown',
23
- inputSchema: {
24
- type: 'object',
25
- properties: {
26
- address: {
27
- type: 'string',
28
- description: 'Trader wallet address (0x...)',
29
- },
30
- },
31
- required: ['address'],
32
- },
33
- },
34
- {
35
- name: 'get_trader_trades',
36
- description: 'Get recent trading activity for a trader',
37
- inputSchema: {
38
- type: 'object',
39
- properties: {
40
- address: {
41
- type: 'string',
42
- description: 'Trader wallet address',
43
- },
44
- limit: {
45
- type: 'number',
46
- description: 'Maximum number of trades to return',
47
- default: 20,
48
- },
49
- side: {
50
- type: 'string',
51
- enum: ['BUY', 'SELL'],
52
- description: 'Filter by trade side',
53
- },
54
- },
55
- required: ['address'],
56
- },
57
- },
58
- {
59
- name: 'get_trader_profile',
60
- description: 'Get comprehensive trader profile with performance metrics',
61
- inputSchema: {
62
- type: 'object',
63
- properties: {
64
- address: {
65
- type: 'string',
66
- description: 'Trader wallet address',
67
- },
68
- },
69
- required: ['address'],
70
- },
71
- },
72
- {
73
- name: 'get_leaderboard',
74
- description: 'Get top traders by PnL',
75
- inputSchema: {
76
- type: 'object',
77
- properties: {
78
- limit: {
79
- type: 'number',
80
- description: 'Number of traders to return',
81
- default: 10,
82
- },
83
- offset: {
84
- type: 'number',
85
- description: 'Pagination offset',
86
- default: 0,
87
- },
88
- },
89
- },
90
- },
91
- ];
92
-
93
- export async function handleGetTraderPositions(
94
- sdk: PolymarketSDK,
95
- input: GetTraderPositionsInput
96
- ): Promise<GetTraderPositionsOutput> {
97
- validateAddress(input.address);
98
-
99
- try {
100
- const positions = await sdk.wallets.getWalletPositions(input.address);
101
-
102
- const totalUnrealizedPnl = positions.reduce((sum, p) => sum + (p.cashPnl || 0), 0);
103
- const totalRealizedPnl = positions.reduce((sum, p) => sum + (p.realizedPnl || 0), 0);
104
- const winningPositions = positions.filter((p) => (p.cashPnl || 0) > 0).length;
105
- const losingPositions = positions.filter((p) => (p.cashPnl || 0) < 0).length;
106
-
107
- return {
108
- trader: {
109
- address: input.address,
110
- displayName: null, // Will be enriched if available
111
- },
112
- positions: positions.map((p) => ({
113
- market: {
114
- conditionId: p.conditionId,
115
- title: p.title,
116
- slug: p.slug,
117
- },
118
- holding: {
119
- outcome: p.outcome,
120
- size: p.size,
121
- avgPrice: p.avgPrice,
122
- curPrice: p.curPrice,
123
- },
124
- pnl: {
125
- unrealized: p.cashPnl,
126
- unrealizedPercent: p.percentPnl,
127
- realized: p.realizedPnl,
128
- },
129
- status: {
130
- redeemable: p.redeemable,
131
- endDate: p.endDate,
132
- },
133
- })),
134
- summary: {
135
- totalPositions: positions.length,
136
- totalUnrealizedPnl,
137
- totalRealizedPnl,
138
- winningPositions,
139
- losingPositions,
140
- },
141
- };
142
- } catch (err) {
143
- throw wrapError(err);
144
- }
145
- }
146
-
147
- export async function handleGetTraderTrades(
148
- sdk: PolymarketSDK,
149
- input: GetTraderTradesInput
150
- ): Promise<GetTraderTradesOutput> {
151
- validateAddress(input.address);
152
-
153
- try {
154
- const activityResult = await sdk.wallets.getWalletActivity(
155
- input.address,
156
- input.limit || 100
157
- );
158
-
159
- let trades = activityResult.activities.filter((a) => a.type === 'TRADE');
160
-
161
- // Filter by side if specified
162
- if (input.side) {
163
- trades = trades.filter((a) => a.side === input.side);
164
- }
165
-
166
- // Apply limit
167
- const limit = input.limit || 20;
168
- trades = trades.slice(0, limit);
169
-
170
- const buyTrades = trades.filter((t) => t.side === 'BUY');
171
- const sellTrades = trades.filter((t) => t.side === 'SELL');
172
-
173
- return {
174
- trader: {
175
- address: input.address,
176
- displayName: null,
177
- },
178
- trades: trades.map((t) => ({
179
- type: t.type,
180
- side: t.side,
181
- market: {
182
- conditionId: t.conditionId,
183
- title: t.title || '',
184
- slug: t.slug,
185
- },
186
- outcome: t.outcome,
187
- execution: {
188
- size: t.size,
189
- price: t.price,
190
- usdcValue: t.usdcSize || t.size * t.price,
191
- },
192
- timestamp: new Date(t.timestamp).toISOString(),
193
- txHash: t.transactionHash,
194
- })),
195
- summary: {
196
- totalTrades: trades.length,
197
- buyCount: buyTrades.length,
198
- sellCount: sellTrades.length,
199
- buyVolume: buyTrades.reduce((sum, t) => sum + (t.usdcSize || t.size * t.price), 0),
200
- sellVolume: sellTrades.reduce((sum, t) => sum + (t.usdcSize || t.size * t.price), 0),
201
- },
202
- };
203
- } catch (err) {
204
- throw wrapError(err);
205
- }
206
- }
207
-
208
- export async function handleGetTraderProfile(
209
- sdk: PolymarketSDK,
210
- input: GetTraderProfileInput
211
- ): Promise<GetTraderProfileOutput> {
212
- validateAddress(input.address);
213
-
214
- try {
215
- const profile = await sdk.wallets.getWalletProfile(input.address);
216
-
217
- // Try to get leaderboard data for rank and official PnL
218
- let rank: number | null = null;
219
- let leaderboardPnl: number | null = null;
220
- let leaderboardVolume: number | null = null;
221
- let displayName: string | null = null;
222
- let verified = false;
223
- try {
224
- const leaderboard = await sdk.wallets.getLeaderboard(0, 100);
225
- const entry = leaderboard.entries.find(
226
- (e) => e.address.toLowerCase() === input.address.toLowerCase()
227
- );
228
- if (entry) {
229
- rank = entry.rank;
230
- leaderboardPnl = entry.pnl;
231
- leaderboardVolume = entry.volume;
232
- displayName = entry.userName || null;
233
- verified = entry.verifiedBadge || false;
234
- }
235
- } catch {
236
- // Ignore leaderboard errors
237
- }
238
-
239
- const winningCount = profile.positionCount > 0
240
- ? Math.round(profile.positionCount * (profile.avgPercentPnL > 0 ? 0.6 : 0.4))
241
- : 0;
242
- const winRate = profile.positionCount > 0
243
- ? winningCount / profile.positionCount
244
- : 0;
245
-
246
- return {
247
- trader: {
248
- address: input.address,
249
- displayName,
250
- xUsername: null,
251
- verified,
252
- profileImage: null,
253
- },
254
- ranking: {
255
- rank,
256
- totalTraders: 10000, // Approximate
257
- },
258
- performance: {
259
- // Official PnL from leaderboard (used for ranking)
260
- officialPnl: leaderboardPnl,
261
- // Volume from leaderboard
262
- totalVolume: leaderboardVolume ?? (profile.totalPnL + profile.unrealizedPnL),
263
- // Calculated PnL from profile positions
264
- unrealizedPnl: profile.unrealizedPnL,
265
- realizedPnl: profile.realizedPnL,
266
- },
267
- stats: {
268
- positionCount: profile.positionCount,
269
- winRate,
270
- avgPercentPnl: profile.avgPercentPnL,
271
- smartScore: profile.smartScore,
272
- },
273
- activity: {
274
- lastTradeAt: profile.lastActiveAt.getTime() > 0
275
- ? profile.lastActiveAt.toISOString()
276
- : null,
277
- isActive: Date.now() - profile.lastActiveAt.getTime() < 7 * 24 * 60 * 60 * 1000,
278
- },
279
- // Explain potential PnL differences
280
- notes: leaderboardPnl !== null && Math.abs((leaderboardPnl || 0) - (profile.unrealizedPnL + profile.realizedPnL)) > 100
281
- ? 'Note: officialPnl (from leaderboard) may differ from unrealizedPnl + realizedPnl (from positions) due to different calculation methods. Leaderboard PnL includes historical settled positions.'
282
- : undefined,
283
- };
284
- } catch (err) {
285
- throw wrapError(err);
286
- }
287
- }
288
-
289
- export async function handleGetLeaderboard(
290
- sdk: PolymarketSDK,
291
- input: GetLeaderboardInput
292
- ): Promise<GetLeaderboardOutput> {
293
- const limit = input.limit || 10;
294
- const offset = input.offset || 0;
295
-
296
- try {
297
- const page = Math.floor(offset / 50);
298
- const leaderboard = await sdk.wallets.getLeaderboard(page, 50);
299
-
300
- // Apply offset and limit within the page
301
- const startIdx = offset % 50;
302
- const entries = leaderboard.entries.slice(startIdx, startIdx + limit);
303
-
304
- return {
305
- traders: entries.map((e) => ({
306
- rank: e.rank,
307
- address: e.address,
308
- displayName: e.userName || null,
309
- pnl: e.pnl,
310
- volume: e.volume,
311
- verified: e.verifiedBadge || false,
312
- })),
313
- pagination: {
314
- total: leaderboard.total,
315
- offset,
316
- limit,
317
- },
318
- };
319
- } catch (err) {
320
- throw wrapError(err);
321
- }
322
- }