@waiaas/daemon 2.5.0 → 2.6.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) 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/connect-info.d.ts.map +1 -1
  8. package/dist/api/routes/connect-info.js +6 -0
  9. package/dist/api/routes/connect-info.js.map +1 -1
  10. package/dist/api/routes/incoming.d.ts +40 -0
  11. package/dist/api/routes/incoming.d.ts.map +1 -0
  12. package/dist/api/routes/incoming.js +281 -0
  13. package/dist/api/routes/incoming.js.map +1 -0
  14. package/dist/api/routes/openapi-schemas.d.ts +337 -24
  15. package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
  16. package/dist/api/routes/openapi-schemas.js +78 -0
  17. package/dist/api/routes/openapi-schemas.js.map +1 -1
  18. package/dist/api/routes/tokens.d.ts.map +1 -1
  19. package/dist/api/routes/tokens.js +1 -0
  20. package/dist/api/routes/tokens.js.map +1 -1
  21. package/dist/api/routes/wallets.d.ts +4 -0
  22. package/dist/api/routes/wallets.d.ts.map +1 -1
  23. package/dist/api/routes/wallets.js +173 -1
  24. package/dist/api/routes/wallets.js.map +1 -1
  25. package/dist/api/routes/x402.js +1 -1
  26. package/dist/api/routes/x402.js.map +1 -1
  27. package/dist/api/server.d.ts +4 -0
  28. package/dist/api/server.d.ts.map +1 -1
  29. package/dist/api/server.js +12 -0
  30. package/dist/api/server.js.map +1 -1
  31. package/dist/infrastructure/config/loader.d.ts +43 -0
  32. package/dist/infrastructure/config/loader.d.ts.map +1 -1
  33. package/dist/infrastructure/config/loader.js +13 -1
  34. package/dist/infrastructure/config/loader.js.map +1 -1
  35. package/dist/infrastructure/database/index.d.ts +1 -1
  36. package/dist/infrastructure/database/index.d.ts.map +1 -1
  37. package/dist/infrastructure/database/index.js +1 -1
  38. package/dist/infrastructure/database/index.js.map +1 -1
  39. package/dist/infrastructure/database/migrate.d.ts +2 -2
  40. package/dist/infrastructure/database/migrate.d.ts.map +1 -1
  41. package/dist/infrastructure/database/migrate.js +123 -6
  42. package/dist/infrastructure/database/migrate.js.map +1 -1
  43. package/dist/infrastructure/database/schema.d.ts +400 -1
  44. package/dist/infrastructure/database/schema.d.ts.map +1 -1
  45. package/dist/infrastructure/database/schema.js +43 -2
  46. package/dist/infrastructure/database/schema.js.map +1 -1
  47. package/dist/infrastructure/oracle/coingecko-oracle.d.ts +9 -1
  48. package/dist/infrastructure/oracle/coingecko-oracle.d.ts.map +1 -1
  49. package/dist/infrastructure/oracle/coingecko-oracle.js +40 -23
  50. package/dist/infrastructure/oracle/coingecko-oracle.js.map +1 -1
  51. package/dist/infrastructure/oracle/coingecko-platform-ids.d.ts +11 -10
  52. package/dist/infrastructure/oracle/coingecko-platform-ids.d.ts.map +1 -1
  53. package/dist/infrastructure/oracle/coingecko-platform-ids.js +20 -12
  54. package/dist/infrastructure/oracle/coingecko-platform-ids.js.map +1 -1
  55. package/dist/infrastructure/oracle/index.d.ts +1 -1
  56. package/dist/infrastructure/oracle/index.d.ts.map +1 -1
  57. package/dist/infrastructure/oracle/index.js +1 -1
  58. package/dist/infrastructure/oracle/index.js.map +1 -1
  59. package/dist/infrastructure/oracle/oracle-chain.d.ts.map +1 -1
  60. package/dist/infrastructure/oracle/oracle-chain.js +7 -4
  61. package/dist/infrastructure/oracle/oracle-chain.js.map +1 -1
  62. package/dist/infrastructure/oracle/price-cache.d.ts +24 -8
  63. package/dist/infrastructure/oracle/price-cache.d.ts.map +1 -1
  64. package/dist/infrastructure/oracle/price-cache.js +32 -11
  65. package/dist/infrastructure/oracle/price-cache.js.map +1 -1
  66. package/dist/infrastructure/oracle/pyth-feed-ids.d.ts +11 -8
  67. package/dist/infrastructure/oracle/pyth-feed-ids.d.ts.map +1 -1
  68. package/dist/infrastructure/oracle/pyth-feed-ids.js +16 -17
  69. package/dist/infrastructure/oracle/pyth-feed-ids.js.map +1 -1
  70. package/dist/infrastructure/oracle/pyth-oracle.d.ts.map +1 -1
  71. package/dist/infrastructure/oracle/pyth-oracle.js +7 -4
  72. package/dist/infrastructure/oracle/pyth-oracle.js.map +1 -1
  73. package/dist/infrastructure/settings/hot-reload.d.ts +9 -0
  74. package/dist/infrastructure/settings/hot-reload.d.ts.map +1 -1
  75. package/dist/infrastructure/settings/hot-reload.js +34 -5
  76. package/dist/infrastructure/settings/hot-reload.js.map +1 -1
  77. package/dist/infrastructure/settings/setting-keys.d.ts +2 -2
  78. package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
  79. package/dist/infrastructure/settings/setting-keys.js +12 -3
  80. package/dist/infrastructure/settings/setting-keys.js.map +1 -1
  81. package/dist/infrastructure/token-registry/token-registry-service.d.ts +1 -0
  82. package/dist/infrastructure/token-registry/token-registry-service.d.ts.map +1 -1
  83. package/dist/infrastructure/token-registry/token-registry-service.js +15 -1
  84. package/dist/infrastructure/token-registry/token-registry-service.js.map +1 -1
  85. package/dist/lifecycle/daemon.d.ts +3 -1
  86. package/dist/lifecycle/daemon.d.ts.map +1 -1
  87. package/dist/lifecycle/daemon.js +84 -4
  88. package/dist/lifecycle/daemon.js.map +1 -1
  89. package/dist/notifications/channels/discord.d.ts.map +1 -1
  90. package/dist/notifications/channels/discord.js +21 -8
  91. package/dist/notifications/channels/discord.js.map +1 -1
  92. package/dist/notifications/channels/format-utils.d.ts +11 -0
  93. package/dist/notifications/channels/format-utils.d.ts.map +1 -0
  94. package/dist/notifications/channels/format-utils.js +19 -0
  95. package/dist/notifications/channels/format-utils.js.map +1 -0
  96. package/dist/notifications/channels/ntfy.d.ts.map +1 -1
  97. package/dist/notifications/channels/ntfy.js +18 -2
  98. package/dist/notifications/channels/ntfy.js.map +1 -1
  99. package/dist/notifications/channels/slack.d.ts.map +1 -1
  100. package/dist/notifications/channels/slack.js +20 -7
  101. package/dist/notifications/channels/slack.js.map +1 -1
  102. package/dist/notifications/channels/telegram.d.ts.map +1 -1
  103. package/dist/notifications/channels/telegram.js +21 -5
  104. package/dist/notifications/channels/telegram.js.map +1 -1
  105. package/dist/notifications/notification-service.d.ts +14 -0
  106. package/dist/notifications/notification-service.d.ts.map +1 -1
  107. package/dist/notifications/notification-service.js +89 -2
  108. package/dist/notifications/notification-service.js.map +1 -1
  109. package/dist/pipeline/database-policy-engine.d.ts +9 -5
  110. package/dist/pipeline/database-policy-engine.d.ts.map +1 -1
  111. package/dist/pipeline/database-policy-engine.js +42 -10
  112. package/dist/pipeline/database-policy-engine.js.map +1 -1
  113. package/dist/pipeline/resolve-effective-amount-usd.d.ts +1 -1
  114. package/dist/pipeline/resolve-effective-amount-usd.d.ts.map +1 -1
  115. package/dist/pipeline/resolve-effective-amount-usd.js +5 -3
  116. package/dist/pipeline/resolve-effective-amount-usd.js.map +1 -1
  117. package/dist/pipeline/stages.d.ts.map +1 -1
  118. package/dist/pipeline/stages.js +7 -1
  119. package/dist/pipeline/stages.js.map +1 -1
  120. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.d.ts +11 -0
  121. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.d.ts.map +1 -0
  122. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.js +432 -0
  123. package/dist/services/incoming/__tests__/incoming-tx-monitor-service.test.js.map +1 -0
  124. package/dist/services/incoming/__tests__/incoming-tx-queue.test.d.ts +12 -0
  125. package/dist/services/incoming/__tests__/incoming-tx-queue.test.d.ts.map +1 -0
  126. package/dist/services/incoming/__tests__/incoming-tx-queue.test.js +419 -0
  127. package/dist/services/incoming/__tests__/incoming-tx-queue.test.js.map +1 -0
  128. package/dist/services/incoming/__tests__/incoming-tx-workers.test.d.ts +14 -0
  129. package/dist/services/incoming/__tests__/incoming-tx-workers.test.d.ts.map +1 -0
  130. package/dist/services/incoming/__tests__/incoming-tx-workers.test.js +452 -0
  131. package/dist/services/incoming/__tests__/incoming-tx-workers.test.js.map +1 -0
  132. package/dist/services/incoming/__tests__/integration-pitfall.test.d.ts +17 -0
  133. package/dist/services/incoming/__tests__/integration-pitfall.test.d.ts.map +1 -0
  134. package/dist/services/incoming/__tests__/integration-pitfall.test.js +653 -0
  135. package/dist/services/incoming/__tests__/integration-pitfall.test.js.map +1 -0
  136. package/dist/services/incoming/__tests__/integration-resilience.test.d.ts +14 -0
  137. package/dist/services/incoming/__tests__/integration-resilience.test.d.ts.map +1 -0
  138. package/dist/services/incoming/__tests__/integration-resilience.test.js +501 -0
  139. package/dist/services/incoming/__tests__/integration-resilience.test.js.map +1 -0
  140. package/dist/services/incoming/__tests__/integration-wiring.test.d.ts +15 -0
  141. package/dist/services/incoming/__tests__/integration-wiring.test.d.ts.map +1 -0
  142. package/dist/services/incoming/__tests__/integration-wiring.test.js +355 -0
  143. package/dist/services/incoming/__tests__/integration-wiring.test.js.map +1 -0
  144. package/dist/services/incoming/__tests__/safety-rules.test.d.ts +10 -0
  145. package/dist/services/incoming/__tests__/safety-rules.test.d.ts.map +1 -0
  146. package/dist/services/incoming/__tests__/safety-rules.test.js +165 -0
  147. package/dist/services/incoming/__tests__/safety-rules.test.js.map +1 -0
  148. package/dist/services/incoming/__tests__/subscription-multiplexer.test.d.ts +2 -0
  149. package/dist/services/incoming/__tests__/subscription-multiplexer.test.d.ts.map +1 -0
  150. package/dist/services/incoming/__tests__/subscription-multiplexer.test.js +267 -0
  151. package/dist/services/incoming/__tests__/subscription-multiplexer.test.js.map +1 -0
  152. package/dist/services/incoming/incoming-tx-monitor-service.d.ts +98 -0
  153. package/dist/services/incoming/incoming-tx-monitor-service.d.ts.map +1 -0
  154. package/dist/services/incoming/incoming-tx-monitor-service.js +357 -0
  155. package/dist/services/incoming/incoming-tx-monitor-service.js.map +1 -0
  156. package/dist/services/incoming/incoming-tx-queue.d.ts +52 -0
  157. package/dist/services/incoming/incoming-tx-queue.d.ts.map +1 -0
  158. package/dist/services/incoming/incoming-tx-queue.js +109 -0
  159. package/dist/services/incoming/incoming-tx-queue.js.map +1 -0
  160. package/dist/services/incoming/incoming-tx-workers.d.ts +89 -0
  161. package/dist/services/incoming/incoming-tx-workers.d.ts.map +1 -0
  162. package/dist/services/incoming/incoming-tx-workers.js +176 -0
  163. package/dist/services/incoming/incoming-tx-workers.js.map +1 -0
  164. package/dist/services/incoming/index.d.ts +14 -0
  165. package/dist/services/incoming/index.d.ts.map +1 -0
  166. package/dist/services/incoming/index.js +11 -0
  167. package/dist/services/incoming/index.js.map +1 -0
  168. package/dist/services/incoming/safety-rules.d.ts +70 -0
  169. package/dist/services/incoming/safety-rules.d.ts.map +1 -0
  170. package/dist/services/incoming/safety-rules.js +68 -0
  171. package/dist/services/incoming/safety-rules.js.map +1 -0
  172. package/dist/services/incoming/subscription-multiplexer.d.ts +87 -0
  173. package/dist/services/incoming/subscription-multiplexer.d.ts.map +1 -0
  174. package/dist/services/incoming/subscription-multiplexer.js +169 -0
  175. package/dist/services/incoming/subscription-multiplexer.js.map +1 -0
  176. package/dist/services/signing-sdk/approval-channel-router.d.ts +1 -1
  177. package/dist/services/signing-sdk/approval-channel-router.d.ts.map +1 -1
  178. package/dist/services/signing-sdk/approval-channel-router.js +2 -3
  179. package/dist/services/signing-sdk/approval-channel-router.js.map +1 -1
  180. package/dist/services/signing-sdk/channels/wallet-notification-channel.js +1 -1
  181. package/dist/services/signing-sdk/channels/wallet-notification-channel.js.map +1 -1
  182. package/dist/services/wc-session-service.d.ts +0 -2
  183. package/dist/services/wc-session-service.d.ts.map +1 -1
  184. package/dist/services/wc-session-service.js +2 -23
  185. package/dist/services/wc-session-service.js.map +1 -1
  186. package/dist/services/x402/x402-domain-policy.d.ts +6 -1
  187. package/dist/services/x402/x402-domain-policy.d.ts.map +1 -1
  188. package/dist/services/x402/x402-domain-policy.js +6 -2
  189. package/dist/services/x402/x402-domain-policy.js.map +1 -1
  190. package/package.json +4 -4
  191. package/public/admin/assets/index-D06O_cSo.js +1 -0
  192. package/public/admin/index.html +1 -1
  193. package/public/admin/assets/index-BLLOYSZp.js +0 -1
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Integration wiring tests for incoming TX monitoring pipeline.
3
+ *
4
+ * Verifies the 3 bug fixes from Plan 01 (Phase 230) work correctly
5
+ * when components are wired together:
6
+ *
7
+ * BUG-1: BackgroundWorkers instance sharing -- monitor registers 6 workers to the provided instance
8
+ * BUG-2: Polling worker handlers -- invoke subscriber.pollAll() for solana and ethereum chains
9
+ * BUG-3: Gap recovery wiring -- onGapRecovery invokes createGapRecoveryHandler -> subscriber.pollAll()
10
+ *
11
+ * These tests use real IncomingTxMonitorService with mock boundaries (DB, IChainSubscriber)
12
+ * to verify cross-component wiring at the integration level.
13
+ */
14
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
15
+ import { IncomingTxMonitorService } from '../incoming-tx-monitor-service.js';
16
+ // ---------------------------------------------------------------------------
17
+ // Mock generateId for queue flush
18
+ // ---------------------------------------------------------------------------
19
+ let idCounter = 0;
20
+ vi.mock('../../../infrastructure/database/id.js', () => ({
21
+ generateId: () => `uuid-${++idCounter}`,
22
+ }));
23
+ // ---------------------------------------------------------------------------
24
+ // Helpers
25
+ // ---------------------------------------------------------------------------
26
+ function makeConfig(overrides = {}) {
27
+ return {
28
+ enabled: true,
29
+ pollIntervalSec: 30,
30
+ retentionDays: 90,
31
+ dustThresholdUsd: 0.01,
32
+ amountMultiplier: 10,
33
+ cooldownMinutes: 5,
34
+ ...overrides,
35
+ };
36
+ }
37
+ function createMockSqlite() {
38
+ const runFn = vi.fn().mockReturnValue({ changes: 1 });
39
+ const getFn = vi.fn().mockReturnValue(undefined);
40
+ const allFn = vi.fn().mockReturnValue([]);
41
+ const prepareFn = vi.fn().mockReturnValue({
42
+ run: runFn,
43
+ get: getFn,
44
+ all: allFn,
45
+ });
46
+ const txFn = vi.fn((fn) => fn);
47
+ return {
48
+ prepare: prepareFn,
49
+ transaction: txFn,
50
+ exec: vi.fn(),
51
+ _runFn: runFn,
52
+ _getFn: getFn,
53
+ _allFn: allFn,
54
+ _prepareFn: prepareFn,
55
+ };
56
+ }
57
+ function createMockEventBus() {
58
+ return {
59
+ emit: vi.fn().mockReturnValue(true),
60
+ on: vi.fn(),
61
+ removeAllListeners: vi.fn(),
62
+ listenerCount: vi.fn().mockReturnValue(0),
63
+ };
64
+ }
65
+ function createMockWorkers() {
66
+ return {
67
+ register: vi.fn(),
68
+ startAll: vi.fn(),
69
+ stopAll: vi.fn(),
70
+ size: 0,
71
+ isRunning: vi.fn().mockReturnValue(false),
72
+ };
73
+ }
74
+ function createMockSubscriberFactory() {
75
+ return vi.fn().mockReturnValue({
76
+ connect: vi.fn().mockResolvedValue(undefined),
77
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
78
+ subscribe: vi.fn().mockResolvedValue(undefined),
79
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
80
+ pollAll: vi.fn().mockResolvedValue(undefined),
81
+ destroy: vi.fn().mockResolvedValue(undefined),
82
+ });
83
+ }
84
+ /** Create a fresh IncomingTxMonitorService with isolated mocks. */
85
+ function createFreshService(opts = {}) {
86
+ const sqlite = createMockSqlite();
87
+ const eventBus = createMockEventBus();
88
+ const workers = createMockWorkers();
89
+ const subscriberFactory = createMockSubscriberFactory();
90
+ // Return empty wallets from DB query
91
+ sqlite._allFn.mockReturnValue([]);
92
+ const service = new IncomingTxMonitorService({
93
+ sqlite: sqlite,
94
+ db: {},
95
+ workers: workers,
96
+ eventBus: eventBus,
97
+ killSwitchService: null,
98
+ notificationService: null,
99
+ subscriberFactory,
100
+ config: makeConfig(opts.configOverrides),
101
+ });
102
+ return { service, sqlite, eventBus, workers, subscriberFactory };
103
+ }
104
+ // ===========================================================================
105
+ // Section 1: BUG-1 -- BackgroundWorkers Instance Sharing
106
+ // ===========================================================================
107
+ describe('BUG-1: BackgroundWorkers Instance Sharing', () => {
108
+ beforeEach(() => {
109
+ vi.clearAllMocks();
110
+ idCounter = 0;
111
+ });
112
+ it('monitor service registers workers to the provided BackgroundWorkers instance', async () => {
113
+ const { service, workers } = createFreshService();
114
+ await service.start();
115
+ // Assert workers.register was called exactly 6 times
116
+ expect(workers.register).toHaveBeenCalledTimes(6);
117
+ // Assert the exact 6 worker names
118
+ const registeredNames = workers.register.mock.calls.map((call) => call[0]);
119
+ expect(registeredNames).toEqual(expect.arrayContaining([
120
+ 'incoming-tx-flush',
121
+ 'incoming-tx-retention',
122
+ 'incoming-tx-confirm-solana',
123
+ 'incoming-tx-confirm-evm',
124
+ 'incoming-tx-poll-solana',
125
+ 'incoming-tx-poll-evm',
126
+ ]));
127
+ // Verify exactly these 6 (no more, no less)
128
+ expect(registeredNames).toHaveLength(6);
129
+ await service.stop();
130
+ });
131
+ it('all registered worker handlers are callable functions', async () => {
132
+ const { service, workers } = createFreshService();
133
+ await service.start();
134
+ // Extract handler functions from workers.register.mock.calls
135
+ for (const call of workers.register.mock.calls) {
136
+ const config = call[1];
137
+ // Each registered worker should have a handler that is a function
138
+ expect(typeof config.handler).toBe('function');
139
+ // Call each handler and assert it does not throw
140
+ const handler = config.handler;
141
+ await expect(handler()).resolves.not.toThrow();
142
+ }
143
+ await service.stop();
144
+ });
145
+ });
146
+ // ===========================================================================
147
+ // Section 2: BUG-2 -- Polling Worker Handlers
148
+ // ===========================================================================
149
+ describe('BUG-2: Polling Worker Handlers', () => {
150
+ beforeEach(() => {
151
+ vi.clearAllMocks();
152
+ idCounter = 0;
153
+ });
154
+ it('Solana polling worker calls pollAll() on solana subscribers', async () => {
155
+ const sqlite = createMockSqlite();
156
+ const eventBus = createMockEventBus();
157
+ const workers = createMockWorkers();
158
+ const mockPollAll = vi.fn().mockResolvedValue(undefined);
159
+ const subscriberFactory = vi.fn().mockReturnValue({
160
+ connect: vi.fn().mockResolvedValue(undefined),
161
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
162
+ subscribe: vi.fn().mockResolvedValue(undefined),
163
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
164
+ pollAll: mockPollAll,
165
+ destroy: vi.fn().mockResolvedValue(undefined),
166
+ });
167
+ // Return one solana wallet from DB
168
+ sqlite._allFn.mockReturnValueOnce([
169
+ { id: 'w1', chain: 'solana', network: 'mainnet', public_key: 'pk1' },
170
+ ]);
171
+ const service = new IncomingTxMonitorService({
172
+ sqlite: sqlite,
173
+ db: {},
174
+ workers: workers,
175
+ eventBus: eventBus,
176
+ killSwitchService: null,
177
+ notificationService: null,
178
+ subscriberFactory,
179
+ config: makeConfig(),
180
+ });
181
+ await service.start();
182
+ // Extract 'incoming-tx-poll-solana' handler
183
+ const pollSolanaCall = workers.register.mock.calls.find((call) => call[0] === 'incoming-tx-poll-solana');
184
+ expect(pollSolanaCall).toBeDefined();
185
+ const handler = pollSolanaCall[1].handler;
186
+ await handler();
187
+ // Assert subscriber.pollAll() was called
188
+ expect(mockPollAll).toHaveBeenCalledTimes(1);
189
+ await service.stop();
190
+ });
191
+ it('EVM polling worker calls pollAll() on ethereum subscribers', async () => {
192
+ const sqlite = createMockSqlite();
193
+ const eventBus = createMockEventBus();
194
+ const workers = createMockWorkers();
195
+ const mockPollAll = vi.fn().mockResolvedValue(undefined);
196
+ const subscriberFactory = vi.fn().mockReturnValue({
197
+ connect: vi.fn().mockResolvedValue(undefined),
198
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
199
+ subscribe: vi.fn().mockResolvedValue(undefined),
200
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
201
+ pollAll: mockPollAll,
202
+ destroy: vi.fn().mockResolvedValue(undefined),
203
+ });
204
+ // Return one ethereum wallet from DB
205
+ sqlite._allFn.mockReturnValueOnce([
206
+ { id: 'w2', chain: 'ethereum', network: 'mainnet', public_key: 'pk2' },
207
+ ]);
208
+ const service = new IncomingTxMonitorService({
209
+ sqlite: sqlite,
210
+ db: {},
211
+ workers: workers,
212
+ eventBus: eventBus,
213
+ killSwitchService: null,
214
+ notificationService: null,
215
+ subscriberFactory,
216
+ config: makeConfig(),
217
+ });
218
+ await service.start();
219
+ // Extract 'incoming-tx-poll-evm' handler
220
+ const pollEvmCall = workers.register.mock.calls.find((call) => call[0] === 'incoming-tx-poll-evm');
221
+ expect(pollEvmCall).toBeDefined();
222
+ const handler = pollEvmCall[1].handler;
223
+ await handler();
224
+ // Assert subscriber.pollAll() was called
225
+ expect(mockPollAll).toHaveBeenCalledTimes(1);
226
+ await service.stop();
227
+ });
228
+ it('polling worker handles subscriber.pollAll() errors gracefully', async () => {
229
+ const sqlite = createMockSqlite();
230
+ const eventBus = createMockEventBus();
231
+ const workers = createMockWorkers();
232
+ const mockPollAll = vi.fn().mockRejectedValue(new Error('RPC timeout'));
233
+ const subscriberFactory = vi.fn().mockReturnValue({
234
+ connect: vi.fn().mockResolvedValue(undefined),
235
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
236
+ subscribe: vi.fn().mockResolvedValue(undefined),
237
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
238
+ pollAll: mockPollAll,
239
+ destroy: vi.fn().mockResolvedValue(undefined),
240
+ });
241
+ // Return one solana wallet from DB
242
+ sqlite._allFn.mockReturnValueOnce([
243
+ { id: 'w1', chain: 'solana', network: 'mainnet', public_key: 'pk1' },
244
+ ]);
245
+ const service = new IncomingTxMonitorService({
246
+ sqlite: sqlite,
247
+ db: {},
248
+ workers: workers,
249
+ eventBus: eventBus,
250
+ killSwitchService: null,
251
+ notificationService: null,
252
+ subscriberFactory,
253
+ config: makeConfig(),
254
+ });
255
+ await service.start();
256
+ // Extract 'incoming-tx-poll-solana' handler
257
+ const pollSolanaCall = workers.register.mock.calls.find((call) => call[0] === 'incoming-tx-poll-solana');
258
+ const handler = pollSolanaCall[1].handler;
259
+ // Spy on console.warn to verify error logging
260
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
261
+ // Should NOT throw -- error is caught and logged
262
+ await expect(handler()).resolves.not.toThrow();
263
+ // Verify warning was logged
264
+ expect(warnSpy).toHaveBeenCalledWith('Solana polling worker error:', expect.any(Error));
265
+ warnSpy.mockRestore();
266
+ await service.stop();
267
+ });
268
+ });
269
+ // ===========================================================================
270
+ // Section 3: BUG-3 -- Gap Recovery Wiring
271
+ // ===========================================================================
272
+ describe('BUG-3: Gap Recovery Wiring', () => {
273
+ beforeEach(() => {
274
+ vi.clearAllMocks();
275
+ idCounter = 0;
276
+ });
277
+ it('onGapRecovery invokes createGapRecoveryHandler which calls subscriber.pollAll()', async () => {
278
+ const sqlite = createMockSqlite();
279
+ const eventBus = createMockEventBus();
280
+ const workers = createMockWorkers();
281
+ const mockPollAll = vi.fn().mockResolvedValue(undefined);
282
+ const subscriberFactory = vi.fn().mockReturnValue({
283
+ connect: vi.fn().mockResolvedValue(undefined),
284
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
285
+ subscribe: vi.fn().mockResolvedValue(undefined),
286
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
287
+ pollAll: mockPollAll,
288
+ destroy: vi.fn().mockResolvedValue(undefined),
289
+ });
290
+ // Return one solana wallet from DB
291
+ sqlite._allFn.mockReturnValueOnce([
292
+ { id: 'w1', chain: 'solana', network: 'mainnet', public_key: 'pk1' },
293
+ ]);
294
+ const service = new IncomingTxMonitorService({
295
+ sqlite: sqlite,
296
+ db: {},
297
+ workers: workers,
298
+ eventBus: eventBus,
299
+ killSwitchService: null,
300
+ notificationService: null,
301
+ subscriberFactory,
302
+ config: makeConfig(),
303
+ });
304
+ await service.start();
305
+ // Access the multiplexer's onGapRecovery callback via internal deps
306
+ const multiplexer = service.multiplexer;
307
+ const onGapRecovery = multiplexer.deps.onGapRecovery;
308
+ expect(onGapRecovery).toBeDefined();
309
+ expect(typeof onGapRecovery).toBe('function');
310
+ // Call onGapRecovery for solana:mainnet
311
+ await onGapRecovery('solana', 'mainnet', ['w1']);
312
+ // Assert subscriber.pollAll() was called (via createGapRecoveryHandler -> entry.subscriber.pollAll())
313
+ expect(mockPollAll).toHaveBeenCalledTimes(1);
314
+ await service.stop();
315
+ });
316
+ it('onGapRecovery handles missing chain:network gracefully', async () => {
317
+ const sqlite = createMockSqlite();
318
+ const eventBus = createMockEventBus();
319
+ const workers = createMockWorkers();
320
+ const mockPollAll = vi.fn().mockResolvedValue(undefined);
321
+ const subscriberFactory = vi.fn().mockReturnValue({
322
+ connect: vi.fn().mockResolvedValue(undefined),
323
+ waitForDisconnect: vi.fn().mockReturnValue(new Promise(() => { })),
324
+ subscribe: vi.fn().mockResolvedValue(undefined),
325
+ unsubscribe: vi.fn().mockResolvedValue(undefined),
326
+ pollAll: mockPollAll,
327
+ destroy: vi.fn().mockResolvedValue(undefined),
328
+ });
329
+ // Only return a solana wallet (no ethereum)
330
+ sqlite._allFn.mockReturnValueOnce([
331
+ { id: 'w1', chain: 'solana', network: 'mainnet', public_key: 'pk1' },
332
+ ]);
333
+ const service = new IncomingTxMonitorService({
334
+ sqlite: sqlite,
335
+ db: {},
336
+ workers: workers,
337
+ eventBus: eventBus,
338
+ killSwitchService: null,
339
+ notificationService: null,
340
+ subscriberFactory,
341
+ config: makeConfig(),
342
+ });
343
+ await service.start();
344
+ // Access onGapRecovery
345
+ const multiplexer = service.multiplexer;
346
+ const onGapRecovery = multiplexer.deps.onGapRecovery;
347
+ // Call onGapRecovery for 'ethereum:mainnet' which has no subscriber
348
+ // Should NOT throw -- createGapRecoveryHandler gracefully skips missing entries
349
+ await expect(onGapRecovery('ethereum', 'mainnet', ['w1'])).resolves.not.toThrow();
350
+ // solana pollAll should NOT have been called (we requested ethereum)
351
+ expect(mockPollAll).not.toHaveBeenCalled();
352
+ await service.stop();
353
+ });
354
+ });
355
+ //# sourceMappingURL=integration-wiring.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-wiring.test.js","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/integration-wiring.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tests for incoming transaction safety rules.
3
+ *
4
+ * Covers all 3 rule implementations with edge cases:
5
+ * - DustAttackRule: below/above threshold, null usdPrice
6
+ * - UnknownTokenRule: unregistered token, registered token, native transfer
7
+ * - LargeAmountRule: above/below multiplier, null avg, null price
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=safety-rules.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety-rules.test.d.ts","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/safety-rules.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Tests for incoming transaction safety rules.
3
+ *
4
+ * Covers all 3 rule implementations with edge cases:
5
+ * - DustAttackRule: below/above threshold, null usdPrice
6
+ * - UnknownTokenRule: unregistered token, registered token, native transfer
7
+ * - LargeAmountRule: above/below multiplier, null avg, null price
8
+ */
9
+ import { describe, it, expect } from 'vitest';
10
+ import { DustAttackRule, UnknownTokenRule, LargeAmountRule, } from '../safety-rules.js';
11
+ // ---------------------------------------------------------------------------
12
+ // Helpers
13
+ // ---------------------------------------------------------------------------
14
+ function makeTx(overrides = {}) {
15
+ return {
16
+ id: 'tx-001',
17
+ txHash: '0xabc',
18
+ walletId: 'wallet-001',
19
+ fromAddress: '0xsender',
20
+ amount: '1000000000', // 1 SOL in lamports (9 decimals)
21
+ tokenAddress: null,
22
+ chain: 'solana',
23
+ network: 'mainnet',
24
+ status: 'DETECTED',
25
+ blockNumber: 100,
26
+ detectedAt: 1700000000,
27
+ confirmedAt: null,
28
+ isSuspicious: false,
29
+ ...overrides,
30
+ };
31
+ }
32
+ function makeContext(overrides = {}) {
33
+ return {
34
+ dustThresholdUsd: 0.01,
35
+ amountMultiplier: 10,
36
+ isRegisteredToken: true,
37
+ usdPrice: 100, // $100 per whole token
38
+ avgIncomingUsd: 500, // average incoming is $500
39
+ decimals: 9,
40
+ ...overrides,
41
+ };
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // DustAttackRule
45
+ // ---------------------------------------------------------------------------
46
+ describe('DustAttackRule', () => {
47
+ const rule = new DustAttackRule();
48
+ it('has name "dust"', () => {
49
+ expect(rule.name).toBe('dust');
50
+ });
51
+ it('flags transaction below dust threshold', () => {
52
+ // amount=10 lamports, price=$100, decimals=9 -> USD = 10 * 100 / 1e9 = 0.000001
53
+ const tx = makeTx({ amount: '10' });
54
+ const ctx = makeContext({ dustThresholdUsd: 0.01 });
55
+ expect(rule.check(tx, ctx)).toBe(true);
56
+ });
57
+ it('does not flag transaction above dust threshold', () => {
58
+ // amount=1e9 (1 SOL), price=$100 -> USD = 100
59
+ const tx = makeTx({ amount: '1000000000' });
60
+ const ctx = makeContext({ dustThresholdUsd: 0.01 });
61
+ expect(rule.check(tx, ctx)).toBe(false);
62
+ });
63
+ it('returns false when usdPrice is null (safe default)', () => {
64
+ const tx = makeTx({ amount: '10' });
65
+ const ctx = makeContext({ usdPrice: null });
66
+ expect(rule.check(tx, ctx)).toBe(false);
67
+ });
68
+ it('flags when USD value exactly equals threshold', () => {
69
+ // amount * price / 10^decimals = 0.01
70
+ // amount = 0.01 * 1e9 / 100 = 100000
71
+ const tx = makeTx({ amount: '100000' });
72
+ const ctx = makeContext({ dustThresholdUsd: 0.01, usdPrice: 100, decimals: 9 });
73
+ // 100000 * 100 / 1e9 = 0.01 -- NOT less than threshold
74
+ expect(rule.check(tx, ctx)).toBe(false);
75
+ });
76
+ it('handles EVM decimals (18)', () => {
77
+ // amount=100 wei, price=$2000, decimals=18 -> USD = 100 * 2000 / 1e18 = 0.0000000000000002
78
+ const tx = makeTx({ amount: '100', chain: 'ethereum' });
79
+ const ctx = makeContext({ usdPrice: 2000, decimals: 18, dustThresholdUsd: 0.01 });
80
+ expect(rule.check(tx, ctx)).toBe(true);
81
+ });
82
+ });
83
+ // ---------------------------------------------------------------------------
84
+ // UnknownTokenRule
85
+ // ---------------------------------------------------------------------------
86
+ describe('UnknownTokenRule', () => {
87
+ const rule = new UnknownTokenRule();
88
+ it('has name "unknownToken"', () => {
89
+ expect(rule.name).toBe('unknownToken');
90
+ });
91
+ it('flags token transfer with unregistered token', () => {
92
+ const tx = makeTx({ tokenAddress: '0xunknown' });
93
+ const ctx = makeContext({ isRegisteredToken: false });
94
+ expect(rule.check(tx, ctx)).toBe(true);
95
+ });
96
+ it('does not flag token transfer with registered token', () => {
97
+ const tx = makeTx({ tokenAddress: '0xknown' });
98
+ const ctx = makeContext({ isRegisteredToken: true });
99
+ expect(rule.check(tx, ctx)).toBe(false);
100
+ });
101
+ it('does not flag native transfer (tokenAddress = null)', () => {
102
+ const tx = makeTx({ tokenAddress: null });
103
+ const ctx = makeContext({ isRegisteredToken: false });
104
+ expect(rule.check(tx, ctx)).toBe(false);
105
+ });
106
+ });
107
+ // ---------------------------------------------------------------------------
108
+ // LargeAmountRule
109
+ // ---------------------------------------------------------------------------
110
+ describe('LargeAmountRule', () => {
111
+ const rule = new LargeAmountRule();
112
+ it('has name "largeAmount"', () => {
113
+ expect(rule.name).toBe('largeAmount');
114
+ });
115
+ it('flags transaction above multiplier * average', () => {
116
+ // amount=100e9 lamports (100 SOL), price=$100, decimals=9 -> USD = 10000
117
+ // avgIncoming=$500, multiplier=10 -> threshold = $5000
118
+ // 10000 > 5000 -> flagged
119
+ const tx = makeTx({ amount: '100000000000' });
120
+ const ctx = makeContext({
121
+ usdPrice: 100,
122
+ avgIncomingUsd: 500,
123
+ amountMultiplier: 10,
124
+ decimals: 9,
125
+ });
126
+ expect(rule.check(tx, ctx)).toBe(true);
127
+ });
128
+ it('does not flag transaction below multiplier * average', () => {
129
+ // amount=1e9 (1 SOL), price=$100 -> USD = 100
130
+ // avgIncoming=$500, multiplier=10 -> threshold = $5000
131
+ // 100 < 5000 -> not flagged
132
+ const tx = makeTx({ amount: '1000000000' });
133
+ const ctx = makeContext({
134
+ usdPrice: 100,
135
+ avgIncomingUsd: 500,
136
+ amountMultiplier: 10,
137
+ decimals: 9,
138
+ });
139
+ expect(rule.check(tx, ctx)).toBe(false);
140
+ });
141
+ it('returns false when avgIncomingUsd is null (safe default)', () => {
142
+ const tx = makeTx({ amount: '100000000000' });
143
+ const ctx = makeContext({ avgIncomingUsd: null });
144
+ expect(rule.check(tx, ctx)).toBe(false);
145
+ });
146
+ it('returns false when usdPrice is null (safe default)', () => {
147
+ const tx = makeTx({ amount: '100000000000' });
148
+ const ctx = makeContext({ usdPrice: null });
149
+ expect(rule.check(tx, ctx)).toBe(false);
150
+ });
151
+ it('does not flag when exactly at multiplier * average', () => {
152
+ // amount=50e9 (50 SOL), price=$100 -> USD = 5000
153
+ // avgIncoming=$500, multiplier=10 -> threshold = $5000
154
+ // 5000 > 5000 is false -> not flagged
155
+ const tx = makeTx({ amount: '50000000000' });
156
+ const ctx = makeContext({
157
+ usdPrice: 100,
158
+ avgIncomingUsd: 500,
159
+ amountMultiplier: 10,
160
+ decimals: 9,
161
+ });
162
+ expect(rule.check(tx, ctx)).toBe(false);
163
+ });
164
+ });
165
+ //# sourceMappingURL=safety-rules.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety-rules.test.js","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/safety-rules.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=subscription-multiplexer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-multiplexer.test.d.ts","sourceRoot":"","sources":["../../../../src/services/incoming/__tests__/subscription-multiplexer.test.ts"],"names":[],"mappings":""}