@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,477 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrderManager Unit Tests
|
|
3
|
+
*
|
|
4
|
+
* Focus: Fill event generation in polling mode
|
|
5
|
+
* Issue #7: Polling mode doesn't emit fill events, only status changes
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
import { OrderManager } from './order-manager.js';
|
|
9
|
+
import { OrderStatus } from '../core/types.js';
|
|
10
|
+
import { MockRateLimiter, MockCache, waitFor } from '../__tests__/test-utils.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Mock Dependencies
|
|
13
|
+
// ============================================================================
|
|
14
|
+
class MockTradingService {
|
|
15
|
+
orders = new Map();
|
|
16
|
+
async initialize() { }
|
|
17
|
+
async getOrder(orderId) {
|
|
18
|
+
return this.orders.get(orderId) || null;
|
|
19
|
+
}
|
|
20
|
+
// Test helper: update order state
|
|
21
|
+
updateOrder(orderId, updates) {
|
|
22
|
+
const existing = this.orders.get(orderId);
|
|
23
|
+
if (existing) {
|
|
24
|
+
this.orders.set(orderId, { ...existing, ...updates });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.orders.set(orderId, {
|
|
28
|
+
id: orderId,
|
|
29
|
+
status: OrderStatus.OPEN,
|
|
30
|
+
tokenId: 'token123',
|
|
31
|
+
side: 'BUY',
|
|
32
|
+
price: 0.52,
|
|
33
|
+
originalSize: 100,
|
|
34
|
+
filledSize: 0,
|
|
35
|
+
remainingSize: 100,
|
|
36
|
+
associateTrades: [],
|
|
37
|
+
createdAt: Date.now(),
|
|
38
|
+
...updates,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
getCredentials() {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Test Fixtures
|
|
48
|
+
// ============================================================================
|
|
49
|
+
const createTestOrder = (overrides) => ({
|
|
50
|
+
id: 'test-order-1',
|
|
51
|
+
status: OrderStatus.OPEN,
|
|
52
|
+
tokenId: 'token123',
|
|
53
|
+
side: 'BUY',
|
|
54
|
+
price: 0.52,
|
|
55
|
+
originalSize: 100,
|
|
56
|
+
filledSize: 0,
|
|
57
|
+
remainingSize: 100,
|
|
58
|
+
associateTrades: [],
|
|
59
|
+
createdAt: Date.now(),
|
|
60
|
+
...overrides,
|
|
61
|
+
});
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Tests
|
|
64
|
+
// ============================================================================
|
|
65
|
+
describe('OrderManager - Polling Fill Detection', () => {
|
|
66
|
+
let orderManager;
|
|
67
|
+
let mockTradingService;
|
|
68
|
+
let rateLimiter;
|
|
69
|
+
let cache;
|
|
70
|
+
beforeEach(async () => {
|
|
71
|
+
rateLimiter = new MockRateLimiter();
|
|
72
|
+
cache = new MockCache();
|
|
73
|
+
mockTradingService = new MockTradingService();
|
|
74
|
+
orderManager = new OrderManager({
|
|
75
|
+
privateKey: '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
|
|
76
|
+
rateLimiter: rateLimiter,
|
|
77
|
+
cache: cache,
|
|
78
|
+
mode: 'polling',
|
|
79
|
+
pollingInterval: 100, // Fast polling for tests
|
|
80
|
+
});
|
|
81
|
+
// Inject mock trading service
|
|
82
|
+
orderManager.tradingService = mockTradingService;
|
|
83
|
+
await orderManager.start();
|
|
84
|
+
});
|
|
85
|
+
afterEach(() => {
|
|
86
|
+
orderManager.stop();
|
|
87
|
+
});
|
|
88
|
+
describe('Fill Detection', () => {
|
|
89
|
+
it('should emit order_partially_filled when filledSize increases', async () => {
|
|
90
|
+
const orderId = 'order-1';
|
|
91
|
+
const initialOrder = createTestOrder({
|
|
92
|
+
id: orderId,
|
|
93
|
+
filledSize: 0,
|
|
94
|
+
remainingSize: 100,
|
|
95
|
+
});
|
|
96
|
+
// Set initial state
|
|
97
|
+
mockTradingService.updateOrder(orderId, initialOrder);
|
|
98
|
+
// Start watching
|
|
99
|
+
orderManager.watchOrder(orderId);
|
|
100
|
+
// Setup event listener
|
|
101
|
+
const fillEvents = [];
|
|
102
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
103
|
+
fillEvents.push(event);
|
|
104
|
+
});
|
|
105
|
+
// Wait for initial poll
|
|
106
|
+
await waitFor(150);
|
|
107
|
+
// Simulate partial fill (50 shares filled)
|
|
108
|
+
mockTradingService.updateOrder(orderId, {
|
|
109
|
+
filledSize: 50,
|
|
110
|
+
remainingSize: 50,
|
|
111
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
112
|
+
associateTrades: ['trade-1'],
|
|
113
|
+
});
|
|
114
|
+
// Wait for next poll
|
|
115
|
+
await waitFor(150);
|
|
116
|
+
// Verify fill event emitted
|
|
117
|
+
expect(fillEvents).toHaveLength(1);
|
|
118
|
+
expect(fillEvents[0]).toMatchObject({
|
|
119
|
+
orderId,
|
|
120
|
+
fill: {
|
|
121
|
+
size: 50, // Delta from 0 to 50
|
|
122
|
+
price: 0.52, // Order price
|
|
123
|
+
},
|
|
124
|
+
cumulativeFilled: 50,
|
|
125
|
+
remainingSize: 50,
|
|
126
|
+
isCompleteFill: false,
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
it('should emit order_filled when order completely filled', async () => {
|
|
130
|
+
const orderId = 'order-2';
|
|
131
|
+
// Set initial state with partial fill
|
|
132
|
+
mockTradingService.updateOrder(orderId, {
|
|
133
|
+
id: orderId,
|
|
134
|
+
filledSize: 50,
|
|
135
|
+
remainingSize: 50,
|
|
136
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
137
|
+
associateTrades: ['trade-1'],
|
|
138
|
+
});
|
|
139
|
+
// Start watching (this will poll and set initial state)
|
|
140
|
+
orderManager.watchOrder(orderId);
|
|
141
|
+
// Setup event listener AFTER first poll
|
|
142
|
+
await waitFor(150);
|
|
143
|
+
const fillEvents = [];
|
|
144
|
+
orderManager.on('order_filled', (event) => {
|
|
145
|
+
fillEvents.push(event);
|
|
146
|
+
});
|
|
147
|
+
// Simulate complete fill
|
|
148
|
+
mockTradingService.updateOrder(orderId, {
|
|
149
|
+
filledSize: 100,
|
|
150
|
+
remainingSize: 0,
|
|
151
|
+
status: OrderStatus.FILLED,
|
|
152
|
+
associateTrades: ['trade-1', 'trade-2'],
|
|
153
|
+
});
|
|
154
|
+
// Wait for next poll
|
|
155
|
+
await waitFor(150);
|
|
156
|
+
// Verify fill event emitted
|
|
157
|
+
expect(fillEvents).toHaveLength(1);
|
|
158
|
+
expect(fillEvents[0]).toMatchObject({
|
|
159
|
+
orderId,
|
|
160
|
+
fill: {
|
|
161
|
+
size: 50, // Delta from 50 to 100
|
|
162
|
+
price: 0.52,
|
|
163
|
+
},
|
|
164
|
+
cumulativeFilled: 100,
|
|
165
|
+
remainingSize: 0,
|
|
166
|
+
isCompleteFill: true,
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
it('should emit multiple partial fill events correctly', async () => {
|
|
170
|
+
const orderId = 'order-3';
|
|
171
|
+
// Set initial state
|
|
172
|
+
mockTradingService.updateOrder(orderId, {
|
|
173
|
+
id: orderId,
|
|
174
|
+
filledSize: 0,
|
|
175
|
+
remainingSize: 100,
|
|
176
|
+
});
|
|
177
|
+
// Start watching and wait for initial state
|
|
178
|
+
orderManager.watchOrder(orderId);
|
|
179
|
+
await waitFor(150);
|
|
180
|
+
// Setup event listener AFTER initial poll
|
|
181
|
+
const partialFillEvents = [];
|
|
182
|
+
const completeFillEvents = [];
|
|
183
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
184
|
+
partialFillEvents.push(event);
|
|
185
|
+
});
|
|
186
|
+
orderManager.on('order_filled', (event) => {
|
|
187
|
+
completeFillEvents.push(event);
|
|
188
|
+
});
|
|
189
|
+
// First fill: 30 shares
|
|
190
|
+
mockTradingService.updateOrder(orderId, {
|
|
191
|
+
filledSize: 30,
|
|
192
|
+
remainingSize: 70,
|
|
193
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
194
|
+
associateTrades: ['trade-1'],
|
|
195
|
+
});
|
|
196
|
+
await waitFor(150);
|
|
197
|
+
// Second fill: 40 more shares (total 70)
|
|
198
|
+
mockTradingService.updateOrder(orderId, {
|
|
199
|
+
filledSize: 70,
|
|
200
|
+
remainingSize: 30,
|
|
201
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
202
|
+
associateTrades: ['trade-1', 'trade-2'],
|
|
203
|
+
});
|
|
204
|
+
await waitFor(150);
|
|
205
|
+
// Final fill: 30 more shares (total 100, complete)
|
|
206
|
+
mockTradingService.updateOrder(orderId, {
|
|
207
|
+
filledSize: 100,
|
|
208
|
+
remainingSize: 0,
|
|
209
|
+
status: OrderStatus.FILLED,
|
|
210
|
+
associateTrades: ['trade-1', 'trade-2', 'trade-3'],
|
|
211
|
+
});
|
|
212
|
+
await waitFor(150);
|
|
213
|
+
// Verify partial fills
|
|
214
|
+
expect(partialFillEvents).toHaveLength(2);
|
|
215
|
+
expect(partialFillEvents[0].fill.size).toBe(30);
|
|
216
|
+
expect(partialFillEvents[1].fill.size).toBe(40);
|
|
217
|
+
// Verify complete fill
|
|
218
|
+
expect(completeFillEvents).toHaveLength(1);
|
|
219
|
+
expect(completeFillEvents[0].fill.size).toBe(30);
|
|
220
|
+
expect(completeFillEvents[0].isCompleteFill).toBe(true);
|
|
221
|
+
});
|
|
222
|
+
it('should not emit duplicate fill events', async () => {
|
|
223
|
+
const orderId = 'order-4';
|
|
224
|
+
// Set initial state
|
|
225
|
+
mockTradingService.updateOrder(orderId, {
|
|
226
|
+
id: orderId,
|
|
227
|
+
filledSize: 0,
|
|
228
|
+
remainingSize: 100,
|
|
229
|
+
});
|
|
230
|
+
// Start watching
|
|
231
|
+
orderManager.watchOrder(orderId);
|
|
232
|
+
// Setup event listener
|
|
233
|
+
const fillEvents = [];
|
|
234
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
235
|
+
fillEvents.push(event);
|
|
236
|
+
});
|
|
237
|
+
// Wait for initial poll
|
|
238
|
+
await waitFor(150);
|
|
239
|
+
// Simulate fill
|
|
240
|
+
mockTradingService.updateOrder(orderId, {
|
|
241
|
+
filledSize: 50,
|
|
242
|
+
remainingSize: 50,
|
|
243
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
244
|
+
});
|
|
245
|
+
// Wait for multiple polls
|
|
246
|
+
await waitFor(150);
|
|
247
|
+
await waitFor(150);
|
|
248
|
+
await waitFor(150);
|
|
249
|
+
// Should only emit once (deduplication works)
|
|
250
|
+
expect(fillEvents).toHaveLength(1);
|
|
251
|
+
});
|
|
252
|
+
it('should include correct fill details', async () => {
|
|
253
|
+
const orderId = 'order-5';
|
|
254
|
+
// Set initial state
|
|
255
|
+
mockTradingService.updateOrder(orderId, {
|
|
256
|
+
id: orderId,
|
|
257
|
+
price: 0.65,
|
|
258
|
+
originalSize: 200,
|
|
259
|
+
filledSize: 0,
|
|
260
|
+
remainingSize: 200,
|
|
261
|
+
associateTrades: [],
|
|
262
|
+
});
|
|
263
|
+
// Start watching
|
|
264
|
+
orderManager.watchOrder(orderId);
|
|
265
|
+
// Setup event listener
|
|
266
|
+
let capturedEvent = null;
|
|
267
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
268
|
+
capturedEvent = event;
|
|
269
|
+
});
|
|
270
|
+
// Wait for initial poll
|
|
271
|
+
await waitFor(150);
|
|
272
|
+
// Simulate fill
|
|
273
|
+
mockTradingService.updateOrder(orderId, {
|
|
274
|
+
filledSize: 100,
|
|
275
|
+
remainingSize: 100,
|
|
276
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
277
|
+
associateTrades: ['trade-abc'],
|
|
278
|
+
});
|
|
279
|
+
// Wait for poll
|
|
280
|
+
await waitFor(150);
|
|
281
|
+
// Verify fill details
|
|
282
|
+
expect(capturedEvent).not.toBeNull();
|
|
283
|
+
expect(capturedEvent).toMatchObject({
|
|
284
|
+
orderId,
|
|
285
|
+
fill: {
|
|
286
|
+
tradeId: 'trade-abc',
|
|
287
|
+
size: 100,
|
|
288
|
+
price: 0.65,
|
|
289
|
+
fee: 0, // Polling doesn't have fee info
|
|
290
|
+
},
|
|
291
|
+
cumulativeFilled: 100,
|
|
292
|
+
remainingSize: 100,
|
|
293
|
+
isCompleteFill: false,
|
|
294
|
+
});
|
|
295
|
+
// Verify order reference
|
|
296
|
+
expect(capturedEvent.order.id).toBe(orderId);
|
|
297
|
+
expect(capturedEvent.order.filledSize).toBe(100);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
describe('Status Change Events', () => {
|
|
301
|
+
it('should emit both fill event and status change event', async () => {
|
|
302
|
+
const orderId = 'order-6';
|
|
303
|
+
// Set initial state
|
|
304
|
+
mockTradingService.updateOrder(orderId, {
|
|
305
|
+
id: orderId,
|
|
306
|
+
filledSize: 0,
|
|
307
|
+
remainingSize: 100,
|
|
308
|
+
status: OrderStatus.OPEN,
|
|
309
|
+
});
|
|
310
|
+
// Start watching and wait for initial state
|
|
311
|
+
orderManager.watchOrder(orderId);
|
|
312
|
+
await waitFor(150);
|
|
313
|
+
// Setup event listeners AFTER initial poll
|
|
314
|
+
const fillEvents = [];
|
|
315
|
+
const statusChanges = [];
|
|
316
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
317
|
+
fillEvents.push(event);
|
|
318
|
+
});
|
|
319
|
+
orderManager.on('status_change', (event) => {
|
|
320
|
+
statusChanges.push(event);
|
|
321
|
+
});
|
|
322
|
+
// Simulate fill with status change
|
|
323
|
+
mockTradingService.updateOrder(orderId, {
|
|
324
|
+
filledSize: 50,
|
|
325
|
+
remainingSize: 50,
|
|
326
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
327
|
+
});
|
|
328
|
+
// Wait for poll
|
|
329
|
+
await waitFor(150);
|
|
330
|
+
// Both events should be emitted
|
|
331
|
+
expect(fillEvents).toHaveLength(1);
|
|
332
|
+
expect(statusChanges).toHaveLength(1);
|
|
333
|
+
expect(statusChanges[0].to).toBe(OrderStatus.PARTIALLY_FILLED);
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
describe('Edge Cases', () => {
|
|
337
|
+
it('should handle filledSize staying the same (no fill)', async () => {
|
|
338
|
+
const orderId = 'order-7';
|
|
339
|
+
// Set initial state with existing fill
|
|
340
|
+
mockTradingService.updateOrder(orderId, {
|
|
341
|
+
id: orderId,
|
|
342
|
+
filledSize: 50,
|
|
343
|
+
remainingSize: 50,
|
|
344
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
345
|
+
});
|
|
346
|
+
// Start watching and wait for initial state
|
|
347
|
+
orderManager.watchOrder(orderId);
|
|
348
|
+
await waitFor(150);
|
|
349
|
+
// Setup event listener AFTER initial poll
|
|
350
|
+
const fillEvents = [];
|
|
351
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
352
|
+
fillEvents.push(event);
|
|
353
|
+
});
|
|
354
|
+
// Wait for multiple polls (no fill change)
|
|
355
|
+
await waitFor(150);
|
|
356
|
+
await waitFor(150);
|
|
357
|
+
// No fill events should be emitted
|
|
358
|
+
expect(fillEvents).toHaveLength(0);
|
|
359
|
+
});
|
|
360
|
+
it('should handle order with no associateTrades', async () => {
|
|
361
|
+
const orderId = 'order-8';
|
|
362
|
+
// Set initial state
|
|
363
|
+
mockTradingService.updateOrder(orderId, {
|
|
364
|
+
id: orderId,
|
|
365
|
+
filledSize: 0,
|
|
366
|
+
remainingSize: 100,
|
|
367
|
+
associateTrades: [],
|
|
368
|
+
});
|
|
369
|
+
// Start watching
|
|
370
|
+
orderManager.watchOrder(orderId);
|
|
371
|
+
// Setup event listener
|
|
372
|
+
let capturedEvent = null;
|
|
373
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
374
|
+
capturedEvent = event;
|
|
375
|
+
});
|
|
376
|
+
// Wait for initial poll
|
|
377
|
+
await waitFor(150);
|
|
378
|
+
// Simulate fill with no trade ID
|
|
379
|
+
mockTradingService.updateOrder(orderId, {
|
|
380
|
+
filledSize: 50,
|
|
381
|
+
remainingSize: 50,
|
|
382
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
383
|
+
associateTrades: [], // Empty array
|
|
384
|
+
});
|
|
385
|
+
// Wait for poll
|
|
386
|
+
await waitFor(150);
|
|
387
|
+
// Should generate synthetic tradeId
|
|
388
|
+
expect(capturedEvent).not.toBeNull();
|
|
389
|
+
expect(capturedEvent.fill.tradeId).toMatch(/^polling_\d+$/);
|
|
390
|
+
});
|
|
391
|
+
it('should handle order going directly from OPEN to FILLED', async () => {
|
|
392
|
+
const orderId = 'order-9';
|
|
393
|
+
// Set initial state
|
|
394
|
+
mockTradingService.updateOrder(orderId, {
|
|
395
|
+
id: orderId,
|
|
396
|
+
filledSize: 0,
|
|
397
|
+
remainingSize: 100,
|
|
398
|
+
status: OrderStatus.OPEN,
|
|
399
|
+
});
|
|
400
|
+
// Start watching and wait for initial state
|
|
401
|
+
orderManager.watchOrder(orderId);
|
|
402
|
+
await waitFor(150);
|
|
403
|
+
// Setup event listeners AFTER initial poll
|
|
404
|
+
const partialFillEvents = [];
|
|
405
|
+
const completeFillEvents = [];
|
|
406
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
407
|
+
partialFillEvents.push(event);
|
|
408
|
+
});
|
|
409
|
+
orderManager.on('order_filled', (event) => {
|
|
410
|
+
completeFillEvents.push(event);
|
|
411
|
+
});
|
|
412
|
+
// Simulate instant complete fill (market order scenario)
|
|
413
|
+
mockTradingService.updateOrder(orderId, {
|
|
414
|
+
filledSize: 100,
|
|
415
|
+
remainingSize: 0,
|
|
416
|
+
status: OrderStatus.FILLED,
|
|
417
|
+
associateTrades: ['trade-1'],
|
|
418
|
+
});
|
|
419
|
+
// Wait for poll
|
|
420
|
+
await waitFor(150);
|
|
421
|
+
// Should emit complete fill only
|
|
422
|
+
expect(partialFillEvents).toHaveLength(0);
|
|
423
|
+
expect(completeFillEvents).toHaveLength(1);
|
|
424
|
+
expect(completeFillEvents[0].fill.size).toBe(100);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
describe('OrderManager - WebSocket + Polling Deduplication', () => {
|
|
429
|
+
let orderManager;
|
|
430
|
+
let mockTradingService;
|
|
431
|
+
beforeEach(async () => {
|
|
432
|
+
mockTradingService = new MockTradingService();
|
|
433
|
+
orderManager = new OrderManager({
|
|
434
|
+
privateKey: '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
|
|
435
|
+
rateLimiter: new MockRateLimiter(),
|
|
436
|
+
cache: new MockCache(),
|
|
437
|
+
mode: 'hybrid', // Both WebSocket and Polling
|
|
438
|
+
pollingInterval: 100,
|
|
439
|
+
});
|
|
440
|
+
// Inject mock trading service
|
|
441
|
+
orderManager.tradingService = mockTradingService;
|
|
442
|
+
await orderManager.start();
|
|
443
|
+
});
|
|
444
|
+
afterEach(() => {
|
|
445
|
+
orderManager.stop();
|
|
446
|
+
});
|
|
447
|
+
it('should not emit duplicate fills when both WebSocket and Polling detect same fill', async () => {
|
|
448
|
+
const orderId = 'order-10';
|
|
449
|
+
// Set initial state
|
|
450
|
+
mockTradingService.updateOrder(orderId, {
|
|
451
|
+
id: orderId,
|
|
452
|
+
filledSize: 0,
|
|
453
|
+
remainingSize: 100,
|
|
454
|
+
});
|
|
455
|
+
// Start watching
|
|
456
|
+
orderManager.watchOrder(orderId);
|
|
457
|
+
// Setup event listener
|
|
458
|
+
const fillEvents = [];
|
|
459
|
+
orderManager.on('order_partially_filled', (event) => {
|
|
460
|
+
fillEvents.push(event);
|
|
461
|
+
});
|
|
462
|
+
// Wait for initial poll
|
|
463
|
+
await waitFor(150);
|
|
464
|
+
// Update order state
|
|
465
|
+
mockTradingService.updateOrder(orderId, {
|
|
466
|
+
filledSize: 50,
|
|
467
|
+
remainingSize: 50,
|
|
468
|
+
status: OrderStatus.PARTIALLY_FILLED,
|
|
469
|
+
});
|
|
470
|
+
// Wait for multiple polls
|
|
471
|
+
await waitFor(150);
|
|
472
|
+
await waitFor(150);
|
|
473
|
+
// Deduplication should prevent multiple emissions
|
|
474
|
+
expect(fillEvents).toHaveLength(1);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
//# sourceMappingURL=order-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order-manager.test.js","sourceRoot":"","sources":["../../../src/services/order-manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ import { Wallet } from 'ethers';
|
|
|
21
21
|
import { RateLimiter } from '../core/rate-limiter.js';
|
|
22
22
|
import type { UnifiedCache } from '../core/unified-cache.js';
|
|
23
23
|
import type { Side } from '../core/types.js';
|
|
24
|
+
import { OrderStatus } from '../core/types.js';
|
|
24
25
|
export declare const POLYGON_MAINNET = 137;
|
|
25
26
|
export declare const POLYGON_AMOY = 80002;
|
|
26
27
|
/** Minimum order value in USDC (price * size >= MIN_ORDER_VALUE) */
|
|
@@ -56,9 +57,20 @@ export interface MarketOrderParams {
|
|
|
56
57
|
price?: number;
|
|
57
58
|
orderType?: 'FOK' | 'FAK';
|
|
58
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Order representation with detailed status tracking
|
|
62
|
+
*
|
|
63
|
+
* Status Flow:
|
|
64
|
+
* pending → open → partially_filled → filled
|
|
65
|
+
* ↓ ↓ (or)
|
|
66
|
+
* cancelled cancelled expired
|
|
67
|
+
*
|
|
68
|
+
* @see OrderStatus enum for detailed state documentation
|
|
69
|
+
*/
|
|
59
70
|
export interface Order {
|
|
60
71
|
id: string;
|
|
61
|
-
status
|
|
72
|
+
/** Current order status - see OrderStatus enum for state machine */
|
|
73
|
+
status: OrderStatus;
|
|
62
74
|
tokenId: string;
|
|
63
75
|
side: Side;
|
|
64
76
|
price: number;
|
|
@@ -67,6 +79,16 @@ export interface Order {
|
|
|
67
79
|
remainingSize: number;
|
|
68
80
|
associateTrades: string[];
|
|
69
81
|
createdAt: number;
|
|
82
|
+
/**
|
|
83
|
+
* Last update timestamp
|
|
84
|
+
* Updated on: status change, new fill, cancellation
|
|
85
|
+
*/
|
|
86
|
+
updatedAt?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Expiration timestamp (for GTD orders)
|
|
89
|
+
* undefined for GTC orders
|
|
90
|
+
*/
|
|
91
|
+
expiration?: number;
|
|
70
92
|
}
|
|
71
93
|
export interface OrderResult {
|
|
72
94
|
success: boolean;
|
|
@@ -159,10 +181,76 @@ export declare class TradingService {
|
|
|
159
181
|
* Market orders below this limit will be rejected by the API.
|
|
160
182
|
*/
|
|
161
183
|
createMarketOrder(params: MarketOrderParams): Promise<OrderResult>;
|
|
184
|
+
/**
|
|
185
|
+
* Create and post multiple limit orders in a batch
|
|
186
|
+
*
|
|
187
|
+
* Note: Polymarket enforces:
|
|
188
|
+
* - Maximum 15 orders per batch
|
|
189
|
+
* - Same minimum requirements as single orders (5 shares, $1 value)
|
|
190
|
+
*
|
|
191
|
+
* This method uses Polymarket's batch API (POST /orders) which submits
|
|
192
|
+
* all orders in a single HTTP request, significantly faster than individual calls.
|
|
193
|
+
*
|
|
194
|
+
* @param orders - Array of limit order parameters (max 15)
|
|
195
|
+
* @returns Batch result with individual order IDs or errors
|
|
196
|
+
*/
|
|
197
|
+
createBatchOrders(orders: LimitOrderParams[]): Promise<OrderResult>;
|
|
198
|
+
/**
|
|
199
|
+
* Get a single order by ID
|
|
200
|
+
*
|
|
201
|
+
* @param orderId - Order ID (hash)
|
|
202
|
+
* @returns Order details or null if not found
|
|
203
|
+
*/
|
|
204
|
+
getOrder(orderId: string): Promise<Order | null>;
|
|
162
205
|
cancelOrder(orderId: string): Promise<OrderResult>;
|
|
163
206
|
cancelOrders(orderIds: string[]): Promise<OrderResult>;
|
|
164
207
|
cancelAllOrders(): Promise<OrderResult>;
|
|
208
|
+
/**
|
|
209
|
+
* Cancel orders by market or asset
|
|
210
|
+
*
|
|
211
|
+
* @param marketId - Market condition ID (optional)
|
|
212
|
+
* @param assetId - Token ID (optional)
|
|
213
|
+
* @returns Cancel result with canceled order IDs
|
|
214
|
+
*/
|
|
215
|
+
cancelMarketOrders(marketId?: string, assetId?: string): Promise<OrderResult>;
|
|
165
216
|
getOpenOrders(marketId?: string): Promise<Order[]>;
|
|
217
|
+
/**
|
|
218
|
+
* Check if an order can be cancelled
|
|
219
|
+
*
|
|
220
|
+
* Orders can be cancelled if they are in OPEN or PARTIALLY_FILLED status.
|
|
221
|
+
* Orders in terminal states (FILLED, CANCELLED, EXPIRED, REJECTED) or
|
|
222
|
+
* PENDING state cannot be cancelled via API.
|
|
223
|
+
*
|
|
224
|
+
* @param orderId - Order ID to check
|
|
225
|
+
* @returns Promise<boolean> - true if order can be cancelled
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* const canCancel = await sdk.trading.canCancelOrder(orderId);
|
|
230
|
+
* if (canCancel) {
|
|
231
|
+
* await sdk.trading.cancelOrder(orderId);
|
|
232
|
+
* }
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
canCancelOrder(orderId: string): Promise<boolean>;
|
|
236
|
+
/**
|
|
237
|
+
* Get order fill progress as percentage
|
|
238
|
+
*
|
|
239
|
+
* Returns the percentage of the order that has been filled (0-100).
|
|
240
|
+
* Useful for tracking partial fills and displaying progress.
|
|
241
|
+
*
|
|
242
|
+
* @param orderId - Order ID to check
|
|
243
|
+
* @returns Promise<number | null> - Fill percentage (0-100) or null if order not found
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* const progress = await sdk.trading.getOrderProgress(orderId);
|
|
248
|
+
* if (progress !== null) {
|
|
249
|
+
* console.log(`Order ${progress.toFixed(1)}% filled`);
|
|
250
|
+
* }
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
getOrderProgress(orderId: string): Promise<number | null>;
|
|
166
254
|
getTrades(marketId?: string): Promise<TradeInfo[]>;
|
|
167
255
|
isOrderScoring(orderId: string): Promise<boolean>;
|
|
168
256
|
areOrdersScoring(orderIds: string[]): Promise<Record<string, boolean>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trading-service.d.ts","sourceRoot":"","sources":["../../../src/services/trading-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,UAAU,EAMV,KAAK,QAAQ,EACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,WAAW,EAAW,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,KAAK,EAAE,IAAI,EAAa,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"trading-service.d.ts","sourceRoot":"","sources":["../../../src/services/trading-service.ts"],"names":[],"mappings":"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"}
|