@waiaas/daemon 2.5.0-rc.1 → 2.6.0-rc

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 (142) hide show
  1. package/dist/api/middleware/error-handler.d.ts +1 -1
  2. package/dist/api/middleware/error-handler.js +2 -2
  3. package/dist/api/middleware/error-handler.js.map +1 -1
  4. package/dist/api/routes/admin.d.ts.map +1 -1
  5. package/dist/api/routes/admin.js +6 -30
  6. package/dist/api/routes/admin.js.map +1 -1
  7. package/dist/api/routes/incoming.d.ts +40 -0
  8. package/dist/api/routes/incoming.d.ts.map +1 -0
  9. package/dist/api/routes/incoming.js +281 -0
  10. package/dist/api/routes/incoming.js.map +1 -0
  11. package/dist/api/routes/openapi-schemas.d.ts +243 -2
  12. package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
  13. package/dist/api/routes/openapi-schemas.js +77 -0
  14. package/dist/api/routes/openapi-schemas.js.map +1 -1
  15. package/dist/api/routes/wallets.d.ts +4 -0
  16. package/dist/api/routes/wallets.d.ts.map +1 -1
  17. package/dist/api/routes/wallets.js +173 -1
  18. package/dist/api/routes/wallets.js.map +1 -1
  19. package/dist/api/routes/x402.js +1 -1
  20. package/dist/api/routes/x402.js.map +1 -1
  21. package/dist/api/server.d.ts +4 -0
  22. package/dist/api/server.d.ts.map +1 -1
  23. package/dist/api/server.js +12 -0
  24. package/dist/api/server.js.map +1 -1
  25. package/dist/infrastructure/config/loader.d.ts +43 -0
  26. package/dist/infrastructure/config/loader.d.ts.map +1 -1
  27. package/dist/infrastructure/config/loader.js +13 -1
  28. package/dist/infrastructure/config/loader.js.map +1 -1
  29. package/dist/infrastructure/database/index.d.ts +1 -1
  30. package/dist/infrastructure/database/index.d.ts.map +1 -1
  31. package/dist/infrastructure/database/index.js +1 -1
  32. package/dist/infrastructure/database/index.js.map +1 -1
  33. package/dist/infrastructure/database/migrate.d.ts +2 -2
  34. package/dist/infrastructure/database/migrate.d.ts.map +1 -1
  35. package/dist/infrastructure/database/migrate.js +83 -5
  36. package/dist/infrastructure/database/migrate.js.map +1 -1
  37. package/dist/infrastructure/database/schema.d.ts +381 -1
  38. package/dist/infrastructure/database/schema.d.ts.map +1 -1
  39. package/dist/infrastructure/database/schema.js +42 -2
  40. package/dist/infrastructure/database/schema.js.map +1 -1
  41. package/dist/infrastructure/settings/hot-reload.d.ts +9 -0
  42. package/dist/infrastructure/settings/hot-reload.d.ts.map +1 -1
  43. package/dist/infrastructure/settings/hot-reload.js +34 -5
  44. package/dist/infrastructure/settings/hot-reload.js.map +1 -1
  45. package/dist/infrastructure/settings/setting-keys.d.ts +2 -2
  46. package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
  47. package/dist/infrastructure/settings/setting-keys.js +12 -3
  48. package/dist/infrastructure/settings/setting-keys.js.map +1 -1
  49. package/dist/lifecycle/daemon.d.ts +3 -1
  50. package/dist/lifecycle/daemon.d.ts.map +1 -1
  51. package/dist/lifecycle/daemon.js +84 -4
  52. package/dist/lifecycle/daemon.js.map +1 -1
  53. package/dist/notifications/channels/discord.d.ts.map +1 -1
  54. package/dist/notifications/channels/discord.js +17 -8
  55. package/dist/notifications/channels/discord.js.map +1 -1
  56. package/dist/notifications/channels/format-utils.d.ts +11 -0
  57. package/dist/notifications/channels/format-utils.d.ts.map +1 -0
  58. package/dist/notifications/channels/format-utils.js +19 -0
  59. package/dist/notifications/channels/format-utils.js.map +1 -0
  60. package/dist/notifications/channels/ntfy.d.ts.map +1 -1
  61. package/dist/notifications/channels/ntfy.js +15 -2
  62. package/dist/notifications/channels/ntfy.js.map +1 -1
  63. package/dist/notifications/channels/slack.d.ts.map +1 -1
  64. package/dist/notifications/channels/slack.js +16 -7
  65. package/dist/notifications/channels/slack.js.map +1 -1
  66. package/dist/notifications/channels/telegram.d.ts.map +1 -1
  67. package/dist/notifications/channels/telegram.js +17 -5
  68. package/dist/notifications/channels/telegram.js.map +1 -1
  69. package/dist/notifications/notification-service.d.ts +14 -0
  70. package/dist/notifications/notification-service.d.ts.map +1 -1
  71. package/dist/notifications/notification-service.js +83 -2
  72. package/dist/notifications/notification-service.js.map +1 -1
  73. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.d.ts +11 -0
  74. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.d.ts.map +1 -0
  75. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.js +432 -0
  76. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.js.map +1 -0
  77. package/dist/services/incoming/__tests__/incoming-tx-queue.test.d.ts +12 -0
  78. package/dist/services/incoming/__tests__/incoming-tx-queue.test.d.ts.map +1 -0
  79. package/dist/services/incoming/__tests__/incoming-tx-queue.test.js +419 -0
  80. package/dist/services/incoming/__tests__/incoming-tx-queue.test.js.map +1 -0
  81. package/dist/services/incoming/__tests__/incoming-tx-workers.test.d.ts +14 -0
  82. package/dist/services/incoming/__tests__/incoming-tx-workers.test.d.ts.map +1 -0
  83. package/dist/services/incoming/__tests__/incoming-tx-workers.test.js +452 -0
  84. package/dist/services/incoming/__tests__/incoming-tx-workers.test.js.map +1 -0
  85. package/dist/services/incoming/__tests__/integration-pitfall.test.d.ts +17 -0
  86. package/dist/services/incoming/__tests__/integration-pitfall.test.d.ts.map +1 -0
  87. package/dist/services/incoming/__tests__/integration-pitfall.test.js +653 -0
  88. package/dist/services/incoming/__tests__/integration-pitfall.test.js.map +1 -0
  89. package/dist/services/incoming/__tests__/integration-resilience.test.d.ts +14 -0
  90. package/dist/services/incoming/__tests__/integration-resilience.test.d.ts.map +1 -0
  91. package/dist/services/incoming/__tests__/integration-resilience.test.js +501 -0
  92. package/dist/services/incoming/__tests__/integration-resilience.test.js.map +1 -0
  93. package/dist/services/incoming/__tests__/integration-wiring.test.d.ts +15 -0
  94. package/dist/services/incoming/__tests__/integration-wiring.test.d.ts.map +1 -0
  95. package/dist/services/incoming/__tests__/integration-wiring.test.js +355 -0
  96. package/dist/services/incoming/__tests__/integration-wiring.test.js.map +1 -0
  97. package/dist/services/incoming/__tests__/safety-rules.test.d.ts +10 -0
  98. package/dist/services/incoming/__tests__/safety-rules.test.d.ts.map +1 -0
  99. package/dist/services/incoming/__tests__/safety-rules.test.js +165 -0
  100. package/dist/services/incoming/__tests__/safety-rules.test.js.map +1 -0
  101. package/dist/services/incoming/__tests__/subscription-multiplexer.test.d.ts +2 -0
  102. package/dist/services/incoming/__tests__/subscription-multiplexer.test.d.ts.map +1 -0
  103. package/dist/services/incoming/__tests__/subscription-multiplexer.test.js +267 -0
  104. package/dist/services/incoming/__tests__/subscription-multiplexer.test.js.map +1 -0
  105. package/dist/services/incoming/incoming-tx-monitor-service.d.ts +98 -0
  106. package/dist/services/incoming/incoming-tx-monitor-service.d.ts.map +1 -0
  107. package/dist/services/incoming/incoming-tx-monitor-service.js +336 -0
  108. package/dist/services/incoming/incoming-tx-monitor-service.js.map +1 -0
  109. package/dist/services/incoming/incoming-tx-queue.d.ts +52 -0
  110. package/dist/services/incoming/incoming-tx-queue.d.ts.map +1 -0
  111. package/dist/services/incoming/incoming-tx-queue.js +109 -0
  112. package/dist/services/incoming/incoming-tx-queue.js.map +1 -0
  113. package/dist/services/incoming/incoming-tx-workers.d.ts +89 -0
  114. package/dist/services/incoming/incoming-tx-workers.d.ts.map +1 -0
  115. package/dist/services/incoming/incoming-tx-workers.js +176 -0
  116. package/dist/services/incoming/incoming-tx-workers.js.map +1 -0
  117. package/dist/services/incoming/index.d.ts +14 -0
  118. package/dist/services/incoming/index.d.ts.map +1 -0
  119. package/dist/services/incoming/index.js +11 -0
  120. package/dist/services/incoming/index.js.map +1 -0
  121. package/dist/services/incoming/safety-rules.d.ts +70 -0
  122. package/dist/services/incoming/safety-rules.d.ts.map +1 -0
  123. package/dist/services/incoming/safety-rules.js +68 -0
  124. package/dist/services/incoming/safety-rules.js.map +1 -0
  125. package/dist/services/incoming/subscription-multiplexer.d.ts +87 -0
  126. package/dist/services/incoming/subscription-multiplexer.d.ts.map +1 -0
  127. package/dist/services/incoming/subscription-multiplexer.js +169 -0
  128. package/dist/services/incoming/subscription-multiplexer.js.map +1 -0
  129. package/dist/services/signing-sdk/approval-channel-router.d.ts +1 -1
  130. package/dist/services/signing-sdk/approval-channel-router.d.ts.map +1 -1
  131. package/dist/services/signing-sdk/approval-channel-router.js +2 -3
  132. package/dist/services/signing-sdk/approval-channel-router.js.map +1 -1
  133. package/dist/services/signing-sdk/channels/wallet-notification-channel.js +1 -1
  134. package/dist/services/signing-sdk/channels/wallet-notification-channel.js.map +1 -1
  135. package/dist/services/x402/x402-domain-policy.d.ts +6 -1
  136. package/dist/services/x402/x402-domain-policy.d.ts.map +1 -1
  137. package/dist/services/x402/x402-domain-policy.js +6 -2
  138. package/dist/services/x402/x402-domain-policy.js.map +1 -1
  139. package/package.json +4 -4
  140. package/public/admin/assets/index-D06O_cSo.js +1 -0
  141. package/public/admin/index.html +1 -1
  142. package/public/admin/assets/index-BLLOYSZp.js +0 -1
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Tests for IncomingTxQueue.
3
+ *
4
+ * Covers: Map-based dedup by txHash:walletId, batch flush with
5
+ * ON CONFLICT DO NOTHING, overflow protection (MAX_QUEUE_SIZE),
6
+ * drain for graceful shutdown, and edge cases.
7
+ *
8
+ * Uses a mock better-sqlite3 Database to verify SQL statements
9
+ * and parameter values without requiring a real SQLite instance.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=incoming-tx-queue.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incoming-tx-queue.test.d.ts","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/incoming-tx-queue.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,419 @@
1
+ /**
2
+ * Tests for IncomingTxQueue.
3
+ *
4
+ * Covers: Map-based dedup by txHash:walletId, batch flush with
5
+ * ON CONFLICT DO NOTHING, overflow protection (MAX_QUEUE_SIZE),
6
+ * drain for graceful shutdown, and edge cases.
7
+ *
8
+ * Uses a mock better-sqlite3 Database to verify SQL statements
9
+ * and parameter values without requiring a real SQLite instance.
10
+ */
11
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
12
+ import { IncomingTxQueue } from '../incoming-tx-queue.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Mock generateId to return predictable IDs
15
+ // ---------------------------------------------------------------------------
16
+ let idCounter = 0;
17
+ vi.mock('../../../infrastructure/database/id.js', () => ({
18
+ generateId: () => `uuid-${++idCounter}`,
19
+ }));
20
+ // ---------------------------------------------------------------------------
21
+ // Helpers
22
+ // ---------------------------------------------------------------------------
23
+ let txCounter = 0;
24
+ /**
25
+ * Factory for IncomingTransaction with sensible defaults.
26
+ * Each call produces a unique txHash to prevent unintentional dedup.
27
+ */
28
+ function makeTx(overrides) {
29
+ txCounter++;
30
+ return {
31
+ id: '', // Will be replaced by generateId in flush
32
+ walletId: 'wallet-1',
33
+ chain: 'solana',
34
+ network: 'mainnet',
35
+ txHash: `tx-hash-${txCounter}`,
36
+ fromAddress: 'from-addr-1',
37
+ amount: '1000000',
38
+ tokenAddress: null,
39
+ status: 'DETECTED',
40
+ blockNumber: null,
41
+ detectedAt: Math.floor(Date.now() / 1000),
42
+ confirmedAt: null,
43
+ isSuspicious: false,
44
+ ...overrides,
45
+ };
46
+ }
47
+ /**
48
+ * Create a mock better-sqlite3 Database.
49
+ *
50
+ * @param changesOverride - Function that returns `changes` value per stmt.run() call.
51
+ * By default returns 1 (row inserted). Return 0 to simulate ON CONFLICT skip.
52
+ */
53
+ function createMockDb(changesOverride) {
54
+ let stmtRunCallIndex = 0;
55
+ const runCalls = [];
56
+ let prepareSql = '';
57
+ const mockStmt = {
58
+ run: (...args) => {
59
+ runCalls.push(args);
60
+ const changes = changesOverride
61
+ ? changesOverride(stmtRunCallIndex++)
62
+ : 1;
63
+ return { changes };
64
+ },
65
+ };
66
+ const mockDb = {
67
+ prepare: (sql) => {
68
+ prepareSql = sql;
69
+ return mockStmt;
70
+ },
71
+ transaction: (fn) => {
72
+ // Mimic better-sqlite3 transaction: returns a callable that executes fn
73
+ return (batch) => fn(batch);
74
+ },
75
+ };
76
+ return {
77
+ db: mockDb,
78
+ getRunCalls: () => runCalls,
79
+ getPrepareSql: () => prepareSql,
80
+ resetCalls: () => {
81
+ runCalls.length = 0;
82
+ stmtRunCallIndex = 0;
83
+ },
84
+ };
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // Tests
88
+ // ---------------------------------------------------------------------------
89
+ describe('IncomingTxQueue', () => {
90
+ let queue;
91
+ beforeEach(() => {
92
+ queue = new IncomingTxQueue();
93
+ idCounter = 0;
94
+ txCounter = 0;
95
+ });
96
+ // -----------------------------------------------------------------------
97
+ // 1. Dedup tests
98
+ // -----------------------------------------------------------------------
99
+ describe('push() deduplication', () => {
100
+ it('should deduplicate by txHash:walletId -- same key twice results in size 1', () => {
101
+ const tx = makeTx({ txHash: 'dup-hash', walletId: 'w1' });
102
+ queue.push(tx);
103
+ queue.push(tx);
104
+ expect(queue.size).toBe(1);
105
+ });
106
+ it('should allow same txHash with different walletId -- size 2', () => {
107
+ queue.push(makeTx({ txHash: 'same-hash', walletId: 'w1' }));
108
+ queue.push(makeTx({ txHash: 'same-hash', walletId: 'w2' }));
109
+ expect(queue.size).toBe(2);
110
+ });
111
+ it('should allow different txHash with same walletId -- size 2', () => {
112
+ queue.push(makeTx({ txHash: 'hash-a', walletId: 'w1' }));
113
+ queue.push(makeTx({ txHash: 'hash-b', walletId: 'w1' }));
114
+ expect(queue.size).toBe(2);
115
+ });
116
+ it('should keep the first entry when duplicate is pushed', () => {
117
+ const first = makeTx({ txHash: 'dup', walletId: 'w1', amount: '100' });
118
+ const second = makeTx({ txHash: 'dup', walletId: 'w1', amount: '999' });
119
+ queue.push(first);
120
+ queue.push(second);
121
+ const mock = createMockDb();
122
+ const result = queue.flush(mock.db);
123
+ // Should have the first entry's amount, not the second
124
+ expect(result[0].amount).toBe('100');
125
+ });
126
+ });
127
+ // -----------------------------------------------------------------------
128
+ // 2. Flush tests
129
+ // -----------------------------------------------------------------------
130
+ describe('flush()', () => {
131
+ it('should return empty array when queue is empty', () => {
132
+ const mock = createMockDb();
133
+ const result = queue.flush(mock.db);
134
+ expect(result).toEqual([]);
135
+ });
136
+ it('should flush 3 items, call sqlite.transaction, return 3 items, queue size 0', () => {
137
+ const mock = createMockDb();
138
+ queue.push(makeTx());
139
+ queue.push(makeTx());
140
+ queue.push(makeTx());
141
+ const result = queue.flush(mock.db);
142
+ expect(result).toHaveLength(3);
143
+ expect(queue.size).toBe(0);
144
+ expect(mock.getRunCalls()).toHaveLength(3);
145
+ });
146
+ it('should flush at most MAX_BATCH (100) items, leaving remainder in queue', () => {
147
+ const mock = createMockDb();
148
+ for (let i = 0; i < 150; i++) {
149
+ queue.push(makeTx());
150
+ }
151
+ expect(queue.size).toBe(150);
152
+ const result = queue.flush(mock.db);
153
+ expect(result).toHaveLength(100);
154
+ expect(queue.size).toBe(50);
155
+ });
156
+ it('should generate UUID v7 IDs for each item via generateId()', () => {
157
+ const mock = createMockDb();
158
+ queue.push(makeTx());
159
+ queue.push(makeTx());
160
+ const result = queue.flush(mock.db);
161
+ expect(result[0].id).toBe('uuid-1');
162
+ expect(result[1].id).toBe('uuid-2');
163
+ });
164
+ it('should pass correct parameters to stmt.run()', () => {
165
+ const mock = createMockDb();
166
+ const tx = makeTx({
167
+ walletId: 'w-abc',
168
+ chain: 'ethereum',
169
+ network: 'ethereum-mainnet',
170
+ txHash: 'hash-xyz',
171
+ fromAddress: 'from-0x123',
172
+ amount: '5000000',
173
+ tokenAddress: '0xtoken',
174
+ status: 'DETECTED',
175
+ blockNumber: 42,
176
+ detectedAt: 1700000000,
177
+ confirmedAt: null,
178
+ isSuspicious: true,
179
+ });
180
+ queue.push(tx);
181
+ queue.flush(mock.db);
182
+ const calls = mock.getRunCalls();
183
+ expect(calls).toHaveLength(1);
184
+ // Parameters: id, walletId, chain, network, txHash, fromAddress, amount, tokenAddress, status, blockNumber, detectedAt, confirmedAt, isSuspicious
185
+ expect(calls[0]).toEqual([
186
+ 'uuid-1', // id (generated)
187
+ 'w-abc', // walletId
188
+ 'ethereum', // chain
189
+ 'ethereum-mainnet', // network
190
+ 'hash-xyz', // txHash
191
+ 'from-0x123', // fromAddress
192
+ '5000000', // amount
193
+ '0xtoken', // tokenAddress
194
+ 'DETECTED', // status
195
+ 42, // blockNumber
196
+ 1700000000, // detectedAt
197
+ null, // confirmedAt
198
+ 1, // isSuspicious (boolean -> 1)
199
+ ]);
200
+ });
201
+ it('should convert isSuspicious false to 0', () => {
202
+ const mock = createMockDb();
203
+ queue.push(makeTx({ isSuspicious: false }));
204
+ queue.flush(mock.db);
205
+ const calls = mock.getRunCalls();
206
+ // Last parameter is isSuspicious
207
+ expect(calls[0][12]).toBe(0);
208
+ });
209
+ it('should convert undefined isSuspicious to 0', () => {
210
+ const mock = createMockDb();
211
+ const tx = makeTx();
212
+ delete tx.isSuspicious;
213
+ queue.push(tx);
214
+ queue.flush(mock.db);
215
+ const calls = mock.getRunCalls();
216
+ expect(calls[0][12]).toBe(0);
217
+ });
218
+ });
219
+ // -----------------------------------------------------------------------
220
+ // 3. ON CONFLICT tests
221
+ // -----------------------------------------------------------------------
222
+ describe('ON CONFLICT handling', () => {
223
+ it('should exclude items where stmt.run().changes === 0 from returned array', () => {
224
+ // Items 0 and 2 inserted (changes=1), item 1 skipped (changes=0)
225
+ const mock = createMockDb((idx) => (idx === 1 ? 0 : 1));
226
+ queue.push(makeTx({ txHash: 'a' }));
227
+ queue.push(makeTx({ txHash: 'b' }));
228
+ queue.push(makeTx({ txHash: 'c' }));
229
+ const result = queue.flush(mock.db);
230
+ expect(result).toHaveLength(2);
231
+ expect(result[0].txHash).toBe('a');
232
+ expect(result[1].txHash).toBe('c');
233
+ });
234
+ it('should return empty array if all items conflict', () => {
235
+ const mock = createMockDb(() => 0);
236
+ queue.push(makeTx());
237
+ queue.push(makeTx());
238
+ const result = queue.flush(mock.db);
239
+ expect(result).toHaveLength(0);
240
+ // Queue should still be empty (items were extracted)
241
+ expect(queue.size).toBe(0);
242
+ });
243
+ it('should include ON CONFLICT(tx_hash, wallet_id) DO NOTHING in INSERT SQL', () => {
244
+ const mock = createMockDb();
245
+ queue.push(makeTx());
246
+ queue.flush(mock.db);
247
+ const sql = mock.getPrepareSql();
248
+ expect(sql).toContain('ON CONFLICT(tx_hash, wallet_id) DO NOTHING');
249
+ });
250
+ it('should include all 13 column names in INSERT SQL', () => {
251
+ const mock = createMockDb();
252
+ queue.push(makeTx());
253
+ queue.flush(mock.db);
254
+ const sql = mock.getPrepareSql();
255
+ const expectedColumns = [
256
+ 'id', 'wallet_id', 'chain', 'network', 'tx_hash',
257
+ 'from_address', 'amount', 'token_address', 'status',
258
+ 'block_number', 'detected_at', 'confirmed_at', 'is_suspicious',
259
+ ];
260
+ for (const col of expectedColumns) {
261
+ expect(sql).toContain(col);
262
+ }
263
+ });
264
+ });
265
+ // -----------------------------------------------------------------------
266
+ // 4. Overflow tests
267
+ // -----------------------------------------------------------------------
268
+ describe('overflow protection (MAX_QUEUE_SIZE)', () => {
269
+ it('should cap queue at 10,000 entries when pushing 10,001', () => {
270
+ for (let i = 0; i < 10_001; i++) {
271
+ queue.push(makeTx());
272
+ }
273
+ expect(queue.size).toBe(10_000);
274
+ });
275
+ it('should log console.warn on overflow', () => {
276
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
277
+ // Fill to MAX_QUEUE_SIZE
278
+ for (let i = 0; i < 10_000; i++) {
279
+ queue.push(makeTx());
280
+ }
281
+ expect(warnSpy).not.toHaveBeenCalled();
282
+ // Push one more to trigger overflow
283
+ queue.push(makeTx());
284
+ expect(warnSpy).toHaveBeenCalledWith('IncomingTxQueue overflow: dropping oldest entry');
285
+ warnSpy.mockRestore();
286
+ });
287
+ it('should drop the oldest entry on overflow (first-inserted is removed)', () => {
288
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
289
+ // Push 10,000 items, keeping track of the first
290
+ const firstTx = makeTx({ txHash: 'first-tx' });
291
+ queue.push(firstTx);
292
+ for (let i = 1; i < 10_000; i++) {
293
+ queue.push(makeTx());
294
+ }
295
+ expect(queue.size).toBe(10_000);
296
+ // Push one more -- should evict 'first-tx'
297
+ const overflowTx = makeTx({ txHash: 'overflow-tx' });
298
+ queue.push(overflowTx);
299
+ expect(queue.size).toBe(10_000);
300
+ // Flush all and verify first-tx is not present
301
+ const mock = createMockDb();
302
+ const allInserted = [];
303
+ while (queue.size > 0) {
304
+ allInserted.push(...queue.flush(mock.db));
305
+ }
306
+ const hashes = allInserted.map((tx) => tx.txHash);
307
+ expect(hashes).not.toContain('first-tx');
308
+ expect(hashes).toContain('overflow-tx');
309
+ warnSpy.mockRestore();
310
+ });
311
+ });
312
+ // -----------------------------------------------------------------------
313
+ // 5. drain() tests
314
+ // -----------------------------------------------------------------------
315
+ describe('drain()', () => {
316
+ it('should drain 250 items across multiple flush cycles, queue empty after', () => {
317
+ const mock = createMockDb();
318
+ for (let i = 0; i < 250; i++) {
319
+ queue.push(makeTx());
320
+ }
321
+ const result = queue.drain(mock.db);
322
+ expect(result).toHaveLength(250);
323
+ expect(queue.size).toBe(0);
324
+ });
325
+ it('should return empty array when draining empty queue', () => {
326
+ const mock = createMockDb();
327
+ const result = queue.drain(mock.db);
328
+ expect(result).toEqual([]);
329
+ });
330
+ it('should combine results from multiple flush cycles', () => {
331
+ const mock = createMockDb();
332
+ // 250 items = 3 flush cycles (100 + 100 + 50)
333
+ for (let i = 0; i < 250; i++) {
334
+ queue.push(makeTx());
335
+ }
336
+ const result = queue.drain(mock.db);
337
+ // Should have all 250 items with unique generated IDs
338
+ const ids = new Set(result.map((tx) => tx.id));
339
+ expect(ids.size).toBe(250);
340
+ });
341
+ });
342
+ // -----------------------------------------------------------------------
343
+ // 6. Thread safety / single-threaded correctness tests
344
+ // -----------------------------------------------------------------------
345
+ describe('single-threaded correctness', () => {
346
+ it('should only flush items present at call time (not items pushed during iteration)', () => {
347
+ const mock = createMockDb();
348
+ // Push 5 items
349
+ for (let i = 0; i < 5; i++) {
350
+ queue.push(makeTx());
351
+ }
352
+ // flush extracts items from Map. Since JS is single-threaded,
353
+ // no new items can appear during flush. Verify flush count matches.
354
+ const result = queue.flush(mock.db);
355
+ expect(result).toHaveLength(5);
356
+ expect(queue.size).toBe(0);
357
+ });
358
+ it('should handle rapid push-flush-push-flush cycles correctly', () => {
359
+ const mock = createMockDb();
360
+ queue.push(makeTx({ txHash: 'batch1-a' }));
361
+ queue.push(makeTx({ txHash: 'batch1-b' }));
362
+ const result1 = queue.flush(mock.db);
363
+ expect(result1).toHaveLength(2);
364
+ expect(queue.size).toBe(0);
365
+ queue.push(makeTx({ txHash: 'batch2-a' }));
366
+ const result2 = queue.flush(mock.db);
367
+ expect(result2).toHaveLength(1);
368
+ expect(result2[0].txHash).toBe('batch2-a');
369
+ expect(queue.size).toBe(0);
370
+ });
371
+ });
372
+ // -----------------------------------------------------------------------
373
+ // 7. Edge cases
374
+ // -----------------------------------------------------------------------
375
+ describe('edge cases', () => {
376
+ it('should handle null tokenAddress correctly', () => {
377
+ const mock = createMockDb();
378
+ queue.push(makeTx({ tokenAddress: null }));
379
+ queue.flush(mock.db);
380
+ const calls = mock.getRunCalls();
381
+ // tokenAddress is at index 7 in the parameter list
382
+ expect(calls[0][7]).toBeNull();
383
+ });
384
+ it('should handle token transfer with tokenAddress', () => {
385
+ const mock = createMockDb();
386
+ queue.push(makeTx({ tokenAddress: 'So11111111111111111111111111111111111111112' }));
387
+ queue.flush(mock.db);
388
+ const calls = mock.getRunCalls();
389
+ expect(calls[0][7]).toBe('So11111111111111111111111111111111111111112');
390
+ });
391
+ it('should handle isSuspicious=true correctly in flush parameters', () => {
392
+ const mock = createMockDb();
393
+ queue.push(makeTx({ isSuspicious: true }));
394
+ queue.flush(mock.db);
395
+ const calls = mock.getRunCalls();
396
+ // isSuspicious is at index 12 (last parameter)
397
+ expect(calls[0][12]).toBe(1);
398
+ });
399
+ it('should correctly extract exactly MAX_BATCH from larger queue', () => {
400
+ const mock = createMockDb();
401
+ // Push exactly 100 + 1 items
402
+ for (let i = 0; i < 101; i++) {
403
+ queue.push(makeTx());
404
+ }
405
+ const result = queue.flush(mock.db);
406
+ expect(result).toHaveLength(100);
407
+ expect(queue.size).toBe(1);
408
+ // Second flush gets the remaining 1
409
+ const result2 = queue.flush(mock.db);
410
+ expect(result2).toHaveLength(1);
411
+ expect(queue.size).toBe(0);
412
+ });
413
+ it('should report size 0 for newly created queue', () => {
414
+ const freshQueue = new IncomingTxQueue();
415
+ expect(freshQueue.size).toBe(0);
416
+ });
417
+ });
418
+ });
419
+ //# sourceMappingURL=incoming-tx-queue.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incoming-tx-queue.test.js","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/incoming-tx-queue.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,EAAE,CAAC,IAAI,CAAC,wCAAwC,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,UAAU,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE;CACxC,CAAC,CAAC,CAAC;AAEJ,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB;;;GAGG;AACH,SAAS,MAAM,CAAC,SAAwC;IACtD,SAAS,EAAE,CAAC;IACZ,OAAO;QACL,EAAE,EAAE,EAAE,EAAE,0CAA0C;QAClD,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,WAAW,SAAS,EAAE;QAC9B,WAAW,EAAE,aAAa;QAC1B,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,UAAU;QAClB,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QACzC,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,KAAK;QACnB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,eAA+C;IACnE,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,EAAE,CAAC;IAEpB,MAAM,QAAQ,GAAG;QACf,GAAG,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;YAC1B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM,OAAO,GAAG,eAAe;gBAC7B,CAAC,CAAC,eAAe,CAAC,gBAAgB,EAAE,CAAC;gBACrC,CAAC,CAAC,CAAC,CAAC;YACN,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;IAEF,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE;YACvB,UAAU,GAAG,GAAG,CAAC;YACjB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,WAAW,EAAE,CAAC,EAA2D,EAAE,EAAE;YAC3E,wEAAwE;YACxE,OAAO,CAAC,KAA4B,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,MAAsD;QAC1D,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ;QAC3B,aAAa,EAAE,GAAG,EAAE,CAAC,UAAU;QAC/B,UAAU,EAAE,GAAG,EAAE;YACf,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YACpB,gBAAgB,GAAG,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAE9E,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,KAAsB,CAAC;IAE3B,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9B,SAAS,GAAG,CAAC,CAAC;QACd,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,iBAAiB;IACjB,0EAA0E;IAE1E,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;YACnF,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACxE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEnB,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,uDAAuD;YACvD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,iBAAiB;IACjB,0EAA0E;IAE1E,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAErB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE7B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAErB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,MAAM,CAAC;gBAChB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,UAAU;gBACjB,OAAO,EAAE,kBAAkB;gBAC3B,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,YAAY;gBACzB,MAAM,EAAE,SAAS;gBACjB,YAAY,EAAE,SAAS;gBACvB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,EAAE;gBACf,UAAU,EAAE,UAAU;gBACtB,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC9B,kJAAkJ;YAClJ,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACvB,QAAQ,EAAQ,iBAAiB;gBACjC,OAAO,EAAS,WAAW;gBAC3B,UAAU,EAAM,QAAQ;gBACxB,kBAAkB,EAAE,UAAU;gBAC9B,UAAU,EAAM,SAAS;gBACzB,YAAY,EAAI,cAAc;gBAC9B,SAAS,EAAO,SAAS;gBACzB,SAAS,EAAO,eAAe;gBAC/B,UAAU,EAAM,SAAS;gBACzB,EAAE,EAAc,cAAc;gBAC9B,UAAU,EAAM,aAAa;gBAC7B,IAAI,EAAY,cAAc;gBAC9B,CAAC,EAAe,8BAA8B;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YAC5C,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,iCAAiC;YACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;YACpB,OAAQ,EAAyC,CAAC,YAAY,CAAC;YAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,uBAAuB;IACvB,0EAA0E;IAE1E,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;YACjF,iEAAiE;YACjE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAExD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAEnC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAErB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,qDAAqD;YACrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;YACjF,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAErB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAErB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACjC,MAAM,eAAe,GAAG;gBACtB,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;gBAChD,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ;gBACnD,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe;aAC/D,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,oBAAoB;IACpB,0EAA0E;IAE1E,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;QACpD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEvE,yBAAyB;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAEvC,oCAAoC;YACpC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACrB,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,iDAAiD,CAAC,CAAC;YAExF,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEvE,gDAAgD;YAChD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhC,2CAA2C;YAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhC,+CAA+C;YAC/C,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,WAAW,GAA0B,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBACtB,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAExC,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,mBAAmB;IACnB,0EAA0E;IAE1E,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,8CAA8C;YAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,sDAAsD;YACtD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,uDAAuD;IACvD,0EAA0E;IAE1E,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;YAC1F,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,eAAe;YACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YAED,8DAA8D;YAC9D,oEAAoE;YACpE,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAE5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YAC3C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE3B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,gBAAgB;IAChB,0EAA0E;IAE1E,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3C,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,mDAAmD;YACnD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,6CAA6C,EAAE,CAAC,CAAC,CAAC;YACpF,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3C,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,+CAA+C;YAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACtE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAC5B,6BAA6B;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE3B,oCAAoC;YACpC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Tests for incoming transaction worker handlers and cursor utilities.
3
+ *
4
+ * Covers:
5
+ * - Confirmation worker (Solana finalized check + EVM block threshold)
6
+ * - Retention policy worker (configurable days, hot-reload)
7
+ * - Gap recovery handler (pollAll() delegation)
8
+ * - Cursor utilities (updateCursor, loadCursor)
9
+ *
10
+ * Uses mock better-sqlite3 Database objects to isolate worker logic
11
+ * from actual database operations.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=incoming-tx-workers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incoming-tx-workers.test.d.ts","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/incoming-tx-workers.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}