@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.
Files changed (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +538 -0
  3. package/README.md +357 -78
  4. package/docs/00-design.md +1 -1
  5. package/docs/02-API.md +21 -21
  6. package/docs/arb/test-plan.md +387 -0
  7. package/docs/arb/test-results.md +336 -0
  8. package/docs/arbitrage.md +754 -0
  9. package/docs/reports/smart-money-analysis-2025-12-23-cn.md +840 -0
  10. package/examples/13-arbitrage-service.ts +211 -0
  11. package/examples/README.md +1 -1
  12. package/package.json +19 -19
  13. package/scripts/arb/faze-bo3-arb.ts +385 -0
  14. package/scripts/arb/settle-position.ts +190 -0
  15. package/scripts/arb/token-rebalancer.ts +420 -0
  16. package/scripts/arb-tests/01-unit-tests.ts +495 -0
  17. package/scripts/arb-tests/02-integration-tests.ts +412 -0
  18. package/scripts/arb-tests/03-e2e-tests.ts +503 -0
  19. package/scripts/arb-tests/README.md +109 -0
  20. package/scripts/verify/verify-all-apis.ts +1 -1
  21. package/src/clients/clob-api.ts +1 -1
  22. package/src/clients/gamma-api.ts +1 -1
  23. package/src/core/cache-adapter-bridge.ts +1 -1
  24. package/src/core/types.ts +3 -3
  25. package/src/core/unified-cache.ts +1 -1
  26. package/src/index.ts +25 -19
  27. package/src/services/arbitrage-service.ts +1807 -0
  28. package/.env +0 -0
  29. package/dist/__tests__/clob-api.test.d.ts +0 -5
  30. package/dist/__tests__/clob-api.test.d.ts.map +0 -1
  31. package/dist/__tests__/clob-api.test.js +0 -240
  32. package/dist/__tests__/clob-api.test.js.map +0 -1
  33. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +0 -11
  34. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +0 -1
  35. package/dist/__tests__/integration/bridge-client.integration.test.js +0 -260
  36. package/dist/__tests__/integration/bridge-client.integration.test.js.map +0 -1
  37. package/dist/__tests__/integration/clob-api.integration.test.d.ts +0 -13
  38. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +0 -1
  39. package/dist/__tests__/integration/clob-api.integration.test.js +0 -170
  40. package/dist/__tests__/integration/clob-api.integration.test.js.map +0 -1
  41. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +0 -17
  42. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +0 -1
  43. package/dist/__tests__/integration/ctf-client.integration.test.js +0 -234
  44. package/dist/__tests__/integration/ctf-client.integration.test.js.map +0 -1
  45. package/dist/__tests__/integration/data-api.integration.test.d.ts +0 -9
  46. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +0 -1
  47. package/dist/__tests__/integration/data-api.integration.test.js +0 -161
  48. package/dist/__tests__/integration/data-api.integration.test.js.map +0 -1
  49. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +0 -9
  50. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +0 -1
  51. package/dist/__tests__/integration/gamma-api.integration.test.js +0 -170
  52. package/dist/__tests__/integration/gamma-api.integration.test.js.map +0 -1
  53. package/dist/__tests__/test-utils.d.ts +0 -92
  54. package/dist/__tests__/test-utils.d.ts.map +0 -1
  55. package/dist/__tests__/test-utils.js +0 -143
  56. package/dist/__tests__/test-utils.js.map +0 -1
  57. package/dist/clients/bridge-client.d.ts +0 -388
  58. package/dist/clients/bridge-client.d.ts.map +0 -1
  59. package/dist/clients/bridge-client.js +0 -587
  60. package/dist/clients/bridge-client.js.map +0 -1
  61. package/dist/clients/clob-api.d.ts +0 -318
  62. package/dist/clients/clob-api.d.ts.map +0 -1
  63. package/dist/clients/clob-api.js +0 -388
  64. package/dist/clients/clob-api.js.map +0 -1
  65. package/dist/clients/ctf-client.d.ts +0 -473
  66. package/dist/clients/ctf-client.d.ts.map +0 -1
  67. package/dist/clients/ctf-client.js +0 -915
  68. package/dist/clients/ctf-client.js.map +0 -1
  69. package/dist/clients/data-api.d.ts +0 -134
  70. package/dist/clients/data-api.d.ts.map +0 -1
  71. package/dist/clients/data-api.js +0 -265
  72. package/dist/clients/data-api.js.map +0 -1
  73. package/dist/clients/gamma-api.d.ts +0 -401
  74. package/dist/clients/gamma-api.d.ts.map +0 -1
  75. package/dist/clients/gamma-api.js +0 -352
  76. package/dist/clients/gamma-api.js.map +0 -1
  77. package/dist/clients/trading-client.d.ts +0 -252
  78. package/dist/clients/trading-client.d.ts.map +0 -1
  79. package/dist/clients/trading-client.js +0 -543
  80. package/dist/clients/trading-client.js.map +0 -1
  81. package/dist/clients/websocket-manager.d.ts +0 -100
  82. package/dist/clients/websocket-manager.d.ts.map +0 -1
  83. package/dist/clients/websocket-manager.js +0 -193
  84. package/dist/clients/websocket-manager.js.map +0 -1
  85. package/dist/core/cache-adapter-bridge.d.ts +0 -36
  86. package/dist/core/cache-adapter-bridge.d.ts.map +0 -1
  87. package/dist/core/cache-adapter-bridge.js +0 -81
  88. package/dist/core/cache-adapter-bridge.js.map +0 -1
  89. package/dist/core/cache.d.ts +0 -40
  90. package/dist/core/cache.d.ts.map +0 -1
  91. package/dist/core/cache.js +0 -71
  92. package/dist/core/cache.js.map +0 -1
  93. package/dist/core/errors.d.ts +0 -38
  94. package/dist/core/errors.d.ts.map +0 -1
  95. package/dist/core/errors.js +0 -84
  96. package/dist/core/errors.js.map +0 -1
  97. package/dist/core/rate-limiter.d.ts +0 -31
  98. package/dist/core/rate-limiter.d.ts.map +0 -1
  99. package/dist/core/rate-limiter.js +0 -70
  100. package/dist/core/rate-limiter.js.map +0 -1
  101. package/dist/core/types.d.ts +0 -314
  102. package/dist/core/types.d.ts.map +0 -1
  103. package/dist/core/types.js +0 -19
  104. package/dist/core/types.js.map +0 -1
  105. package/dist/core/unified-cache.d.ts +0 -63
  106. package/dist/core/unified-cache.d.ts.map +0 -1
  107. package/dist/core/unified-cache.js +0 -114
  108. package/dist/core/unified-cache.js.map +0 -1
  109. package/dist/index.d.ts +0 -94
  110. package/dist/index.d.ts.map +0 -1
  111. package/dist/index.js +0 -258
  112. package/dist/index.js.map +0 -1
  113. package/dist/mcp/errors.d.ts +0 -33
  114. package/dist/mcp/errors.d.ts.map +0 -1
  115. package/dist/mcp/errors.js +0 -86
  116. package/dist/mcp/errors.js.map +0 -1
  117. package/dist/mcp/index.d.ts +0 -62
  118. package/dist/mcp/index.d.ts.map +0 -1
  119. package/dist/mcp/index.js +0 -173
  120. package/dist/mcp/index.js.map +0 -1
  121. package/dist/mcp/server.d.ts +0 -17
  122. package/dist/mcp/server.d.ts.map +0 -1
  123. package/dist/mcp/server.js +0 -155
  124. package/dist/mcp/server.js.map +0 -1
  125. package/dist/mcp/tools/guide.d.ts +0 -12
  126. package/dist/mcp/tools/guide.d.ts.map +0 -1
  127. package/dist/mcp/tools/guide.js +0 -801
  128. package/dist/mcp/tools/guide.js.map +0 -1
  129. package/dist/mcp/tools/index.d.ts +0 -11
  130. package/dist/mcp/tools/index.d.ts.map +0 -1
  131. package/dist/mcp/tools/index.js +0 -27
  132. package/dist/mcp/tools/index.js.map +0 -1
  133. package/dist/mcp/tools/market.d.ts +0 -11
  134. package/dist/mcp/tools/market.d.ts.map +0 -1
  135. package/dist/mcp/tools/market.js +0 -314
  136. package/dist/mcp/tools/market.js.map +0 -1
  137. package/dist/mcp/tools/order.d.ts +0 -10
  138. package/dist/mcp/tools/order.d.ts.map +0 -1
  139. package/dist/mcp/tools/order.js +0 -258
  140. package/dist/mcp/tools/order.js.map +0 -1
  141. package/dist/mcp/tools/trade.d.ts +0 -38
  142. package/dist/mcp/tools/trade.d.ts.map +0 -1
  143. package/dist/mcp/tools/trade.js +0 -314
  144. package/dist/mcp/tools/trade.js.map +0 -1
  145. package/dist/mcp/tools/trader.d.ts +0 -11
  146. package/dist/mcp/tools/trader.d.ts.map +0 -1
  147. package/dist/mcp/tools/trader.js +0 -277
  148. package/dist/mcp/tools/trader.js.map +0 -1
  149. package/dist/mcp/tools/wallet.d.ts +0 -274
  150. package/dist/mcp/tools/wallet.d.ts.map +0 -1
  151. package/dist/mcp/tools/wallet.js +0 -579
  152. package/dist/mcp/tools/wallet.js.map +0 -1
  153. package/dist/mcp/types.d.ts +0 -413
  154. package/dist/mcp/types.d.ts.map +0 -1
  155. package/dist/mcp/types.js +0 -5
  156. package/dist/mcp/types.js.map +0 -1
  157. package/dist/services/authorization-service.d.ts +0 -97
  158. package/dist/services/authorization-service.d.ts.map +0 -1
  159. package/dist/services/authorization-service.js +0 -279
  160. package/dist/services/authorization-service.js.map +0 -1
  161. package/dist/services/market-service.d.ts +0 -108
  162. package/dist/services/market-service.d.ts.map +0 -1
  163. package/dist/services/market-service.js +0 -458
  164. package/dist/services/market-service.js.map +0 -1
  165. package/dist/services/realtime-service.d.ts +0 -82
  166. package/dist/services/realtime-service.d.ts.map +0 -1
  167. package/dist/services/realtime-service.js +0 -150
  168. package/dist/services/realtime-service.js.map +0 -1
  169. package/dist/services/swap-service.d.ts +0 -217
  170. package/dist/services/swap-service.d.ts.map +0 -1
  171. package/dist/services/swap-service.js +0 -695
  172. package/dist/services/swap-service.js.map +0 -1
  173. package/dist/services/wallet-service.d.ts +0 -94
  174. package/dist/services/wallet-service.d.ts.map +0 -1
  175. package/dist/services/wallet-service.js +0 -173
  176. package/dist/services/wallet-service.js.map +0 -1
  177. package/dist/utils/price-utils.d.ts +0 -153
  178. package/dist/utils/price-utils.d.ts.map +0 -1
  179. package/dist/utils/price-utils.js +0 -236
  180. package/dist/utils/price-utils.js.map +0 -1
  181. package/docs/01-mcp.md +0 -2041
  182. package/docs/e2e/01-trader-tools.md +0 -159
  183. package/docs/e2e/02-market-tools.md +0 -180
  184. package/docs/e2e/03-order-tools.md +0 -166
  185. package/docs/e2e/04-wallet-tools.md +0 -224
  186. package/docs/e2e/05-trading-tools.md +0 -327
  187. package/docs/e2e/06-integration-scenarios.md +0 -481
  188. package/docs/e2e/coordinator.md +0 -376
  189. package/scripts/truth.md +0 -440
  190. package/src/mcp/README.md +0 -380
  191. package/src/mcp/errors.ts +0 -124
  192. package/src/mcp/index.ts +0 -309
  193. package/src/mcp/server.ts +0 -183
  194. package/src/mcp/tools/guide.ts +0 -821
  195. package/src/mcp/tools/index.ts +0 -73
  196. package/src/mcp/tools/market.ts +0 -363
  197. package/src/mcp/tools/order.ts +0 -326
  198. package/src/mcp/tools/trade.ts +0 -417
  199. package/src/mcp/tools/trader.ts +0 -322
  200. package/src/mcp/tools/wallet.ts +0 -683
  201. 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
- }