hive-stream 3.0.2 → 3.0.3

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 (197) hide show
  1. package/DOCUMENTATION.md +50 -2
  2. package/README.md +44 -3
  3. package/dist/adapters/base.adapter.d.ts +5 -0
  4. package/dist/adapters/base.adapter.js +9 -0
  5. package/dist/adapters/base.adapter.js.map +1 -1
  6. package/dist/adapters/mongodb.adapter.d.ts +6 -6
  7. package/dist/adapters/mongodb.adapter.js +36 -21
  8. package/dist/adapters/mongodb.adapter.js.map +1 -1
  9. package/dist/adapters/postgresql.adapter.d.ts +7 -0
  10. package/dist/adapters/postgresql.adapter.js +46 -19
  11. package/dist/adapters/postgresql.adapter.js.map +1 -1
  12. package/dist/adapters/sqlite.adapter.d.ts +4 -0
  13. package/dist/adapters/sqlite.adapter.js +10 -0
  14. package/dist/adapters/sqlite.adapter.js.map +1 -1
  15. package/dist/api.d.ts +13 -3
  16. package/dist/api.js +96 -62
  17. package/dist/api.js.map +1 -1
  18. package/dist/config.d.ts +7 -1
  19. package/dist/config.js +7 -1
  20. package/dist/config.js.map +1 -1
  21. package/dist/contracts/auctionhouse.contract.d.ts +4 -0
  22. package/dist/contracts/auctionhouse.contract.js +234 -0
  23. package/dist/contracts/auctionhouse.contract.js.map +1 -0
  24. package/dist/contracts/booking.contract.d.ts +4 -0
  25. package/dist/contracts/booking.contract.js +225 -0
  26. package/dist/contracts/booking.contract.js.map +1 -0
  27. package/dist/contracts/bountyboard.contract.d.ts +4 -0
  28. package/dist/contracts/bountyboard.contract.js +233 -0
  29. package/dist/contracts/bountyboard.contract.js.map +1 -0
  30. package/dist/contracts/bundlemarketplace.contract.d.ts +4 -0
  31. package/dist/contracts/bundlemarketplace.contract.js +195 -0
  32. package/dist/contracts/bundlemarketplace.contract.js.map +1 -0
  33. package/dist/contracts/charitymatch.contract.d.ts +4 -0
  34. package/dist/contracts/charitymatch.contract.js +172 -0
  35. package/dist/contracts/charitymatch.contract.js.map +1 -0
  36. package/dist/contracts/coinflip.contract.js +7 -1
  37. package/dist/contracts/coinflip.contract.js.map +1 -1
  38. package/dist/contracts/crowdfund.contract.d.ts +4 -0
  39. package/dist/contracts/crowdfund.contract.js +290 -0
  40. package/dist/contracts/crowdfund.contract.js.map +1 -0
  41. package/dist/contracts/dcabot.contract.d.ts +4 -0
  42. package/dist/contracts/dcabot.contract.js +217 -0
  43. package/dist/contracts/dcabot.contract.js.map +1 -0
  44. package/dist/contracts/dice.contract.js +7 -1
  45. package/dist/contracts/dice.contract.js.map +1 -1
  46. package/dist/contracts/domainregistry.contract.d.ts +4 -0
  47. package/dist/contracts/domainregistry.contract.js +232 -0
  48. package/dist/contracts/domainregistry.contract.js.map +1 -0
  49. package/dist/contracts/exchange.contract.js +209 -168
  50. package/dist/contracts/exchange.contract.js.map +1 -1
  51. package/dist/contracts/fanclub.contract.d.ts +4 -0
  52. package/dist/contracts/fanclub.contract.js +193 -0
  53. package/dist/contracts/fanclub.contract.js.map +1 -0
  54. package/dist/contracts/giftcard.contract.d.ts +4 -0
  55. package/dist/contracts/giftcard.contract.js +158 -0
  56. package/dist/contracts/giftcard.contract.js.map +1 -0
  57. package/dist/contracts/grantrounds.contract.d.ts +4 -0
  58. package/dist/contracts/grantrounds.contract.js +265 -0
  59. package/dist/contracts/grantrounds.contract.js.map +1 -0
  60. package/dist/contracts/groupbuy.contract.d.ts +4 -0
  61. package/dist/contracts/groupbuy.contract.js +198 -0
  62. package/dist/contracts/groupbuy.contract.js.map +1 -0
  63. package/dist/contracts/helpers.d.ts +64 -0
  64. package/dist/contracts/helpers.js +159 -0
  65. package/dist/contracts/helpers.js.map +1 -0
  66. package/dist/contracts/insurancepool.contract.d.ts +4 -0
  67. package/dist/contracts/insurancepool.contract.js +281 -0
  68. package/dist/contracts/insurancepool.contract.js.map +1 -0
  69. package/dist/contracts/invoice.contract.d.ts +4 -0
  70. package/dist/contracts/invoice.contract.js +193 -0
  71. package/dist/contracts/invoice.contract.js.map +1 -0
  72. package/dist/contracts/launchpad.contract.d.ts +4 -0
  73. package/dist/contracts/launchpad.contract.js +225 -0
  74. package/dist/contracts/launchpad.contract.js.map +1 -0
  75. package/dist/contracts/lotto.contract.js +53 -37
  76. package/dist/contracts/lotto.contract.js.map +1 -1
  77. package/dist/contracts/multisigtreasury.contract.d.ts +4 -0
  78. package/dist/contracts/multisigtreasury.contract.js +245 -0
  79. package/dist/contracts/multisigtreasury.contract.js.map +1 -0
  80. package/dist/contracts/nft.contract.d.ts +1 -0
  81. package/dist/contracts/nft.contract.js +236 -192
  82. package/dist/contracts/nft.contract.js.map +1 -1
  83. package/dist/contracts/oraclebounty.contract.d.ts +4 -0
  84. package/dist/contracts/oraclebounty.contract.js +250 -0
  85. package/dist/contracts/oraclebounty.contract.js.map +1 -0
  86. package/dist/contracts/payroll.contract.d.ts +4 -0
  87. package/dist/contracts/payroll.contract.js +232 -0
  88. package/dist/contracts/payroll.contract.js.map +1 -0
  89. package/dist/contracts/paywall.contract.d.ts +4 -0
  90. package/dist/contracts/paywall.contract.js +185 -0
  91. package/dist/contracts/paywall.contract.js.map +1 -0
  92. package/dist/contracts/poll.contract.js +2 -0
  93. package/dist/contracts/poll.contract.js.map +1 -1
  94. package/dist/contracts/predictionmarket.contract.d.ts +4 -0
  95. package/dist/contracts/predictionmarket.contract.js +213 -0
  96. package/dist/contracts/predictionmarket.contract.js.map +1 -0
  97. package/dist/contracts/proposaltimelock.contract.d.ts +4 -0
  98. package/dist/contracts/proposaltimelock.contract.js +250 -0
  99. package/dist/contracts/proposaltimelock.contract.js.map +1 -0
  100. package/dist/contracts/questpass.contract.d.ts +4 -0
  101. package/dist/contracts/questpass.contract.js +214 -0
  102. package/dist/contracts/questpass.contract.js.map +1 -0
  103. package/dist/contracts/referral.contract.d.ts +4 -0
  104. package/dist/contracts/referral.contract.js +238 -0
  105. package/dist/contracts/referral.contract.js.map +1 -0
  106. package/dist/contracts/rental.contract.d.ts +4 -0
  107. package/dist/contracts/rental.contract.js +221 -0
  108. package/dist/contracts/rental.contract.js.map +1 -0
  109. package/dist/contracts/revenuesplit.contract.d.ts +4 -0
  110. package/dist/contracts/revenuesplit.contract.js +211 -0
  111. package/dist/contracts/revenuesplit.contract.js.map +1 -0
  112. package/dist/contracts/rps.contract.js +17 -1
  113. package/dist/contracts/rps.contract.js.map +1 -1
  114. package/dist/contracts/savings.contract.d.ts +4 -0
  115. package/dist/contracts/savings.contract.js +208 -0
  116. package/dist/contracts/savings.contract.js.map +1 -0
  117. package/dist/contracts/subscription.contract.d.ts +4 -0
  118. package/dist/contracts/subscription.contract.js +241 -0
  119. package/dist/contracts/subscription.contract.js.map +1 -0
  120. package/dist/contracts/sweepstakes.contract.d.ts +4 -0
  121. package/dist/contracts/sweepstakes.contract.js +209 -0
  122. package/dist/contracts/sweepstakes.contract.js.map +1 -0
  123. package/dist/contracts/ticketing.contract.d.ts +4 -0
  124. package/dist/contracts/ticketing.contract.js +185 -0
  125. package/dist/contracts/ticketing.contract.js.map +1 -0
  126. package/dist/contracts/tipjar.contract.js +2 -0
  127. package/dist/contracts/tipjar.contract.js.map +1 -1
  128. package/dist/contracts/token.contract.js +135 -125
  129. package/dist/contracts/token.contract.js.map +1 -1
  130. package/dist/index.d.ts +39 -0
  131. package/dist/index.js +71 -1
  132. package/dist/index.js.map +1 -1
  133. package/dist/metadata.d.ts +7 -0
  134. package/dist/metadata.js +64 -1
  135. package/dist/metadata.js.map +1 -1
  136. package/dist/providers/block-provider.d.ts +22 -0
  137. package/dist/providers/block-provider.js +3 -0
  138. package/dist/providers/block-provider.js.map +1 -0
  139. package/dist/providers/haf-client.d.ts +30 -0
  140. package/dist/providers/haf-client.js +119 -0
  141. package/dist/providers/haf-client.js.map +1 -0
  142. package/dist/providers/haf-provider.d.ts +49 -0
  143. package/dist/providers/haf-provider.js +256 -0
  144. package/dist/providers/haf-provider.js.map +1 -0
  145. package/dist/providers/hive-provider.d.ts +13 -0
  146. package/dist/providers/hive-provider.js +25 -0
  147. package/dist/providers/hive-provider.js.map +1 -0
  148. package/dist/providers/index.d.ts +4 -0
  149. package/dist/providers/index.js +21 -0
  150. package/dist/providers/index.js.map +1 -0
  151. package/dist/streamer.d.ts +21 -1
  152. package/dist/streamer.js +187 -62
  153. package/dist/streamer.js.map +1 -1
  154. package/dist/utils.js +11 -2
  155. package/dist/utils.js.map +1 -1
  156. package/package.json +16 -1
  157. package/.claude/settings.local.json +0 -12
  158. package/.env.example +0 -3
  159. package/.travis.yml +0 -11
  160. package/AGENTS.md +0 -35
  161. package/CLAUDE.md +0 -75
  162. package/ecosystem.config.js +0 -17
  163. package/examples/contracts/README.md +0 -8
  164. package/examples/contracts/exchange.ts +0 -38
  165. package/examples/contracts/poll.ts +0 -21
  166. package/examples/contracts/rps.ts +0 -19
  167. package/examples/contracts/tipjar.ts +0 -19
  168. package/jest.config.js +0 -9
  169. package/test-contract-block.md +0 -19
  170. package/tests/actions.spec.ts +0 -252
  171. package/tests/adapters/actions-persistence.spec.ts +0 -144
  172. package/tests/adapters/postgresql.adapter.spec.ts +0 -127
  173. package/tests/adapters/sqlite.adapter.spec.ts +0 -181
  174. package/tests/config-input.spec.ts +0 -90
  175. package/tests/contracts/coinflip.contract.spec.ts +0 -94
  176. package/tests/contracts/dice.contract.spec.ts +0 -87
  177. package/tests/contracts/entrants.json +0 -729
  178. package/tests/contracts/exchange.contract.spec.ts +0 -84
  179. package/tests/contracts/lotto.contract.spec.ts +0 -59
  180. package/tests/contracts/nft.contract.spec.ts +0 -948
  181. package/tests/contracts/token.contract.spec.ts +0 -90
  182. package/tests/exchanges/coingecko.exchange.spec.ts +0 -169
  183. package/tests/exchanges/exchange.base.spec.ts +0 -246
  184. package/tests/helpers/mock-adapter.ts +0 -214
  185. package/tests/helpers/mock-fetch.ts +0 -165
  186. package/tests/hive-chain-features.spec.ts +0 -319
  187. package/tests/hive-rates.spec.ts +0 -443
  188. package/tests/integration/hive-rates.integration.spec.ts +0 -35
  189. package/tests/metadata.spec.ts +0 -63
  190. package/tests/setup.ts +0 -30
  191. package/tests/streamer-actions.spec.ts +0 -274
  192. package/tests/streamer.spec.ts +0 -342
  193. package/tests/types/rates.spec.ts +0 -216
  194. package/tests/utils.spec.ts +0 -113
  195. package/tsconfig.build.json +0 -4
  196. package/tslint.json +0 -21
  197. package/wallaby.js +0 -26
@@ -1,274 +0,0 @@
1
- import { TimeAction } from '../src/actions';
2
- import { Streamer } from '../src/streamer';
3
- import { action, defineContract } from '../src/contracts/contract';
4
-
5
- describe('Streamer Time-based Actions', () => {
6
- let streamer: Streamer;
7
- let mockAdapter: any;
8
- let mockContract: any;
9
- let testHandler: jest.Mock;
10
- let asyncTestHandler: jest.Mock;
11
-
12
- beforeEach(async () => {
13
- mockAdapter = {
14
- create: jest.fn().mockResolvedValue(true),
15
- destroy: jest.fn().mockResolvedValue(true),
16
- loadActions: jest.fn().mockResolvedValue([]),
17
- loadState: jest.fn().mockResolvedValue({ lastBlockNumber: 0, actions: [] }),
18
- saveState: jest.fn().mockResolvedValue(true),
19
- processBlock: jest.fn().mockResolvedValue(true),
20
- processOperation: jest.fn().mockResolvedValue(true),
21
- processTransfer: jest.fn().mockResolvedValue(true),
22
- processCustomJson: jest.fn().mockResolvedValue(true),
23
- find: jest.fn().mockResolvedValue([]),
24
- findOne: jest.fn().mockResolvedValue(null),
25
- insert: jest.fn().mockResolvedValue(true),
26
- replace: jest.fn().mockResolvedValue(true)
27
- };
28
-
29
- testHandler = jest.fn();
30
- asyncTestHandler = jest.fn().mockResolvedValue(true);
31
-
32
- mockContract = defineContract({
33
- name: 'testcontract',
34
- hooks: {
35
- create: jest.fn(),
36
- destroy: jest.fn()
37
- },
38
- actions: {
39
- testMethod: action(testHandler, { trigger: 'time' }),
40
- asyncTestMethod: action(asyncTestHandler, { trigger: 'time' })
41
- }
42
- });
43
-
44
- streamer = new Streamer({
45
- JSON_ID: 'testing',
46
- DEBUG_MODE: false
47
- });
48
-
49
- await streamer.registerAdapter(mockAdapter);
50
- await streamer.registerContract(mockContract);
51
- });
52
-
53
- afterEach(async () => {
54
- await streamer.stop();
55
- });
56
-
57
- describe('Action Registration', () => {
58
- test('Should register a new action successfully', async () => {
59
- const action = new TimeAction('1m', 'test-action', 'testcontract', 'testMethod');
60
-
61
- await streamer.registerAction(action);
62
-
63
- const actions = streamer.getActions();
64
- expect(actions).toHaveLength(1);
65
- expect(actions[0].id).toBe('test-action');
66
- expect(mockAdapter.saveState).toHaveBeenCalled();
67
- });
68
-
69
- test('Should not register duplicate action IDs', async () => {
70
- const action1 = new TimeAction('1m', 'test-action', 'testcontract', 'testMethod');
71
- const action2 = new TimeAction('5m', 'test-action', 'testcontract', 'testMethod');
72
-
73
- await streamer.registerAction(action1);
74
- await streamer.registerAction(action2);
75
-
76
- const actions = streamer.getActions();
77
- expect(actions).toHaveLength(1);
78
- expect(actions[0].timeValue).toBe('1m'); // First one should remain
79
- });
80
-
81
- test('Should throw error when registering action for non-existent contract', async () => {
82
- const action = new TimeAction('1m', 'test-action', 'nonexistent', 'testMethod');
83
-
84
- await expect(streamer.registerAction(action)).rejects.toThrow(
85
- 'Contract \'nonexistent\' not found for action \'test-action\''
86
- );
87
- });
88
-
89
- test('Should throw error when registering action for non-existent action', async () => {
90
- const action = new TimeAction('1m', 'test-action', 'testcontract', 'nonexistentMethod');
91
-
92
- await expect(streamer.registerAction(action)).rejects.toThrow(
93
- 'Action \'nonexistentMethod\' not found in contract \'testcontract\' for action \'test-action\''
94
- );
95
- });
96
- });
97
-
98
- describe('Action Management', () => {
99
- beforeEach(async () => {
100
- const action1 = new TimeAction('1m', 'action1', 'testcontract', 'testMethod');
101
- const action2 = new TimeAction('5m', 'action2', 'testcontract', 'testMethod');
102
- await streamer.registerAction(action1);
103
- await streamer.registerAction(action2);
104
- });
105
-
106
- test('Should remove action by ID', async () => {
107
- const result = await streamer.removeAction('action1');
108
-
109
- expect(result).toBe(true);
110
- expect(streamer.getActions()).toHaveLength(1);
111
- expect(streamer.getAction('action1')).toBeUndefined();
112
- expect(mockAdapter.saveState).toHaveBeenCalled();
113
- });
114
-
115
- test('Should return false when removing non-existent action', async () => {
116
- const result = await streamer.removeAction('nonexistent');
117
-
118
- expect(result).toBe(false);
119
- expect(streamer.getActions()).toHaveLength(2);
120
- });
121
-
122
- test('Should get action by ID', () => {
123
- const action = streamer.getAction('action1');
124
-
125
- expect(action).toBeDefined();
126
- expect(action?.id).toBe('action1');
127
- });
128
-
129
- test('Should return undefined for non-existent action', () => {
130
- const action = streamer.getAction('nonexistent');
131
-
132
- expect(action).toBeUndefined();
133
- });
134
-
135
- test('Should enable and disable actions', async () => {
136
- const action = streamer.getAction('action1');
137
- expect(action?.enabled).toBe(true);
138
-
139
- const result1 = await streamer.setActionEnabled('action1', false);
140
- expect(result1).toBe(true);
141
- expect(action?.enabled).toBe(false);
142
-
143
- const result2 = await streamer.setActionEnabled('action1', true);
144
- expect(result2).toBe(true);
145
- expect(action?.enabled).toBe(true);
146
- });
147
-
148
- test('Should reset action date', async () => {
149
- const action = streamer.getAction('action1');
150
- const originalDate = action?.date;
151
-
152
- // Wait a bit to ensure time difference
153
- await new Promise(resolve => setTimeout(resolve, 10));
154
-
155
- const result = await streamer.resetAction('action1');
156
-
157
- expect(result).toBe(true);
158
- expect(action?.date.getTime()).toBeGreaterThan(originalDate?.getTime() || 0);
159
- expect(mockAdapter.saveState).toHaveBeenCalled();
160
- });
161
- });
162
-
163
- describe('Action Execution', () => {
164
- let testAction: TimeAction;
165
-
166
- beforeEach(async () => {
167
- testAction = new TimeAction('1m', 'test-action', 'testcontract', 'testMethod', { testData: 'value' });
168
- await streamer.registerAction(testAction);
169
-
170
- // Mock the blockchain time to be in the future to trigger execution
171
- streamer['latestBlockchainTime'] = new Date(Date.now() + 120000); // 2 minutes in future
172
- });
173
-
174
- test('Should execute action when time threshold is met', async () => {
175
- // Set action date to past to trigger execution
176
- testAction.date = new Date(Date.now() - 120000); // 2 minutes ago
177
-
178
- await streamer['processActions']();
179
-
180
- expect(testHandler).toHaveBeenCalledWith({ testData: 'value' }, expect.any(Object));
181
- expect(testAction.executionCount).toBe(1);
182
- expect(testAction.lastExecution).toBeInstanceOf(Date);
183
- });
184
-
185
- test('Should not execute action when time threshold is not met', async () => {
186
- // Reset the action date to be very recent to ensure it doesn't execute
187
- testAction.date = new Date(Date.now() - 10000); // Only 10 seconds ago (less than 1 minute)
188
-
189
- // Also ensure blockchain time is current, not in the future
190
- streamer['latestBlockchainTime'] = new Date();
191
-
192
- await streamer['processActions']();
193
-
194
- expect(testHandler).not.toHaveBeenCalled();
195
- expect(testAction.executionCount).toBe(0);
196
- });
197
-
198
- test('Should not execute disabled actions', async () => {
199
- testAction.date = new Date(Date.now() - 120000); // 2 minutes ago
200
- testAction.disable();
201
-
202
- await streamer['processActions']();
203
-
204
- expect(testHandler).not.toHaveBeenCalled();
205
- });
206
-
207
- test('Should not execute actions that have reached max executions', async () => {
208
- testAction.date = new Date(Date.now() - 120000); // 2 minutes ago
209
- testAction.maxExecutions = 1;
210
- testAction.executionCount = 1;
211
-
212
- await streamer['processActions']();
213
-
214
- expect(testHandler).not.toHaveBeenCalled();
215
- });
216
-
217
- test('Should handle contract method errors gracefully', async () => {
218
- testHandler.mockImplementation(() => {
219
- throw new Error('Contract method error');
220
- });
221
-
222
- testAction.date = new Date(Date.now() - 120000); // 2 minutes ago
223
-
224
- // Should not throw, but log error
225
- await expect(streamer['processActions']()).resolves.toBeUndefined();
226
-
227
- expect(testHandler).toHaveBeenCalled();
228
- // Action should not increment execution count on error
229
- expect(testAction.executionCount).toBe(0);
230
- });
231
-
232
- test('Should clean up completed actions', async () => {
233
- testAction.maxExecutions = 1;
234
- testAction.date = new Date(Date.now() - 120000); // 2 minutes ago
235
-
236
- await streamer['processActions']();
237
-
238
- expect(testHandler).toHaveBeenCalled();
239
- expect(streamer.getActions()).toHaveLength(0); // Action should be removed
240
- });
241
- });
242
-
243
- describe('Action Frequencies', () => {
244
- const testCases = [
245
- { timeValue: '3s', expectedSeconds: 3 },
246
- { timeValue: '30s', expectedSeconds: 30 },
247
- { timeValue: '1m', expectedSeconds: 60 },
248
- { timeValue: 'minute', expectedSeconds: 60 },
249
- { timeValue: '15m', expectedSeconds: 900 },
250
- { timeValue: '1h', expectedSeconds: 3600 },
251
- { timeValue: 'hourly', expectedSeconds: 3600 },
252
- { timeValue: '24h', expectedSeconds: 86400 },
253
- { timeValue: 'daily', expectedSeconds: 86400 },
254
- { timeValue: 'week', expectedSeconds: 604800 }
255
- ];
256
-
257
- testCases.forEach(({ timeValue, expectedSeconds }) => {
258
- test(`Should execute ${timeValue} action after ${expectedSeconds} seconds`, async () => {
259
- const action = new TimeAction(timeValue, `test-${timeValue}`, 'testcontract', 'testMethod');
260
- action.date = new Date(Date.now() - (expectedSeconds * 1000 + 1000)); // Past the threshold
261
-
262
- await streamer.registerAction(action);
263
-
264
- // Mock blockchain time
265
- streamer['latestBlockchainTime'] = new Date();
266
-
267
- await streamer['processActions']();
268
-
269
- expect(testHandler).toHaveBeenCalled();
270
- expect(action.executionCount).toBe(1);
271
- });
272
- });
273
- });
274
- });
@@ -1,342 +0,0 @@
1
- import { TimeAction } from '../src/actions';
2
- import { Streamer } from '../src/streamer';
3
- import { action as contractAction, defineContract } from '../src/contracts/contract';
4
- import { createMockAdapter } from './helpers/mock-adapter';
5
-
6
- describe('Streamer', () => {
7
- let sut: Streamer;
8
-
9
- beforeEach(async () => {
10
- sut = new Streamer({
11
- JSON_ID: 'testing'
12
- });
13
-
14
- await sut.registerAdapter(createMockAdapter());
15
- });
16
-
17
- afterEach(async () => {
18
- await sut.stop();
19
- });
20
-
21
- describe('Adapters', () => {
22
- test('Registers adapter and calls the create lifecycle method', async () => {
23
- const adapter = {
24
- create: jest.fn().mockResolvedValue(true),
25
- destroy: jest.fn(),
26
- loadActions: jest.fn().mockResolvedValue([]),
27
- loadState: jest.fn().mockResolvedValue(null),
28
- saveState: jest.fn().mockResolvedValue(true),
29
- processBlock: jest.fn(),
30
- processOperation: jest.fn(),
31
- processTransfer: jest.fn(),
32
- processCustomJson: jest.fn(),
33
- find: jest.fn(),
34
- findOne: jest.fn(),
35
- insert: jest.fn(),
36
- replace: jest.fn(),
37
- addEvent: jest.fn(),
38
- client: null,
39
- db: null
40
- } as any;
41
-
42
- await sut.registerAdapter(adapter);
43
-
44
- expect(adapter.create).toHaveBeenCalled();
45
- });
46
- });
47
-
48
- describe('Actions', () => {
49
- test('Registers a new action', async () => {
50
- const mockContract = defineContract({
51
- name: 'testcontract',
52
- actions: {
53
- testmethod: contractAction(jest.fn(), { trigger: 'time' })
54
- }
55
- });
56
-
57
- await sut.registerContract(mockContract);
58
-
59
- const adapter = {
60
- create: jest.fn().mockResolvedValue(true),
61
- destroy: jest.fn(),
62
- loadActions: jest.fn().mockResolvedValue([]),
63
- loadState: jest.fn().mockResolvedValue(null),
64
- saveState: jest.fn().mockResolvedValue(true),
65
- processBlock: jest.fn(),
66
- processOperation: jest.fn(),
67
- processTransfer: jest.fn(),
68
- processCustomJson: jest.fn(),
69
- find: jest.fn(),
70
- findOne: jest.fn(),
71
- insert: jest.fn(),
72
- replace: jest.fn(),
73
- client: null,
74
- db: null
75
- } as any;
76
-
77
- await sut.registerAdapter(adapter);
78
-
79
- const action = new TimeAction('1m', 'testoneminute', 'testcontract', 'testmethod');
80
-
81
- await sut.registerAction(action);
82
-
83
- const foundAction = sut['actions'].find(a => a.id === 'testoneminute');
84
-
85
- expect(foundAction).not.toBeUndefined();
86
- });
87
-
88
- test('Does not allow duplicate actions of the same id', async () => {
89
- const mockContract = defineContract({
90
- name: 'testcontract',
91
- actions: {
92
- testmethod: contractAction(jest.fn(), { trigger: 'time' })
93
- }
94
- });
95
-
96
- await sut.registerContract(mockContract);
97
-
98
- const adapter = {
99
- create: jest.fn().mockResolvedValue(true),
100
- destroy: jest.fn(),
101
- loadActions: jest.fn().mockResolvedValue([]),
102
- loadState: jest.fn().mockResolvedValue(null),
103
- saveState: jest.fn().mockResolvedValue(true),
104
- processBlock: jest.fn(),
105
- processOperation: jest.fn(),
106
- processTransfer: jest.fn(),
107
- processCustomJson: jest.fn(),
108
- find: jest.fn(),
109
- findOne: jest.fn(),
110
- insert: jest.fn(),
111
- replace: jest.fn(),
112
- client: null,
113
- db: null
114
- } as any;
115
-
116
- await sut.registerAdapter(adapter);
117
-
118
- const action = new TimeAction('1m', 'testoneminute', 'testcontract', 'testmethod');
119
- const action2 = new TimeAction('1m', 'testoneminute', 'testcontract', 'testmethod');
120
-
121
- await sut.registerAction(action);
122
- await sut.registerAction(action2);
123
-
124
- expect(sut['actions'].length).toStrictEqual(1);
125
- });
126
-
127
- test('Registers actions loaded from adapter loadActions call', async () => {
128
- const mockContract = defineContract({
129
- name: 'testcontract',
130
- actions: {
131
- testmethod: contractAction(jest.fn(), { trigger: 'time' })
132
- }
133
- });
134
-
135
- await sut.registerContract(mockContract);
136
-
137
- const adapter = {
138
- create: jest.fn().mockResolvedValue(true),
139
- destroy: jest.fn(),
140
- loadActions: jest.fn().mockResolvedValue([{
141
- timeValue: '1m',
142
- id: 'testoneminute',
143
- contractName: 'testcontract',
144
- contractAction: 'testmethod',
145
- payload: {},
146
- date: new Date().toISOString(),
147
- enabled: true,
148
- executionCount: 0
149
- }]),
150
- loadState: jest.fn().mockResolvedValue(null),
151
- saveState: jest.fn().mockResolvedValue(true),
152
- processBlock: jest.fn(),
153
- processOperation: jest.fn(),
154
- processTransfer: jest.fn(),
155
- processCustomJson: jest.fn(),
156
- find: jest.fn(),
157
- findOne: jest.fn(),
158
- insert: jest.fn(),
159
- replace: jest.fn(),
160
- client: null,
161
- db: null
162
- } as any;
163
-
164
- await sut.registerAdapter(adapter);
165
-
166
- const action = new TimeAction('1h', 'testonehour', 'testcontract', 'testmethod');
167
-
168
- await sut.registerAction(action);
169
-
170
- const foundAction = sut['actions'].find(a => a.id === 'testoneminute');
171
-
172
- expect(foundAction).not.toBeUndefined();
173
- });
174
- });
175
-
176
- describe('Contracts', () => {
177
- test('Should register a new contract', async () => {
178
- const contract = defineContract({
179
- name: 'testcontract',
180
- actions: {
181
- myMethod: contractAction(jest.fn())
182
- }
183
- });
184
-
185
- await sut.registerContract(contract);
186
-
187
- expect(sut['contracts'].length).toStrictEqual(1);
188
- });
189
-
190
- test('Should register a new contract and call its create hook', async () => {
191
- const createHook = jest.fn();
192
- const contract = defineContract({
193
- name: 'testcontract',
194
- hooks: {
195
- create: createHook
196
- },
197
- actions: {
198
- myMethod: contractAction(jest.fn())
199
- }
200
- });
201
-
202
- await sut.registerContract(contract);
203
-
204
- expect(createHook).toHaveBeenCalled();
205
- expect(sut['contracts'].length).toStrictEqual(1);
206
- });
207
-
208
- test('Should unregister a registered contract', async () => {
209
- const contract = defineContract({
210
- name: 'testcontract',
211
- actions: {
212
- myMethod: contractAction(jest.fn())
213
- }
214
- });
215
-
216
- await sut.registerContract(contract);
217
- await sut.unregisterContract('testcontract');
218
-
219
- expect(sut['contracts'].length).toStrictEqual(0);
220
- });
221
-
222
- test('Should unregister a registered contract and call its destroy hook', async () => {
223
- const destroyHook = jest.fn();
224
- const contract = defineContract({
225
- name: 'testcontract',
226
- hooks: {
227
- destroy: destroyHook
228
- },
229
- actions: {
230
- myMethod: contractAction(jest.fn())
231
- }
232
- });
233
-
234
- await sut.registerContract(contract);
235
- await sut.unregisterContract('testcontract');
236
-
237
- expect(destroyHook).toHaveBeenCalled();
238
- expect(sut['contracts'].length).toStrictEqual(0);
239
- });
240
- });
241
-
242
- test('Start method should resume from previous block number', async () => {
243
- // Override config to not have a preset LAST_BLOCK_NUMBER
244
- sut.setConfig({ LAST_BLOCK_NUMBER: 0 });
245
-
246
- const adapter = {
247
- create: jest.fn().mockResolvedValue(true),
248
- destroy: jest.fn(),
249
- loadActions: jest.fn().mockResolvedValue([]),
250
- loadState: jest.fn().mockResolvedValue({ lastBlockNumber: 509992 }),
251
- saveState: jest.fn().mockResolvedValue(true),
252
- processBlock: jest.fn(),
253
- processOperation: jest.fn(),
254
- processTransfer: jest.fn(),
255
- processCustomJson: jest.fn(),
256
- find: jest.fn(),
257
- findOne: jest.fn(),
258
- insert: jest.fn(),
259
- replace: jest.fn(),
260
- client: null,
261
- db: null
262
- } as any;
263
-
264
- await sut.registerAdapter(adapter);
265
-
266
- jest.spyOn(sut as any, 'getBlock').mockImplementation(() => true);
267
- jest.spyOn(sut as any, 'getLatestBlock').mockImplementation(() => true);
268
-
269
- await sut.start();
270
-
271
- expect(sut['lastBlockNumber']).toStrictEqual(509992);
272
-
273
- sut.stop();
274
- });
275
-
276
- test('Start method should respect RESUME_FROM_STATE false', async () => {
277
- sut.setConfig({ LAST_BLOCK_NUMBER: 123, RESUME_FROM_STATE: false });
278
-
279
- const adapter = {
280
- create: jest.fn().mockResolvedValue(true),
281
- destroy: jest.fn(),
282
- loadActions: jest.fn().mockResolvedValue([]),
283
- loadState: jest.fn().mockResolvedValue({ lastBlockNumber: 999 }),
284
- saveState: jest.fn().mockResolvedValue(true),
285
- processBlock: jest.fn(),
286
- processOperation: jest.fn(),
287
- processTransfer: jest.fn(),
288
- processCustomJson: jest.fn(),
289
- find: jest.fn(),
290
- findOne: jest.fn(),
291
- insert: jest.fn(),
292
- replace: jest.fn(),
293
- client: null,
294
- db: null
295
- } as any;
296
-
297
- await sut.registerAdapter(adapter);
298
-
299
- jest.spyOn(sut as any, 'getBlock').mockImplementation(() => true);
300
- jest.spyOn(sut as any, 'getLatestBlock').mockImplementation(() => true);
301
-
302
- await sut.start();
303
-
304
- expect(sut['lastBlockNumber']).toStrictEqual(123);
305
-
306
- sut.stop();
307
- });
308
-
309
- test('getBlock should process multiple blocks per batch when behind', async () => {
310
- const adapter = createMockAdapter();
311
- await sut.registerAdapter(adapter);
312
-
313
- sut.setConfig({ CATCH_UP_BATCH_SIZE: 3, BLOCK_CHECK_INTERVAL: 1, DEBUG_MODE: false });
314
- sut['lastBlockNumber'] = 10;
315
-
316
- const mockBlock = {
317
- block_id: 'block-id',
318
- previous: 'prev-id',
319
- transaction_ids: ['trx-1'],
320
- timestamp: '2023-01-01T00:00:00',
321
- transactions: []
322
- };
323
-
324
- sut['client'] = {
325
- database: {
326
- getDynamicGlobalProperties: jest.fn().mockResolvedValue({
327
- head_block_number: 20,
328
- time: '2023-01-01T00:00:00'
329
- }),
330
- getBlock: jest.fn().mockResolvedValue(mockBlock)
331
- }
332
- } as any;
333
-
334
- const loadBlockSpy = jest.spyOn(sut as any, 'loadBlock');
335
-
336
- await (sut as any).getBlock();
337
- clearTimeout(sut['blockNumberTimeout']);
338
-
339
- expect(loadBlockSpy).toHaveBeenCalledTimes(3);
340
- expect(sut['lastBlockNumber']).toStrictEqual(13);
341
- });
342
- });