@catalyst-team/poly-sdk 0.4.3 → 0.4.5
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/dist/src/core/order-status.d.ts +159 -0
- package/dist/src/core/order-status.d.ts.map +1 -0
- package/dist/src/core/order-status.js +254 -0
- package/dist/src/core/order-status.js.map +1 -0
- package/dist/src/core/types.d.ts +124 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js +120 -0
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/services/ctf-detector.d.ts +215 -0
- package/dist/src/services/ctf-detector.d.ts.map +1 -0
- package/dist/src/services/ctf-detector.js +420 -0
- package/dist/src/services/ctf-detector.js.map +1 -0
- package/dist/src/services/ctf-manager.d.ts +202 -0
- package/dist/src/services/ctf-manager.d.ts.map +1 -0
- package/dist/src/services/ctf-manager.js +542 -0
- package/dist/src/services/ctf-manager.js.map +1 -0
- package/dist/src/services/order-manager.d.ts +281 -0
- package/dist/src/services/order-manager.d.ts.map +1 -0
- package/dist/src/services/order-manager.js +641 -0
- package/dist/src/services/order-manager.js.map +1 -0
- package/dist/src/services/order-manager.test.d.ts +8 -0
- package/dist/src/services/order-manager.test.d.ts.map +1 -0
- package/dist/src/services/order-manager.test.js +477 -0
- package/dist/src/services/order-manager.test.js.map +1 -0
- package/dist/src/services/trading-service.d.ts +89 -1
- package/dist/src/services/trading-service.d.ts.map +1 -1
- package/dist/src/services/trading-service.js +227 -1
- package/dist/src/services/trading-service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CTF Detector
|
|
3
|
+
*
|
|
4
|
+
* Monitors Conditional Token Framework (CTF) operations:
|
|
5
|
+
* - Split: USDC → YES + NO tokens
|
|
6
|
+
* - Merge: YES + NO tokens → USDC
|
|
7
|
+
* - Redeem: Winning token → USDC (after market resolution)
|
|
8
|
+
*
|
|
9
|
+
* Detection Methods:
|
|
10
|
+
* - WebSocket: ERC1155 Transfer events (primary, low-latency)
|
|
11
|
+
* - Polling: Balance changes (backup, reliable)
|
|
12
|
+
*
|
|
13
|
+
* ERC1155 Transfer Event Patterns:
|
|
14
|
+
* - Split: Transfer(from=0x0, to=user, tokenId=YES/NO, amount)
|
|
15
|
+
* - Merge: Transfer(from=user, to=0x0, tokenId=YES/NO, amount)
|
|
16
|
+
* - Redeem: Transfer(from=user, to=0x0, tokenId=winningToken, amount)
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* ```ts
|
|
20
|
+
* const detector = new CTFDetector({
|
|
21
|
+
* privateKey: '0x...',
|
|
22
|
+
* market: { conditionId, primaryTokenId, secondaryTokenId },
|
|
23
|
+
* mode: 'hybrid',
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* detector.on('split', (operation) => console.log('Split detected:', operation));
|
|
27
|
+
* detector.on('merge', (operation) => console.log('Merge detected:', operation));
|
|
28
|
+
* detector.on('redeem', (operation) => console.log('Redeem detected:', operation));
|
|
29
|
+
*
|
|
30
|
+
* await detector.start();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { EventEmitter } from 'events';
|
|
34
|
+
import { TradingService } from './trading-service.js';
|
|
35
|
+
import { RateLimiter } from '../core/rate-limiter.js';
|
|
36
|
+
import { createUnifiedCache } from '../core/unified-cache.js';
|
|
37
|
+
import { RealtimeServiceV2 } from './realtime-service-v2.js';
|
|
38
|
+
import { CTFClient } from '../clients/ctf-client.js';
|
|
39
|
+
/**
|
|
40
|
+
* CTF Detector
|
|
41
|
+
*
|
|
42
|
+
* Features:
|
|
43
|
+
* - WebSocket for low-latency detection (ERC1155 Transfer events)
|
|
44
|
+
* - Polling for reliability (balance changes)
|
|
45
|
+
* - Deduplication to prevent duplicate events
|
|
46
|
+
* - Hybrid mode for best reliability
|
|
47
|
+
*/
|
|
48
|
+
export class CTFDetector extends EventEmitter {
|
|
49
|
+
config;
|
|
50
|
+
tradingService;
|
|
51
|
+
ctfClient;
|
|
52
|
+
realtimeService;
|
|
53
|
+
rateLimiter;
|
|
54
|
+
subscription = null;
|
|
55
|
+
pollTimer = null;
|
|
56
|
+
fallbackTimer = null;
|
|
57
|
+
running = false;
|
|
58
|
+
// Track last balance snapshot for change detection
|
|
59
|
+
lastBalanceSnapshot = null;
|
|
60
|
+
// Track processed operations to avoid duplicates
|
|
61
|
+
processedOperations = new Set();
|
|
62
|
+
// Track last successful WebSocket update
|
|
63
|
+
lastWebSocketUpdate = Date.now();
|
|
64
|
+
// Track if WebSocket is connected
|
|
65
|
+
websocketConnected = false;
|
|
66
|
+
constructor(config) {
|
|
67
|
+
super();
|
|
68
|
+
this.config = {
|
|
69
|
+
mode: config.mode ?? 'hybrid',
|
|
70
|
+
pollInterval: config.pollInterval ?? 10000,
|
|
71
|
+
pollFallbackDelay: config.pollFallbackDelay ?? 60000,
|
|
72
|
+
chainId: config.chainId ?? 137,
|
|
73
|
+
debug: config.debug ?? false,
|
|
74
|
+
rpcUrl: config.rpcUrl ?? 'https://polygon-rpc.com',
|
|
75
|
+
...config,
|
|
76
|
+
};
|
|
77
|
+
this.rateLimiter = new RateLimiter();
|
|
78
|
+
const cache = createUnifiedCache();
|
|
79
|
+
this.tradingService = new TradingService(this.rateLimiter, cache, {
|
|
80
|
+
privateKey: config.privateKey,
|
|
81
|
+
chainId: this.config.chainId,
|
|
82
|
+
});
|
|
83
|
+
// Initialize CTFClient for balance queries
|
|
84
|
+
this.ctfClient = new CTFClient({
|
|
85
|
+
privateKey: config.privateKey,
|
|
86
|
+
chainId: this.config.chainId,
|
|
87
|
+
rpcUrl: config.rpcUrl,
|
|
88
|
+
});
|
|
89
|
+
this.realtimeService = new RealtimeServiceV2({
|
|
90
|
+
autoReconnect: true,
|
|
91
|
+
pingInterval: 5000,
|
|
92
|
+
debug: this.config.debug,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// ============= Lifecycle =============
|
|
96
|
+
/**
|
|
97
|
+
* Start CTF operation detection
|
|
98
|
+
*/
|
|
99
|
+
async start() {
|
|
100
|
+
if (this.running)
|
|
101
|
+
return;
|
|
102
|
+
try {
|
|
103
|
+
// Initialize trading client
|
|
104
|
+
await this.tradingService.initialize();
|
|
105
|
+
// Get initial balance snapshot
|
|
106
|
+
await this.updateBalanceSnapshot();
|
|
107
|
+
const mode = this.config.mode;
|
|
108
|
+
// Start WebSocket if enabled
|
|
109
|
+
if (mode === 'websocket' || mode === 'hybrid') {
|
|
110
|
+
await this.startWebSocket();
|
|
111
|
+
}
|
|
112
|
+
// Start polling if enabled or as fallback
|
|
113
|
+
if (mode === 'polling') {
|
|
114
|
+
this.startPolling();
|
|
115
|
+
}
|
|
116
|
+
else if (mode === 'hybrid') {
|
|
117
|
+
// In hybrid mode, start polling as backup after fallback delay
|
|
118
|
+
this.scheduleFallbackPolling();
|
|
119
|
+
}
|
|
120
|
+
this.running = true;
|
|
121
|
+
this.log(`Started in ${mode} mode`);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('[CTFDetector] Failed to start:', error);
|
|
125
|
+
this.emit('error', error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Stop CTF operation detection
|
|
131
|
+
*/
|
|
132
|
+
stop() {
|
|
133
|
+
// Stop WebSocket
|
|
134
|
+
if (this.subscription) {
|
|
135
|
+
this.subscription.unsubscribe();
|
|
136
|
+
this.subscription = null;
|
|
137
|
+
}
|
|
138
|
+
this.realtimeService.disconnect();
|
|
139
|
+
this.websocketConnected = false;
|
|
140
|
+
// Stop polling
|
|
141
|
+
if (this.pollTimer) {
|
|
142
|
+
clearInterval(this.pollTimer);
|
|
143
|
+
this.pollTimer = null;
|
|
144
|
+
}
|
|
145
|
+
// Stop fallback timer
|
|
146
|
+
if (this.fallbackTimer) {
|
|
147
|
+
clearTimeout(this.fallbackTimer);
|
|
148
|
+
this.fallbackTimer = null;
|
|
149
|
+
}
|
|
150
|
+
this.running = false;
|
|
151
|
+
this.log('Stopped');
|
|
152
|
+
}
|
|
153
|
+
// ============= WebSocket Detection =============
|
|
154
|
+
/**
|
|
155
|
+
* Start WebSocket subscription
|
|
156
|
+
*
|
|
157
|
+
* Note: Currently poly-sdk RealtimeServiceV2 supports user_order and user_trade events.
|
|
158
|
+
* ERC1155 Transfer events would require additional WebSocket channel support.
|
|
159
|
+
* For now, this is a placeholder for future implementation.
|
|
160
|
+
*/
|
|
161
|
+
async startWebSocket() {
|
|
162
|
+
try {
|
|
163
|
+
const credentials = this.tradingService.getCredentials();
|
|
164
|
+
if (!credentials) {
|
|
165
|
+
throw new Error('Failed to get API credentials from TradingService');
|
|
166
|
+
}
|
|
167
|
+
// Connect to WebSocket
|
|
168
|
+
this.realtimeService.connect();
|
|
169
|
+
// Wait for connection
|
|
170
|
+
await this.waitForConnection(10000);
|
|
171
|
+
// TODO: Subscribe to ERC1155 Transfer events
|
|
172
|
+
// Currently RealtimeServiceV2 doesn't have a channel for ERC1155 events
|
|
173
|
+
// This would need to be added to poly-sdk or use alternative WebSocket provider
|
|
174
|
+
this.websocketConnected = true;
|
|
175
|
+
this.lastWebSocketUpdate = Date.now();
|
|
176
|
+
this.log('WebSocket connected (note: ERC1155 events not yet supported)');
|
|
177
|
+
this.emit('connected');
|
|
178
|
+
// If WebSocket doesn't support ERC1155 events, fall back to polling
|
|
179
|
+
if (this.config.mode === 'hybrid' && !this.pollTimer) {
|
|
180
|
+
this.log('Falling back to polling (ERC1155 WebSocket not available)');
|
|
181
|
+
this.startPolling();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error('[CTFDetector] WebSocket connection failed:', error);
|
|
186
|
+
this.websocketConnected = false;
|
|
187
|
+
// If hybrid mode, fall back to polling immediately
|
|
188
|
+
if (this.config.mode === 'hybrid' && !this.pollTimer) {
|
|
189
|
+
this.log('Falling back to polling due to WebSocket failure');
|
|
190
|
+
this.startPolling();
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Wait for WebSocket connection
|
|
197
|
+
*/
|
|
198
|
+
async waitForConnection(timeout) {
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
const timer = setTimeout(() => reject(new Error('WebSocket connection timeout')), timeout);
|
|
201
|
+
const onConnected = () => {
|
|
202
|
+
clearTimeout(timer);
|
|
203
|
+
this.realtimeService.off('connected', onConnected);
|
|
204
|
+
this.realtimeService.off('error', onError);
|
|
205
|
+
resolve();
|
|
206
|
+
};
|
|
207
|
+
const onError = (err) => {
|
|
208
|
+
clearTimeout(timer);
|
|
209
|
+
this.realtimeService.off('connected', onConnected);
|
|
210
|
+
this.realtimeService.off('error', onError);
|
|
211
|
+
reject(err);
|
|
212
|
+
};
|
|
213
|
+
this.realtimeService.once('connected', onConnected);
|
|
214
|
+
this.realtimeService.once('error', onError);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// ============= Polling Detection =============
|
|
218
|
+
/**
|
|
219
|
+
* Start polling
|
|
220
|
+
*/
|
|
221
|
+
startPolling() {
|
|
222
|
+
if (this.pollTimer)
|
|
223
|
+
return; // Already polling
|
|
224
|
+
const interval = this.config.pollInterval;
|
|
225
|
+
this.pollTimer = setInterval(() => {
|
|
226
|
+
this.pollForCTFOperations();
|
|
227
|
+
}, interval);
|
|
228
|
+
this.log(`Polling started with ${interval}ms interval`);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Schedule fallback polling
|
|
232
|
+
*
|
|
233
|
+
* In hybrid mode, start polling after a delay if WebSocket hasn't received updates
|
|
234
|
+
*/
|
|
235
|
+
scheduleFallbackPolling() {
|
|
236
|
+
if (this.fallbackTimer)
|
|
237
|
+
return;
|
|
238
|
+
this.fallbackTimer = setTimeout(() => {
|
|
239
|
+
const timeSinceLastUpdate = Date.now() - this.lastWebSocketUpdate;
|
|
240
|
+
const delay = this.config.pollFallbackDelay;
|
|
241
|
+
if (timeSinceLastUpdate > delay && !this.pollTimer) {
|
|
242
|
+
this.log(`No WebSocket updates for ${timeSinceLastUpdate}ms, starting fallback polling`);
|
|
243
|
+
this.startPolling();
|
|
244
|
+
}
|
|
245
|
+
// Reschedule check
|
|
246
|
+
this.fallbackTimer = null;
|
|
247
|
+
this.scheduleFallbackPolling();
|
|
248
|
+
}, this.config.pollFallbackDelay);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Poll for CTF operations by checking balance changes
|
|
252
|
+
*/
|
|
253
|
+
async pollForCTFOperations() {
|
|
254
|
+
if (!this.running) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
const previousSnapshot = this.lastBalanceSnapshot;
|
|
259
|
+
await this.updateBalanceSnapshot();
|
|
260
|
+
const currentSnapshot = this.lastBalanceSnapshot;
|
|
261
|
+
if (!previousSnapshot) {
|
|
262
|
+
// First snapshot, no comparison
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
// Detect balance changes
|
|
266
|
+
const primaryChange = BigInt(currentSnapshot.primary) - BigInt(previousSnapshot.primary);
|
|
267
|
+
const secondaryChange = BigInt(currentSnapshot.secondary) - BigInt(previousSnapshot.secondary);
|
|
268
|
+
// Split: both balances increase
|
|
269
|
+
if (primaryChange > 0 && secondaryChange > 0) {
|
|
270
|
+
await this.detectSplit(primaryChange, currentSnapshot.timestamp);
|
|
271
|
+
}
|
|
272
|
+
// Merge: both balances decrease
|
|
273
|
+
if (primaryChange < 0 && secondaryChange < 0) {
|
|
274
|
+
await this.detectMerge(-primaryChange, currentSnapshot.timestamp);
|
|
275
|
+
}
|
|
276
|
+
// Redeem: one balance decreases, other stays same
|
|
277
|
+
if (primaryChange < 0 && secondaryChange === BigInt(0)) {
|
|
278
|
+
await this.detectRedeem(this.config.market.primaryTokenId, -primaryChange, currentSnapshot.timestamp);
|
|
279
|
+
}
|
|
280
|
+
if (secondaryChange < 0 && primaryChange === BigInt(0)) {
|
|
281
|
+
await this.detectRedeem(this.config.market.secondaryTokenId, -secondaryChange, currentSnapshot.timestamp);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
console.error('[CTFDetector] Polling error:', error);
|
|
286
|
+
this.emit('error', error);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Update balance snapshot
|
|
291
|
+
*/
|
|
292
|
+
async updateBalanceSnapshot() {
|
|
293
|
+
try {
|
|
294
|
+
// Use CTFClient to query ERC-1155 token balances
|
|
295
|
+
const tokenIds = {
|
|
296
|
+
yesTokenId: this.config.market.primaryTokenId,
|
|
297
|
+
noTokenId: this.config.market.secondaryTokenId,
|
|
298
|
+
};
|
|
299
|
+
const balance = await this.ctfClient.getPositionBalanceByTokenIds(this.config.market.conditionId, tokenIds);
|
|
300
|
+
this.lastBalanceSnapshot = {
|
|
301
|
+
primary: balance.yesBalance,
|
|
302
|
+
secondary: balance.noBalance,
|
|
303
|
+
timestamp: Date.now(),
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
console.error('[CTFDetector] Failed to update balance snapshot:', error);
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// ============= Operation Detection =============
|
|
312
|
+
/**
|
|
313
|
+
* Detect split operation
|
|
314
|
+
*/
|
|
315
|
+
async detectSplit(amount, timestamp) {
|
|
316
|
+
const operationKey = `split-${amount.toString()}-${timestamp}`;
|
|
317
|
+
if (this.processedOperations.has(operationKey)) {
|
|
318
|
+
return; // Already processed
|
|
319
|
+
}
|
|
320
|
+
this.processedOperations.add(operationKey);
|
|
321
|
+
// Cleanup old processed operations (keep last 500)
|
|
322
|
+
if (this.processedOperations.size > 1000) {
|
|
323
|
+
const toKeep = Array.from(this.processedOperations).slice(-500);
|
|
324
|
+
this.processedOperations = new Set(toKeep);
|
|
325
|
+
}
|
|
326
|
+
const address = this.tradingService.getAddress();
|
|
327
|
+
if (!address)
|
|
328
|
+
return;
|
|
329
|
+
const operation = {
|
|
330
|
+
type: 'split',
|
|
331
|
+
userAddress: address,
|
|
332
|
+
conditionId: this.config.market.conditionId,
|
|
333
|
+
primaryTokenId: this.config.market.primaryTokenId,
|
|
334
|
+
secondaryTokenId: this.config.market.secondaryTokenId,
|
|
335
|
+
amount: amount.toString(),
|
|
336
|
+
timestamp,
|
|
337
|
+
};
|
|
338
|
+
this.log(`Split detected: ${amount.toString()} tokens`);
|
|
339
|
+
this.emit('split', operation);
|
|
340
|
+
this.emit('operation', operation);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Detect merge operation
|
|
344
|
+
*/
|
|
345
|
+
async detectMerge(amount, timestamp) {
|
|
346
|
+
const operationKey = `merge-${amount.toString()}-${timestamp}`;
|
|
347
|
+
if (this.processedOperations.has(operationKey)) {
|
|
348
|
+
return; // Already processed
|
|
349
|
+
}
|
|
350
|
+
this.processedOperations.add(operationKey);
|
|
351
|
+
const address = this.tradingService.getAddress();
|
|
352
|
+
if (!address)
|
|
353
|
+
return;
|
|
354
|
+
const operation = {
|
|
355
|
+
type: 'merge',
|
|
356
|
+
userAddress: address,
|
|
357
|
+
conditionId: this.config.market.conditionId,
|
|
358
|
+
primaryTokenId: this.config.market.primaryTokenId,
|
|
359
|
+
secondaryTokenId: this.config.market.secondaryTokenId,
|
|
360
|
+
amount: amount.toString(),
|
|
361
|
+
timestamp,
|
|
362
|
+
};
|
|
363
|
+
this.log(`Merge detected: ${amount.toString()} tokens`);
|
|
364
|
+
this.emit('merge', operation);
|
|
365
|
+
this.emit('operation', operation);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Detect redeem operation
|
|
369
|
+
*/
|
|
370
|
+
async detectRedeem(winningTokenId, amount, timestamp) {
|
|
371
|
+
const operationKey = `redeem-${winningTokenId}-${amount.toString()}-${timestamp}`;
|
|
372
|
+
if (this.processedOperations.has(operationKey)) {
|
|
373
|
+
return; // Already processed
|
|
374
|
+
}
|
|
375
|
+
this.processedOperations.add(operationKey);
|
|
376
|
+
const address = this.tradingService.getAddress();
|
|
377
|
+
if (!address)
|
|
378
|
+
return;
|
|
379
|
+
const operation = {
|
|
380
|
+
type: 'redeem',
|
|
381
|
+
userAddress: address,
|
|
382
|
+
conditionId: this.config.market.conditionId,
|
|
383
|
+
winningTokenId,
|
|
384
|
+
amount: amount.toString(),
|
|
385
|
+
timestamp,
|
|
386
|
+
};
|
|
387
|
+
this.log(`Redeem detected: ${amount.toString()} tokens (${winningTokenId})`);
|
|
388
|
+
this.emit('redeem', operation);
|
|
389
|
+
this.emit('operation', operation);
|
|
390
|
+
}
|
|
391
|
+
// ============= Statistics =============
|
|
392
|
+
/**
|
|
393
|
+
* Get statistics
|
|
394
|
+
*/
|
|
395
|
+
getStats() {
|
|
396
|
+
return {
|
|
397
|
+
websocketConnected: this.websocketConnected,
|
|
398
|
+
lastWebSocketUpdate: this.lastWebSocketUpdate,
|
|
399
|
+
lastBalanceCheck: this.lastBalanceSnapshot?.timestamp ?? null,
|
|
400
|
+
mode: this.config.mode,
|
|
401
|
+
processedOperations: this.processedOperations.size,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
// ============= Helpers =============
|
|
405
|
+
/**
|
|
406
|
+
* Log message (if debug enabled)
|
|
407
|
+
*/
|
|
408
|
+
log(message) {
|
|
409
|
+
if (this.config.debug) {
|
|
410
|
+
console.log(`[CTFDetector] ${message}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Factory function to create CTFDetector
|
|
416
|
+
*/
|
|
417
|
+
export function createCTFDetector(config) {
|
|
418
|
+
return new CTFDetector(config);
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=ctf-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctf-detector.js","sourceRoot":"","sources":["../../../src/services/ctf-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CTFManager - Unified CTF Operations and Event Monitoring
|
|
3
|
+
*
|
|
4
|
+
* Core Design Philosophy:
|
|
5
|
+
* - Unifies CTF operations (split/merge/redeem) + real-time event monitoring
|
|
6
|
+
* - Monitors on-chain ERC1155 Transfer events (not polling!)
|
|
7
|
+
* - Provides complete operation lifecycle tracking
|
|
8
|
+
* - Auto-validates operations before submission
|
|
9
|
+
*
|
|
10
|
+
* Architecture (similar to OrderManager):
|
|
11
|
+
* ```
|
|
12
|
+
* CTFManager
|
|
13
|
+
* ├── CTFClient (execute operations)
|
|
14
|
+
* ├── ethers.Contract (listen to ERC1155 events)
|
|
15
|
+
* └── Event Emitter (operation_detected, transaction_confirmed)
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const ctfMgr = new CTFManager({
|
|
21
|
+
* privateKey: '0x...',
|
|
22
|
+
* conditionId: '0x...',
|
|
23
|
+
* primaryTokenId: '123...',
|
|
24
|
+
* secondaryTokenId: '456...',
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* await ctfMgr.start();
|
|
28
|
+
*
|
|
29
|
+
* // Listen to real-time CTF events
|
|
30
|
+
* ctfMgr.on('split_detected', (event) => {
|
|
31
|
+
* console.log(`Split: ${event.amount} USDC → tokens`);
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* ctfMgr.on('merge_detected', (event) => {
|
|
35
|
+
* console.log(`Merge: ${event.amount} tokens → USDC`);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* ctfMgr.on('redeem_detected', (event) => {
|
|
39
|
+
* console.log(`Redeem: ${event.amount} winning tokens`);
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Execute operations (automatically tracked)
|
|
43
|
+
* await ctfMgr.split('100');
|
|
44
|
+
* await ctfMgr.merge('50');
|
|
45
|
+
* await ctfMgr.redeem();
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
import { EventEmitter } from 'events';
|
|
49
|
+
import { type SplitResult, type MergeResult, type RedeemResult } from '../clients/ctf-client.js';
|
|
50
|
+
export interface CTFManagerConfig {
|
|
51
|
+
/** Private key for signing transactions */
|
|
52
|
+
privateKey: string;
|
|
53
|
+
/** Market condition ID */
|
|
54
|
+
conditionId: string;
|
|
55
|
+
/** Primary token ID (YES/primary outcome) */
|
|
56
|
+
primaryTokenId: string;
|
|
57
|
+
/** Secondary token ID (NO/secondary outcome) */
|
|
58
|
+
secondaryTokenId: string;
|
|
59
|
+
/** RPC URL for Polygon (default: public RPC) */
|
|
60
|
+
rpcUrl?: string;
|
|
61
|
+
/** Chain ID (default: 137 Polygon mainnet) */
|
|
62
|
+
chainId?: number;
|
|
63
|
+
/** Enable debug logging */
|
|
64
|
+
debug?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* CTF operation types
|
|
68
|
+
*/
|
|
69
|
+
export type CTFOperationType = 'split' | 'merge' | 'redeem';
|
|
70
|
+
/**
|
|
71
|
+
* Split event (USDC → YES + NO tokens)
|
|
72
|
+
*/
|
|
73
|
+
export interface SplitEvent {
|
|
74
|
+
type: 'split';
|
|
75
|
+
userAddress: string;
|
|
76
|
+
conditionId: string;
|
|
77
|
+
primaryTokenId: string;
|
|
78
|
+
secondaryTokenId: string;
|
|
79
|
+
amount: string;
|
|
80
|
+
txHash: string;
|
|
81
|
+
blockNumber: number;
|
|
82
|
+
timestamp: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Merge event (YES + NO tokens → USDC)
|
|
86
|
+
*/
|
|
87
|
+
export interface MergeEvent {
|
|
88
|
+
type: 'merge';
|
|
89
|
+
userAddress: string;
|
|
90
|
+
conditionId: string;
|
|
91
|
+
primaryTokenId: string;
|
|
92
|
+
secondaryTokenId: string;
|
|
93
|
+
amount: string;
|
|
94
|
+
txHash: string;
|
|
95
|
+
blockNumber: number;
|
|
96
|
+
timestamp: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Redeem event (Winning tokens → USDC)
|
|
100
|
+
*/
|
|
101
|
+
export interface RedeemEvent {
|
|
102
|
+
type: 'redeem';
|
|
103
|
+
userAddress: string;
|
|
104
|
+
conditionId: string;
|
|
105
|
+
winningTokenId: string;
|
|
106
|
+
amount: string;
|
|
107
|
+
txHash: string;
|
|
108
|
+
blockNumber: number;
|
|
109
|
+
timestamp: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Union type for all CTF events
|
|
113
|
+
*/
|
|
114
|
+
export type CTFEvent = SplitEvent | MergeEvent | RedeemEvent;
|
|
115
|
+
export declare class CTFManager extends EventEmitter {
|
|
116
|
+
private ctfClient;
|
|
117
|
+
private provider;
|
|
118
|
+
private ctfContract;
|
|
119
|
+
private config;
|
|
120
|
+
private initialized;
|
|
121
|
+
private userAddress;
|
|
122
|
+
private processedEvents;
|
|
123
|
+
constructor(config: CTFManagerConfig);
|
|
124
|
+
/**
|
|
125
|
+
* Start CTFManager
|
|
126
|
+
* - Starts listening to CTF-specific events (primary detection)
|
|
127
|
+
* - Also listens to ERC1155 Transfer events (fallback)
|
|
128
|
+
*/
|
|
129
|
+
start(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Stop CTFManager
|
|
132
|
+
* - Removes all event listeners
|
|
133
|
+
*/
|
|
134
|
+
stop(): void;
|
|
135
|
+
/**
|
|
136
|
+
* Split USDC into YES + NO tokens
|
|
137
|
+
* Transaction is automatically tracked via on-chain events
|
|
138
|
+
*/
|
|
139
|
+
split(amount: string): Promise<SplitResult>;
|
|
140
|
+
/**
|
|
141
|
+
* Merge YES + NO tokens into USDC
|
|
142
|
+
* Transaction is automatically tracked via on-chain events
|
|
143
|
+
*/
|
|
144
|
+
merge(amount: string): Promise<MergeResult>;
|
|
145
|
+
/**
|
|
146
|
+
* Redeem winning tokens for USDC (after market resolution)
|
|
147
|
+
* Transaction is automatically tracked via on-chain events
|
|
148
|
+
*/
|
|
149
|
+
redeem(outcome?: string): Promise<RedeemResult>;
|
|
150
|
+
/**
|
|
151
|
+
* Handle TransferSingle event
|
|
152
|
+
*
|
|
153
|
+
* ERC1155 TransferSingle patterns:
|
|
154
|
+
* - Split: from=0x0, to=user, id=YES/NO (two events)
|
|
155
|
+
* - Merge: from=user, to=0x0, id=YES/NO (two events)
|
|
156
|
+
* - Redeem: from=user, to=0x0, id=winningToken (one event)
|
|
157
|
+
*/
|
|
158
|
+
private handleTransferSingle;
|
|
159
|
+
/**
|
|
160
|
+
* Handle TransferBatch event (less common)
|
|
161
|
+
*/
|
|
162
|
+
private handleTransferBatch;
|
|
163
|
+
/**
|
|
164
|
+
* Handle PositionSplit event
|
|
165
|
+
* Direct detection of Split operation - faster than parsing Transfer events
|
|
166
|
+
*/
|
|
167
|
+
private handlePositionSplit;
|
|
168
|
+
/**
|
|
169
|
+
* Handle PositionsMerge event
|
|
170
|
+
* Direct detection of Merge operation - faster than parsing Transfer events
|
|
171
|
+
*/
|
|
172
|
+
private handlePositionsMerge;
|
|
173
|
+
/**
|
|
174
|
+
* Handle PayoutRedemption event
|
|
175
|
+
* Direct detection of Redeem operation - faster than parsing Transfer events
|
|
176
|
+
*/
|
|
177
|
+
private handlePayoutRedemption;
|
|
178
|
+
/**
|
|
179
|
+
* Detect split operation
|
|
180
|
+
* Split creates TWO Transfer events (0x0 → user) for both tokens
|
|
181
|
+
* We need to wait for the second event to confirm it's a split
|
|
182
|
+
*/
|
|
183
|
+
private detectSplit;
|
|
184
|
+
/**
|
|
185
|
+
* Detect merge or redeem operation
|
|
186
|
+
* - Merge: TWO Transfer events (user → 0x0) for both tokens
|
|
187
|
+
* - Redeem: ONE Transfer event (user → 0x0) for winning token
|
|
188
|
+
*/
|
|
189
|
+
private detectMergeOrRedeem;
|
|
190
|
+
/**
|
|
191
|
+
* Log message (if debug enabled)
|
|
192
|
+
*/
|
|
193
|
+
private log;
|
|
194
|
+
/**
|
|
195
|
+
* Get current balances
|
|
196
|
+
*/
|
|
197
|
+
getBalances(): Promise<{
|
|
198
|
+
primary: string;
|
|
199
|
+
secondary: string;
|
|
200
|
+
}>;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=ctf-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctf-manager.d.ts","sourceRoot":"","sources":["../../../src/services/ctf-manager.ts"],"names":[],"mappings":"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"}
|