@steerprotocol/data-connector-loader 5.0.0-next.1 → 5.0.0-next.10

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 (50) hide show
  1. package/README.md +102 -0
  2. package/lib/bundle/bundleBase.d.ts +11 -14
  3. package/lib/bundle/bundleBase.js +56 -88
  4. package/lib/bundle/bundleDataConnector.d.ts +2 -6
  5. package/lib/bundle/bundleDataConnector.js +22 -47
  6. package/lib/esm/bundle/bundleBase.d.ts +11 -14
  7. package/lib/esm/bundle/bundleBase.js +77 -91
  8. package/lib/esm/bundle/bundleDataConnector.d.ts +2 -6
  9. package/lib/esm/bundle/bundleDataConnector.js +26 -49
  10. package/lib/esm/execution/executionApp.d.ts +16 -15
  11. package/lib/esm/execution/executionApp.js +364 -321
  12. package/lib/esm/execution/executionBase.d.ts +7 -7
  13. package/lib/esm/execution/executionBase.js +27 -13
  14. package/lib/esm/execution/executionDataConnector.d.ts +6 -3
  15. package/lib/esm/execution/executionDataConnector.js +128 -69
  16. package/lib/esm/index.d.ts +7 -7
  17. package/lib/esm/index.js +4 -4
  18. package/lib/esm/types.d.ts +20 -24
  19. package/lib/esm/types.js +5 -5
  20. package/lib/esm/utils/blockFinder.d.ts +2 -2
  21. package/lib/esm/utils/blockFinder.js +3 -3
  22. package/lib/esm/utils/consts.js +39 -39
  23. package/lib/esm/utils/pluginManager.d.ts +1 -1
  24. package/lib/esm/utils/pluginManager.js +6 -5
  25. package/lib/esm/utils/replace-old-subgraphs.js +79 -61
  26. package/lib/esm/utils/rpc.d.ts +4 -0
  27. package/lib/esm/utils/rpc.js +32 -0
  28. package/lib/esm/utils/utils.d.ts +8 -11
  29. package/lib/esm/utils/utils.js +61 -55
  30. package/lib/execution/executionApp.d.ts +16 -15
  31. package/lib/execution/executionApp.js +353 -315
  32. package/lib/execution/executionBase.d.ts +7 -7
  33. package/lib/execution/executionBase.js +27 -13
  34. package/lib/execution/executionDataConnector.d.ts +6 -3
  35. package/lib/execution/executionDataConnector.js +130 -64
  36. package/lib/index.d.ts +7 -7
  37. package/lib/index.js +1 -1
  38. package/lib/types.d.ts +20 -24
  39. package/lib/types.js +5 -5
  40. package/lib/utils/blockFinder.d.ts +2 -2
  41. package/lib/utils/blockFinder.js +3 -3
  42. package/lib/utils/consts.js +39 -39
  43. package/lib/utils/pluginManager.d.ts +1 -1
  44. package/lib/utils/pluginManager.js +5 -4
  45. package/lib/utils/replace-old-subgraphs.js +79 -61
  46. package/lib/utils/rpc.d.ts +4 -0
  47. package/lib/utils/rpc.js +47 -0
  48. package/lib/utils/utils.d.ts +8 -11
  49. package/lib/utils/utils.js +55 -60
  50. package/package.json +15 -15
@@ -1,44 +1,42 @@
1
- import { DataConnector } from '../bundle/bundleDataConnector.js';
2
- import { ExecutionContextError, StrategyExecutionError } from '../types.js';
3
- import { fetchData, readContract } from '../utils/utils.js';
4
- import { ExecutionBase } from './executionBase.js';
1
+ import { DataConnector } from "../bundle/bundleDataConnector.js";
2
+ import { ExecutionContextError, StrategyExecutionError } from "../types.js";
3
+ import { fetchData, readContract } from "../utils/utils.js";
4
+ import { ExecutionBase } from "./executionBase.js";
5
5
  export class ExecutionApp extends ExecutionBase {
6
6
  constructor(config) {
7
7
  super(config.maxRetries ?? 3);
8
- this.getSlot0 = async (pool, currentExecutionContext, provider, rpc) => {
8
+ this.getSlot0 = async (pool, currentExecutionContext, provider) => {
9
9
  const slot0Abi = [
10
10
  {
11
11
  inputs: [],
12
- name: 'slot0',
12
+ name: "slot0",
13
13
  outputs: [
14
- { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' },
15
- { internalType: 'int24', name: 'tick', type: 'int24' },
16
- { internalType: 'uint16', name: 'observationIndex', type: 'uint16' },
14
+ { internalType: "uint160", name: "sqrtPriceX96", type: "uint160" },
15
+ { internalType: "int24", name: "tick", type: "int24" },
16
+ { internalType: "uint16", name: "observationIndex", type: "uint16" },
17
17
  {
18
- internalType: 'uint16',
19
- name: 'observationCardinality',
20
- type: 'uint16',
18
+ internalType: "uint16",
19
+ name: "observationCardinality",
20
+ type: "uint16",
21
21
  },
22
22
  {
23
- internalType: 'uint16',
24
- name: 'observationCardinalityNext',
25
- type: 'uint16',
23
+ internalType: "uint16",
24
+ name: "observationCardinalityNext",
25
+ type: "uint16",
26
26
  },
27
- { internalType: 'uint8', name: 'feeProtocol', type: 'uint8' },
28
- { internalType: 'bool', name: 'unlocked', type: 'bool' },
27
+ { internalType: "uint8", name: "feeProtocol", type: "uint8" },
28
+ { internalType: "bool", name: "unlocked", type: "bool" },
29
29
  ],
30
- stateMutability: 'view',
31
- type: 'function',
30
+ stateMutability: "view",
31
+ type: "function",
32
32
  },
33
33
  ];
34
34
  const slot0 = await readContract({
35
35
  address: pool,
36
36
  abi: slot0Abi,
37
37
  currentExecutionContext,
38
- functionName: 'slot0',
38
+ functionName: "slot0",
39
39
  provider,
40
- rpc,
41
- chainId: this.chainId,
42
40
  });
43
41
  return {
44
42
  sqrtPriceX96: slot0[0],
@@ -50,55 +48,53 @@ export class ExecutionApp extends ExecutionBase {
50
48
  unlocked: slot0[6],
51
49
  };
52
50
  };
53
- this.getSlot0Aerodrome = async (pool, currentExecutionContext, provider, rpc) => {
51
+ this.getSlot0Aerodrome = async (pool, currentExecutionContext, provider) => {
54
52
  const slot0Abi = [
55
53
  {
56
54
  inputs: [],
57
- name: 'slot0',
55
+ name: "slot0",
58
56
  outputs: [
59
57
  {
60
- internalType: 'uint160',
61
- name: 'sqrtPriceX96',
62
- type: 'uint160',
58
+ internalType: "uint160",
59
+ name: "sqrtPriceX96",
60
+ type: "uint160",
63
61
  },
64
62
  {
65
- internalType: 'int24',
66
- name: 'tick',
67
- type: 'int24',
63
+ internalType: "int24",
64
+ name: "tick",
65
+ type: "int24",
68
66
  },
69
67
  {
70
- internalType: 'uint16',
71
- name: 'observationIndex',
72
- type: 'uint16',
68
+ internalType: "uint16",
69
+ name: "observationIndex",
70
+ type: "uint16",
73
71
  },
74
72
  {
75
- internalType: 'uint16',
76
- name: 'observationCardinality',
77
- type: 'uint16',
73
+ internalType: "uint16",
74
+ name: "observationCardinality",
75
+ type: "uint16",
78
76
  },
79
77
  {
80
- internalType: 'uint16',
81
- name: 'observationCardinalityNext',
82
- type: 'uint16',
78
+ internalType: "uint16",
79
+ name: "observationCardinalityNext",
80
+ type: "uint16",
83
81
  },
84
82
  {
85
- internalType: 'bool',
86
- name: 'unlocked',
87
- type: 'bool',
83
+ internalType: "bool",
84
+ name: "unlocked",
85
+ type: "bool",
88
86
  },
89
87
  ],
90
- stateMutability: 'view',
91
- type: 'function',
88
+ stateMutability: "view",
89
+ type: "function",
92
90
  },
93
91
  ];
94
92
  const slot0 = await readContract({
95
93
  address: pool,
96
94
  abi: slot0Abi,
97
95
  currentExecutionContext,
98
- functionName: 'slot0',
96
+ functionName: "slot0",
99
97
  provider,
100
- rpc,
101
- chainId: this.chainId,
102
98
  });
103
99
  return {
104
100
  sqrtPriceX96: slot0[0],
@@ -113,317 +109,315 @@ export class ExecutionApp extends ExecutionBase {
113
109
  if (this.isAlgebraIntegralPool) {
114
110
  return {
115
111
  inputs: [],
116
- name: 'globalState',
112
+ name: "globalState",
117
113
  outputs: [
118
114
  {
119
- internalType: 'uint160',
120
- name: 'price',
121
- type: 'uint160',
115
+ internalType: "uint160",
116
+ name: "price",
117
+ type: "uint160",
122
118
  },
123
119
  {
124
- internalType: 'int24',
125
- name: 'tick',
126
- type: 'int24',
120
+ internalType: "int24",
121
+ name: "tick",
122
+ type: "int24",
127
123
  },
128
124
  {
129
- internalType: 'uint16',
130
- name: 'lastFee',
131
- type: 'uint16',
125
+ internalType: "uint16",
126
+ name: "lastFee",
127
+ type: "uint16",
132
128
  },
133
129
  {
134
- internalType: 'uint8',
135
- name: 'pluginConfig',
136
- type: 'uint8',
130
+ internalType: "uint8",
131
+ name: "pluginConfig",
132
+ type: "uint8",
137
133
  },
138
134
  {
139
- internalType: 'uint16',
140
- name: 'communityFee',
141
- type: 'uint16',
135
+ internalType: "uint16",
136
+ name: "communityFee",
137
+ type: "uint16",
142
138
  },
143
139
  {
144
- internalType: 'bool',
145
- name: 'unlocked',
146
- type: 'bool',
140
+ internalType: "bool",
141
+ name: "unlocked",
142
+ type: "bool",
147
143
  },
148
144
  ],
149
- stateMutability: 'view',
150
- type: 'function',
145
+ stateMutability: "view",
146
+ type: "function",
151
147
  };
152
148
  }
153
149
  else if (this.isDirectionalPool) {
154
150
  return {
155
151
  inputs: [],
156
- name: 'globalState',
152
+ name: "globalState",
157
153
  outputs: [
158
154
  {
159
- internalType: 'uint160',
160
- name: 'price',
161
- type: 'uint160',
155
+ internalType: "uint160",
156
+ name: "price",
157
+ type: "uint160",
162
158
  },
163
159
  {
164
- internalType: 'int24',
165
- name: 'tick',
166
- type: 'int24',
160
+ internalType: "int24",
161
+ name: "tick",
162
+ type: "int24",
167
163
  },
168
164
  {
169
- internalType: 'uint16',
170
- name: 'feeZto',
171
- type: 'uint16',
165
+ internalType: "uint16",
166
+ name: "feeZto",
167
+ type: "uint16",
172
168
  },
173
169
  {
174
- internalType: 'uint16',
175
- name: 'feeOtz',
176
- type: 'uint16',
170
+ internalType: "uint16",
171
+ name: "feeOtz",
172
+ type: "uint16",
177
173
  },
178
174
  {
179
- internalType: 'uint16',
180
- name: 'timepointIndex',
181
- type: 'uint16',
175
+ internalType: "uint16",
176
+ name: "timepointIndex",
177
+ type: "uint16",
182
178
  },
183
179
  {
184
- internalType: 'uint8',
185
- name: 'communityFeeToken0',
186
- type: 'uint8',
180
+ internalType: "uint8",
181
+ name: "communityFeeToken0",
182
+ type: "uint8",
187
183
  },
188
184
  {
189
- internalType: 'uint8',
190
- name: 'communityFeeToken1',
191
- type: 'uint8',
185
+ internalType: "uint8",
186
+ name: "communityFeeToken1",
187
+ type: "uint8",
192
188
  },
193
189
  {
194
- internalType: 'bool',
195
- name: 'unlocked',
196
- type: 'bool',
190
+ internalType: "bool",
191
+ name: "unlocked",
192
+ type: "bool",
197
193
  },
198
194
  ],
199
- stateMutability: 'view',
200
- type: 'function',
195
+ stateMutability: "view",
196
+ type: "function",
201
197
  };
202
198
  }
203
199
  else if (this.isPoolSharkPool) {
204
200
  return {
205
201
  inputs: [],
206
- name: 'globalState',
202
+ name: "globalState",
207
203
  outputs: [
208
204
  {
209
205
  components: [
210
206
  {
211
207
  components: [
212
208
  {
213
- internalType: 'uint16',
214
- name: 'index',
215
- type: 'uint16',
209
+ internalType: "uint16",
210
+ name: "index",
211
+ type: "uint16",
216
212
  },
217
213
  {
218
- internalType: 'uint16',
219
- name: 'count',
220
- type: 'uint16',
214
+ internalType: "uint16",
215
+ name: "count",
216
+ type: "uint16",
221
217
  },
222
218
  {
223
- internalType: 'uint16',
224
- name: 'countMax',
225
- type: 'uint16',
219
+ internalType: "uint16",
220
+ name: "countMax",
221
+ type: "uint16",
226
222
  },
227
223
  ],
228
- internalType: 'struct PoolsharkStructs.SampleState',
229
- name: 'samples',
230
- type: 'tuple',
224
+ internalType: "struct PoolsharkStructs.SampleState",
225
+ name: "samples",
226
+ type: "tuple",
231
227
  },
232
228
  {
233
- internalType: 'uint200',
234
- name: 'feeGrowthGlobal0',
235
- type: 'uint200',
229
+ internalType: "uint200",
230
+ name: "feeGrowthGlobal0",
231
+ type: "uint200",
236
232
  },
237
233
  {
238
- internalType: 'uint200',
239
- name: 'feeGrowthGlobal1',
240
- type: 'uint200',
234
+ internalType: "uint200",
235
+ name: "feeGrowthGlobal1",
236
+ type: "uint200",
241
237
  },
242
238
  {
243
- internalType: 'uint160',
244
- name: 'secondsPerLiquidityAccum',
245
- type: 'uint160',
239
+ internalType: "uint160",
240
+ name: "secondsPerLiquidityAccum",
241
+ type: "uint160",
246
242
  },
247
243
  {
248
- internalType: 'uint160',
249
- name: 'price',
250
- type: 'uint160',
244
+ internalType: "uint160",
245
+ name: "price",
246
+ type: "uint160",
251
247
  },
252
248
  {
253
- internalType: 'uint128',
254
- name: 'liquidity',
255
- type: 'uint128',
249
+ internalType: "uint128",
250
+ name: "liquidity",
251
+ type: "uint128",
256
252
  },
257
253
  {
258
- internalType: 'int56',
259
- name: 'tickSecondsAccum',
260
- type: 'int56',
254
+ internalType: "int56",
255
+ name: "tickSecondsAccum",
256
+ type: "int56",
261
257
  },
262
258
  {
263
- internalType: 'int24',
264
- name: 'tickAtPrice',
265
- type: 'int24',
259
+ internalType: "int24",
260
+ name: "tickAtPrice",
261
+ type: "int24",
266
262
  },
267
263
  {
268
- internalType: 'uint16',
269
- name: 'protocolSwapFee0',
270
- type: 'uint16',
264
+ internalType: "uint16",
265
+ name: "protocolSwapFee0",
266
+ type: "uint16",
271
267
  },
272
268
  {
273
- internalType: 'uint16',
274
- name: 'protocolSwapFee1',
275
- type: 'uint16',
269
+ internalType: "uint16",
270
+ name: "protocolSwapFee1",
271
+ type: "uint16",
276
272
  },
277
273
  ],
278
- internalType: 'struct PoolsharkStructs.RangePoolState',
279
- name: 'pool',
280
- type: 'tuple',
274
+ internalType: "struct PoolsharkStructs.RangePoolState",
275
+ name: "pool",
276
+ type: "tuple",
281
277
  },
282
278
  {
283
279
  components: [
284
280
  {
285
- internalType: 'uint160',
286
- name: 'price',
287
- type: 'uint160',
281
+ internalType: "uint160",
282
+ name: "price",
283
+ type: "uint160",
288
284
  },
289
285
  {
290
- internalType: 'uint128',
291
- name: 'liquidity',
292
- type: 'uint128',
286
+ internalType: "uint128",
287
+ name: "liquidity",
288
+ type: "uint128",
293
289
  },
294
290
  {
295
- internalType: 'uint128',
296
- name: 'protocolFees',
297
- type: 'uint128',
291
+ internalType: "uint128",
292
+ name: "protocolFees",
293
+ type: "uint128",
298
294
  },
299
295
  {
300
- internalType: 'uint16',
301
- name: 'protocolFillFee',
302
- type: 'uint16',
296
+ internalType: "uint16",
297
+ name: "protocolFillFee",
298
+ type: "uint16",
303
299
  },
304
300
  {
305
- internalType: 'int24',
306
- name: 'tickAtPrice',
307
- type: 'int24',
301
+ internalType: "int24",
302
+ name: "tickAtPrice",
303
+ type: "int24",
308
304
  },
309
305
  ],
310
- internalType: 'struct PoolsharkStructs.LimitPoolState',
311
- name: 'pool0',
312
- type: 'tuple',
306
+ internalType: "struct PoolsharkStructs.LimitPoolState",
307
+ name: "pool0",
308
+ type: "tuple",
313
309
  },
314
310
  {
315
311
  components: [
316
312
  {
317
- internalType: 'uint160',
318
- name: 'price',
319
- type: 'uint160',
313
+ internalType: "uint160",
314
+ name: "price",
315
+ type: "uint160",
320
316
  },
321
317
  {
322
- internalType: 'uint128',
323
- name: 'liquidity',
324
- type: 'uint128',
318
+ internalType: "uint128",
319
+ name: "liquidity",
320
+ type: "uint128",
325
321
  },
326
322
  {
327
- internalType: 'uint128',
328
- name: 'protocolFees',
329
- type: 'uint128',
323
+ internalType: "uint128",
324
+ name: "protocolFees",
325
+ type: "uint128",
330
326
  },
331
327
  {
332
- internalType: 'uint16',
333
- name: 'protocolFillFee',
334
- type: 'uint16',
328
+ internalType: "uint16",
329
+ name: "protocolFillFee",
330
+ type: "uint16",
335
331
  },
336
332
  {
337
- internalType: 'int24',
338
- name: 'tickAtPrice',
339
- type: 'int24',
333
+ internalType: "int24",
334
+ name: "tickAtPrice",
335
+ type: "int24",
340
336
  },
341
337
  ],
342
- internalType: 'struct PoolsharkStructs.LimitPoolState',
343
- name: 'pool1',
344
- type: 'tuple',
338
+ internalType: "struct PoolsharkStructs.LimitPoolState",
339
+ name: "pool1",
340
+ type: "tuple",
345
341
  },
346
342
  {
347
- internalType: 'uint128',
348
- name: 'liquidityGlobal',
349
- type: 'uint128',
343
+ internalType: "uint128",
344
+ name: "liquidityGlobal",
345
+ type: "uint128",
350
346
  },
351
347
  {
352
- internalType: 'uint32',
353
- name: 'positionIdNext',
354
- type: 'uint32',
348
+ internalType: "uint32",
349
+ name: "positionIdNext",
350
+ type: "uint32",
355
351
  },
356
352
  {
357
- internalType: 'uint32',
358
- name: 'epoch',
359
- type: 'uint32',
353
+ internalType: "uint32",
354
+ name: "epoch",
355
+ type: "uint32",
360
356
  },
361
357
  {
362
- internalType: 'uint8',
363
- name: 'unlocked',
364
- type: 'uint8',
358
+ internalType: "uint8",
359
+ name: "unlocked",
360
+ type: "uint8",
365
361
  },
366
362
  ],
367
- stateMutability: 'view',
368
- type: 'function',
363
+ stateMutability: "view",
364
+ type: "function",
369
365
  };
370
366
  }
371
367
  else {
372
368
  return {
373
369
  inputs: [],
374
- name: 'globalState',
370
+ name: "globalState",
375
371
  outputs: [
376
372
  {
377
- internalType: 'uint160',
378
- name: 'price',
379
- type: 'uint160',
373
+ internalType: "uint160",
374
+ name: "price",
375
+ type: "uint160",
380
376
  },
381
377
  {
382
- internalType: 'int24',
383
- name: 'tick',
384
- type: 'int24',
378
+ internalType: "int24",
379
+ name: "tick",
380
+ type: "int24",
385
381
  },
386
382
  {
387
- internalType: 'int24',
388
- name: 'prevInitializedTick',
389
- type: 'int24',
383
+ internalType: "int24",
384
+ name: "prevInitializedTick",
385
+ type: "int24",
390
386
  },
391
387
  {
392
- internalType: 'uint16',
393
- name: 'fee',
394
- type: 'uint16',
388
+ internalType: "uint16",
389
+ name: "fee",
390
+ type: "uint16",
395
391
  },
396
392
  {
397
- internalType: 'uint16',
398
- name: 'timepointIndex',
399
- type: 'uint16',
393
+ internalType: "uint16",
394
+ name: "timepointIndex",
395
+ type: "uint16",
400
396
  },
401
397
  {
402
- internalType: 'uint8',
403
- name: 'communityFee',
404
- type: 'uint8',
398
+ internalType: "uint8",
399
+ name: "communityFee",
400
+ type: "uint8",
405
401
  },
406
402
  {
407
- internalType: 'bool',
408
- name: 'unlocked',
409
- type: 'bool',
403
+ internalType: "bool",
404
+ name: "unlocked",
405
+ type: "bool",
410
406
  },
411
407
  ],
412
- stateMutability: 'view',
413
- type: 'function',
408
+ stateMutability: "view",
409
+ type: "function",
414
410
  };
415
411
  }
416
412
  };
417
- this.getGlobalState = async (pool, currentExecutionContext, provider, rpc) => {
413
+ this.getGlobalState = async (pool, currentExecutionContext, provider) => {
418
414
  const slot0Abi = [this.getGlobalStateAbi()];
419
415
  const slot0 = await readContract({
420
416
  address: pool,
421
417
  abi: slot0Abi,
422
418
  currentExecutionContext,
423
- functionName: 'globalState',
419
+ functionName: "globalState",
424
420
  provider,
425
- rpc,
426
- chainId: this.chainId,
427
421
  });
428
422
  if (this.isPoolSharkPool) {
429
423
  return {
@@ -457,33 +451,40 @@ export class ExecutionApp extends ExecutionBase {
457
451
  };
458
452
  };
459
453
  this.vault = config.vault;
460
- this.steerSubgraph = config.steerSubgraph;
454
+ this.steerSubgraph = config.steerSubgraph ?? "";
461
455
  this.chainId = config.chainId;
462
- this.isAlgebraPool = config.poolType.isAlgebraPool;
463
- this.isAlgebraIntegralPool = config.poolType.isAlgebraIntegralPool;
464
- this.isDirectionalPool = config.poolType.isDirectionalPool;
465
- this.isPoolSharkPool = config.poolType.isPoolSharkPool;
466
- this.isAerodromePool = config.poolType.isAerodromePool;
467
- this.subgraphStudioKey = config.apiKeys.subgraphStudioKey;
468
- this.sentioApiKey = config.apiKeys.sentioApiKey;
456
+ this.isAlgebraPool = config.poolType?.isAlgebraPool ?? false;
457
+ this.isAlgebraIntegralPool =
458
+ config.poolType?.isAlgebraIntegralPool ?? false;
459
+ this.isDirectionalPool = config.poolType?.isDirectionalPool ?? false;
460
+ this.isPoolSharkPool = config.poolType?.isPoolSharkPool ?? false;
461
+ this.isAerodromePool = config.poolType?.isAerodromePool ?? false;
462
+ this.sentioApiKey = config.apiKeys?.sentioApiKey ?? "";
469
463
  this.config = config;
470
464
  }
471
- async execute(_wasmFile, _vaultConfig, _data, _identity, _etherRpcConfig, forceDeposit) {
472
- const dataConnector = new DataConnector(_wasmFile, _vaultConfig, this.config, _identity, _etherRpcConfig);
465
+ async execute(_wasmFile, _vaultConfig, _data, rpc, forceDeposit) {
466
+ if (!this.config.poolType) {
467
+ throw new Error("poolType is required by execute() for pool discovery.");
468
+ }
469
+ if (!this.steerSubgraph.trim()) {
470
+ throw new Error("steerSubgraph is required by execute() for pool discovery.");
471
+ }
472
+ const dataConnector = new DataConnector({
473
+ wasmFile: _wasmFile,
474
+ config: _vaultConfig,
475
+ executionConfig: this.config,
476
+ rpc,
477
+ });
473
478
  await dataConnector.loadSync();
474
479
  const executionContext = await this.getExecutionContext(dataConnector, JSON.parse(_vaultConfig));
475
- let rpc = '';
476
- if (_etherRpcConfig) {
477
- rpc = _etherRpcConfig[this.chainId.toString()].url;
478
- }
479
- const smartPoolExecutionContext = await this.getSmartPoolExecutionContext(executionContext, dataConnector, JSON.parse(_vaultConfig), rpc);
480
+ const smartPoolExecutionContext = await this.getSmartPoolExecutionContext(executionContext, dataConnector, JSON.parse(_vaultConfig));
480
481
  dataConnector.setExecutionContextStrategyExecution({
481
482
  ...executionContext,
482
483
  ...smartPoolExecutionContext,
483
484
  }, forceDeposit);
484
485
  _data = _data.map((element) => JSON.stringify(element));
485
486
  const result = await dataConnector.executeBundle(_data);
486
- return JSON.parse(result);
487
+ return this.parseStrategyResult(result);
487
488
  }
488
489
  /**
489
490
  * Executes a strategy against a supplied execution context.
@@ -492,14 +493,23 @@ export class ExecutionApp extends ExecutionBase {
492
493
  */
493
494
  async executeWithContext(options) {
494
495
  const vaultConfig = this.parseVaultConfig(options.vaultConfig);
495
- const executionContext = options.executionContext;
496
- this.validateExecutionContext(executionContext, vaultConfig);
497
- const dataConnector = new DataConnector(options.wasmFile, options.vaultConfig, this.config, options.identity, options.etherRpcConfig);
496
+ this.validateExecutionContext(options.executionContext, vaultConfig);
497
+ const executionContext = {
498
+ ...options.executionContext,
499
+ positions: options.executionContext.positions.map((position) => ({
500
+ ...position,
501
+ })),
502
+ };
503
+ const dataConnector = new DataConnector({
504
+ wasmFile: options.wasmFile,
505
+ config: options.vaultConfig,
506
+ executionConfig: this.config,
507
+ });
498
508
  try {
499
509
  await dataConnector.loadSync();
500
510
  dataConnector.initializeStrategyWithContext(executionContext, options.forceDeposit);
501
511
  const result = await dataConnector.executeBundle(options.data.map((item) => JSON.stringify(item)));
502
- return JSON.parse(result);
512
+ return this.parseStrategyResult(result);
503
513
  }
504
514
  catch (error) {
505
515
  if (error instanceof ExecutionContextError)
@@ -507,17 +517,28 @@ export class ExecutionApp extends ExecutionBase {
507
517
  throw new StrategyExecutionError(this.redactError(error));
508
518
  }
509
519
  }
520
+ /** T is the complete decoded JSON result. Only the exact sentinel skips JSON decoding. */
521
+ parseStrategyResult(result) {
522
+ if (result === "continue")
523
+ return result;
524
+ try {
525
+ return JSON.parse(result);
526
+ }
527
+ catch (error) {
528
+ throw new StrategyExecutionError(this.redactError(error));
529
+ }
530
+ }
510
531
  parseVaultConfig(vaultConfig) {
511
532
  try {
512
533
  return JSON.parse(vaultConfig);
513
534
  }
514
535
  catch {
515
- throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'vaultConfig must be valid JSON.');
536
+ throw new ExecutionContextError("INVALID_EXECUTION_CONTEXT", "vaultConfig must be valid JSON.");
516
537
  }
517
538
  }
518
539
  validateExecutionContext(context, vaultConfig) {
519
- if (!context || typeof context !== 'object') {
520
- throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'An execution context is required.');
540
+ if (!context || typeof context !== "object") {
541
+ throw new ExecutionContextError("INVALID_EXECUTION_CONTEXT", "An execution context is required.");
521
542
  }
522
543
  if (!Number.isSafeInteger(context.chainId) ||
523
544
  !Number.isSafeInteger(context.blockNumber) ||
@@ -531,50 +552,57 @@ export class ExecutionApp extends ExecutionBase {
531
552
  !Number.isFinite(context.blockTime) ||
532
553
  !Number.isInteger(context.currentTick) ||
533
554
  !Number.isInteger(context.tickSpacing) ||
534
- typeof context.vaultAddress !== 'string' ||
555
+ typeof context.vaultAddress !== "string" ||
535
556
  context.vaultAddress.length === 0 ||
536
- typeof context.totalAmount0 !== 'string' ||
557
+ typeof context.totalAmount0 !== "string" ||
537
558
  !/^\d+$/.test(context.totalAmount0) ||
538
- typeof context.totalAmount1 !== 'string' ||
559
+ typeof context.totalAmount1 !== "string" ||
539
560
  !/^\d+$/.test(context.totalAmount1) ||
540
561
  !Array.isArray(context.positions) ||
541
562
  !Number.isFinite(context.lastExecutionTime) ||
542
563
  context.lastExecutionTime < 0) {
543
- throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context is malformed.');
564
+ throw new ExecutionContextError("INVALID_EXECUTION_CONTEXT", "Execution context is malformed.");
544
565
  }
545
566
  const sameAddress = (left, right) => left?.toLowerCase() === right?.toLowerCase();
546
567
  if (!sameAddress(this.vault, context.vaultAddress) ||
547
568
  !sameAddress(vaultConfig.vaultAddress, context.vaultAddress)) {
548
- throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context vault does not match the execution request.');
569
+ throw new ExecutionContextError("EXECUTION_CONTEXT_MISMATCH", "Supplied context vault does not match the execution request.");
549
570
  }
550
571
  if (this.chainId !== context.chainId ||
551
- (vaultConfig.chainId !== undefined && Number(vaultConfig.chainId) !== context.chainId)) {
552
- throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context chain does not match the execution request.');
572
+ (vaultConfig.chainId !== undefined &&
573
+ Number(vaultConfig.chainId) !== context.chainId)) {
574
+ throw new ExecutionContextError("EXECUTION_CONTEXT_MISMATCH", "Supplied context chain does not match the execution request.");
553
575
  }
554
576
  if (vaultConfig.anchorBlockNumber !== undefined &&
555
577
  String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
556
- throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context block does not match anchorBlockNumber.');
578
+ throw new ExecutionContextError("EXECUTION_CONTEXT_MISMATCH", "Supplied context block does not match anchorBlockNumber.");
557
579
  }
558
- if (Number(vaultConfig.strategyConfigData?.epochLength) !== context.epochLength) {
559
- throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context epoch length does not match vaultConfig.');
580
+ if (Number(vaultConfig.strategyConfigData?.epochLength) !==
581
+ context.epochLength) {
582
+ throw new ExecutionContextError("EXECUTION_CONTEXT_MISMATCH", "Supplied context epoch length does not match vaultConfig.");
560
583
  }
561
584
  for (const position of context.positions) {
562
585
  if (!position ||
563
586
  !Number.isInteger(position.startTick) ||
564
587
  !Number.isInteger(position.endTick) ||
565
588
  !Number.isFinite(position.weight)) {
566
- throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context contains an invalid position.');
589
+ throw new ExecutionContextError("INVALID_EXECUTION_CONTEXT", "Execution context contains an invalid position.");
567
590
  }
568
591
  }
569
592
  }
570
593
  redactError(error) {
571
594
  const message = error instanceof Error ? error.message : String(error);
572
595
  return message
573
- .replace(/https?:\/\/[^\s@/]+(?::[^\s@/]+)?@/gi, 'https://[REDACTED]@')
574
- .replace(/([?&](?:key|token|api[_-]?key|password)=)[^&\s]+/gi, '$1[REDACTED]');
596
+ .replace(/https?:\/\/[^\s@/]+(?::[^\s@/]+)?@/gi, "https://[REDACTED]@")
597
+ .replace(/([?&](?:key|token|api[_-]?key|password)=)[^&\s]+/gi, "$1[REDACTED]");
575
598
  }
576
- async executeStabilityVault(_wasmFile, _vaultConfig, _data, _identity, _etherRpcConfig, forceDeposit) {
577
- const dataConnector = new DataConnector(_wasmFile, _vaultConfig, this.config, _identity, _etherRpcConfig);
599
+ async executeStabilityVault(_wasmFile, _vaultConfig, _data, rpc, forceDeposit) {
600
+ const dataConnector = new DataConnector({
601
+ wasmFile: _wasmFile,
602
+ config: _vaultConfig,
603
+ executionConfig: this.config,
604
+ rpc,
605
+ });
578
606
  await dataConnector.loadSync();
579
607
  const executionContext = await this.getExecutionContext(dataConnector, JSON.parse(_vaultConfig));
580
608
  const dynamicJobExecutionContext = {};
@@ -584,15 +612,20 @@ export class ExecutionApp extends ExecutionBase {
584
612
  }, forceDeposit);
585
613
  _data = _data.map((element) => JSON.stringify(element));
586
614
  const result = await dataConnector.executeDynamicJobBundle(_data);
587
- return JSON.parse(result);
615
+ return this.parseStrategyResult(result);
588
616
  }
589
- async executeDynamicJobs(_wasmFile, _vaultConfig, _data, _job, _identity, _etherRpcConfig, forceDeposit) {
590
- const dataConnector = new DataConnector(_wasmFile, _vaultConfig, this.config, _identity, _etherRpcConfig);
617
+ async executeDynamicJobs(_wasmFile, _vaultConfig, _data, _job, rpc, forceDeposit) {
618
+ const dataConnector = new DataConnector({
619
+ wasmFile: _wasmFile,
620
+ config: _vaultConfig,
621
+ executionConfig: this.config,
622
+ rpc,
623
+ });
591
624
  await dataConnector.loadSync();
592
625
  const executionContext = await this.getExecutionContext(dataConnector, JSON.parse(_vaultConfig));
593
626
  const smartRewardsContractAddress = _job.targetAddresses[0];
594
627
  if (!smartRewardsContractAddress) {
595
- throw new Error('Dynamic job must include at least one target address');
628
+ throw new Error("Dynamic job must include at least one target address");
596
629
  }
597
630
  const dynamicJobExecutionContext = {
598
631
  smartRewardsContractAddress,
@@ -603,18 +636,20 @@ export class ExecutionApp extends ExecutionBase {
603
636
  }, forceDeposit);
604
637
  _data = _data.map((element) => JSON.stringify(element));
605
638
  const result = await dataConnector.executeDynamicJobBundle(_data);
606
- return JSON.parse(result);
639
+ return this.parseStrategyResult(result);
607
640
  }
608
- async getSmartPoolExecutionContext(currentExecutionContext, dataConnector, vaultConfig, rpc) {
641
+ async getSmartPoolExecutionContext(currentExecutionContext, dataConnector, vaultConfig) {
609
642
  const smartPoolExecutionContext = {};
610
643
  const request = {
611
- method: 'POST',
644
+ method: "POST",
612
645
  url: this.steerSubgraph,
613
646
  headers: {
614
- 'Content-Type': !this.steerSubgraph.includes('subgraph-proxy-server')
615
- ? 'application/json'
616
- : 'text/plain;charset=UTF-8',
617
- ...(this.steerSubgraph.includes('sentio') ? { 'api-key': this.sentioApiKey } : {}),
647
+ "Content-Type": !this.steerSubgraph.includes("subgraph-proxy-server")
648
+ ? "application/json"
649
+ : "text/plain;charset=UTF-8",
650
+ ...(this.steerSubgraph.includes("sentio")
651
+ ? { "api-key": this.sentioApiKey }
652
+ : {}),
618
653
  },
619
654
  data: {
620
655
  query: `
@@ -634,15 +669,17 @@ export class ExecutionApp extends ExecutionBase {
634
669
  },
635
670
  };
636
671
  const response = await fetchData(request, 4);
637
- this.log('Subgraph response vault positions :', response);
672
+ this.log("Subgraph response vault positions :", response);
638
673
  const requestSnapshot = {
639
- method: 'POST',
674
+ method: "POST",
640
675
  url: this.steerSubgraph,
641
676
  headers: {
642
- 'Content-Type': !this.steerSubgraph.includes('subgraph-proxy-server')
643
- ? 'application/json'
644
- : 'text/plain;charset=UTF-8',
645
- ...(this.steerSubgraph.includes('sentio') ? { 'api-key': this.sentioApiKey } : {}),
677
+ "Content-Type": !this.steerSubgraph.includes("subgraph-proxy-server")
678
+ ? "application/json"
679
+ : "text/plain;charset=UTF-8",
680
+ ...(this.steerSubgraph.includes("sentio")
681
+ ? { "api-key": this.sentioApiKey }
682
+ : {}),
646
683
  },
647
684
  data: {
648
685
  query: `
@@ -659,9 +696,10 @@ export class ExecutionApp extends ExecutionBase {
659
696
  },
660
697
  };
661
698
  const responseSnapshot = await fetchData(requestSnapshot, 4);
662
- this.log('Subgraph response current snapshot', responseSnapshot);
699
+ this.log("Subgraph response current snapshot", responseSnapshot);
663
700
  const positions = [];
664
- if (response?.data?.vaultPositions && response?.data?.vaultPositions.length > 0) {
701
+ if (response?.data?.vaultPositions &&
702
+ response?.data?.vaultPositions.length > 0) {
665
703
  const positionResponse = response?.data?.vaultPositions[0];
666
704
  for (let i = 0; i < positionResponse.upperTick.length; i++) {
667
705
  const position = positionResponse;
@@ -673,25 +711,31 @@ export class ExecutionApp extends ExecutionBase {
673
711
  }
674
712
  }
675
713
  let lastSnapshot;
676
- if (responseSnapshot?.data?.vaultSnapshots && responseSnapshot?.data?.vaultSnapshots.length > 0) {
714
+ if (responseSnapshot?.data?.vaultSnapshots &&
715
+ responseSnapshot?.data?.vaultSnapshots.length > 0) {
677
716
  lastSnapshot = responseSnapshot?.data?.vaultSnapshots[0];
678
717
  }
679
- this.log('Subgraph response vault positions', positions);
718
+ this.log("Subgraph response vault positions", positions);
680
719
  smartPoolExecutionContext.positions = positions;
681
720
  if (lastSnapshot) {
682
- smartPoolExecutionContext.lastExecutionTime = (Date.now() - Number(lastSnapshot.timestamp) * 1000) / 1000;
721
+ smartPoolExecutionContext.lastExecutionTime =
722
+ (Date.now() - Number(lastSnapshot.timestamp) * 1000) / 1000;
683
723
  }
684
724
  else {
685
- smartPoolExecutionContext.lastExecutionTime = currentExecutionContext.epochTimestamp;
725
+ smartPoolExecutionContext.lastExecutionTime =
726
+ currentExecutionContext.epochTimestamp;
686
727
  }
687
- const provider = dataConnector.getProvider(vaultConfig);
728
+ const provider = dataConnector.getClient();
688
729
  if (!provider) {
689
- throw new Error('Provider configuration issue, unable to process Smart Pool execution context.');
730
+ throw new Error("Provider configuration issue, unable to process Smart Pool execution context.");
731
+ }
732
+ if ((await provider.getChainId()) !== currentExecutionContext.chainId) {
733
+ throw new Error("EXECUTION_CONTEXT_MISMATCH: provider chain does not match supplied context.");
690
734
  }
691
735
  const poolAddress = await this.getVaultPoolAddress();
692
- const currentTick = await this.getPoolCurrentTick(poolAddress, provider, currentExecutionContext, rpc);
693
- const tickSpacing = await this.getTickSpacing(poolAddress, provider, rpc, currentExecutionContext);
694
- const totalAmounts = await this.getTotalAmounts(this.vault, currentExecutionContext, provider, rpc);
736
+ const currentTick = await this.getPoolCurrentTick(poolAddress, provider, currentExecutionContext);
737
+ const tickSpacing = await this.getTickSpacing(poolAddress, provider, currentExecutionContext);
738
+ const totalAmounts = await this.getTotalAmounts(this.vault, currentExecutionContext, provider);
695
739
  // Handle both bigint and serialized bigint from centralized API
696
740
  smartPoolExecutionContext.totalAmount0 = this.convertToString(totalAmounts.total0);
697
741
  smartPoolExecutionContext.totalAmount1 = this.convertToString(totalAmounts.total1);
@@ -700,58 +744,56 @@ export class ExecutionApp extends ExecutionBase {
700
744
  // "currentTick": 10,
701
745
  return smartPoolExecutionContext;
702
746
  }
703
- async getPoolCurrentTick(poolAddress, provider, currentExecutionContext, rpc) {
747
+ async getPoolCurrentTick(poolAddress, provider, currentExecutionContext) {
704
748
  if (this.isAlgebraPool || this.isPoolSharkPool) {
705
- const slot0 = await this.getGlobalState(poolAddress, currentExecutionContext, provider, rpc);
749
+ const slot0 = await this.getGlobalState(poolAddress, currentExecutionContext, provider);
706
750
  return slot0.tick;
707
751
  }
708
752
  else if (this.isAerodromePool) {
709
- const slot0 = await this.getSlot0Aerodrome(poolAddress, currentExecutionContext, provider, rpc);
753
+ const slot0 = await this.getSlot0Aerodrome(poolAddress, currentExecutionContext, provider);
710
754
  return slot0.tick;
711
755
  }
712
756
  else {
713
- const slot0 = await this.getSlot0(poolAddress, currentExecutionContext, provider, rpc);
757
+ const slot0 = await this.getSlot0(poolAddress, currentExecutionContext, provider);
714
758
  return slot0.tick;
715
759
  }
716
760
  }
717
- async getTickSpacing(poolAddress, provider, rpc, currentExecutionContext) {
761
+ async getTickSpacing(poolAddress, provider, currentExecutionContext) {
718
762
  const tickSpacingAbi = [
719
763
  this.isPoolSharkPool
720
764
  ? {
721
765
  inputs: [],
722
- name: 'tickSpacing',
766
+ name: "tickSpacing",
723
767
  outputs: [
724
768
  {
725
- internalType: 'int24',
726
- name: '',
727
- type: 'int24',
769
+ internalType: "int24",
770
+ name: "",
771
+ type: "int24",
728
772
  },
729
773
  ],
730
- stateMutability: 'view',
731
- type: 'function',
774
+ stateMutability: "view",
775
+ type: "function",
732
776
  }
733
777
  : {
734
778
  inputs: [],
735
- name: 'tickSpacing',
779
+ name: "tickSpacing",
736
780
  outputs: [
737
781
  {
738
- internalType: 'int16',
739
- name: '',
740
- type: 'int16',
782
+ internalType: "int16",
783
+ name: "",
784
+ type: "int16",
741
785
  },
742
786
  ],
743
- stateMutability: 'pure',
744
- type: 'function',
787
+ stateMutability: "pure",
788
+ type: "function",
745
789
  },
746
790
  ];
747
791
  const tickSpacing = await readContract({
748
792
  address: poolAddress,
749
793
  abi: tickSpacingAbi,
750
794
  currentExecutionContext,
751
- functionName: 'tickSpacing',
795
+ functionName: "tickSpacing",
752
796
  provider,
753
- rpc,
754
- chainId: this.chainId,
755
797
  });
756
798
  return tickSpacing;
757
799
  }
@@ -760,17 +802,17 @@ export class ExecutionApp extends ExecutionBase {
760
802
  * from the centralized API
761
803
  */
762
804
  convertToString(value) {
763
- if (typeof value === 'bigint') {
805
+ if (typeof value === "bigint") {
764
806
  return value.toString();
765
807
  }
766
- if (typeof value === 'number') {
808
+ if (typeof value === "number") {
767
809
  return value.toString();
768
810
  }
769
- if (typeof value === 'string') {
811
+ if (typeof value === "string") {
770
812
  return value;
771
813
  }
772
814
  // Handle serialized bigint from centralized API (e.g., { type: 'BigNumber', hex: '0x...' })
773
- if (value && typeof value === 'object') {
815
+ if (value && typeof value === "object") {
774
816
  // If it's a BigNumber-like object with hex property
775
817
  if (value.hex !== undefined) {
776
818
  return BigInt(value.hex).toString();
@@ -780,34 +822,33 @@ export class ExecutionApp extends ExecutionBase {
780
822
  return BigInt(value._hex).toString();
781
823
  }
782
824
  // If it has toString method, try using it
783
- if (typeof value.toString === 'function' && value.toString() !== '[object Object]') {
825
+ if (typeof value.toString === "function" &&
826
+ value.toString() !== "[object Object]") {
784
827
  return value.toString();
785
828
  }
786
829
  }
787
830
  // Fallback: convert to string (may result in '[object Object]' if not handled above)
788
831
  return String(value);
789
832
  }
790
- async getTotalAmounts(vaultAddress, currentExecutionContext, provider, rpc) {
833
+ async getTotalAmounts(vaultAddress, currentExecutionContext, provider) {
791
834
  const getTotalAmountsABI = [
792
835
  {
793
836
  inputs: [],
794
- name: 'getTotalAmounts',
837
+ name: "getTotalAmounts",
795
838
  outputs: [
796
- { internalType: 'uint256', name: 'total0', type: 'uint256' },
797
- { internalType: 'uint256', name: 'total1', type: 'uint256' },
839
+ { internalType: "uint256", name: "total0", type: "uint256" },
840
+ { internalType: "uint256", name: "total1", type: "uint256" },
798
841
  ],
799
- stateMutability: 'view',
800
- type: 'function',
842
+ stateMutability: "view",
843
+ type: "function",
801
844
  },
802
845
  ];
803
846
  const totalAmounts = await readContract({
804
847
  address: vaultAddress,
805
848
  abi: getTotalAmountsABI,
806
849
  currentExecutionContext,
807
- functionName: 'getTotalAmounts',
850
+ functionName: "getTotalAmounts",
808
851
  provider,
809
- rpc,
810
- chainId: this.chainId,
811
852
  });
812
853
  return {
813
854
  total0: totalAmounts[0],
@@ -816,7 +857,7 @@ export class ExecutionApp extends ExecutionBase {
816
857
  }
817
858
  async getVaultPoolAddress() {
818
859
  const requestSnapshot = {
819
- method: 'POST',
860
+ method: "POST",
820
861
  url: this.steerSubgraph,
821
862
  data: {
822
863
  query: `
@@ -829,10 +870,12 @@ export class ExecutionApp extends ExecutionBase {
829
870
  `,
830
871
  },
831
872
  headers: {
832
- 'Content-Type': !this.steerSubgraph.includes('subgraph-proxy-server')
833
- ? 'application/json'
834
- : 'text/plain;charset=UTF-8',
835
- ...(this.steerSubgraph.includes('sentio') ? { 'api-key': this.sentioApiKey } : {}),
873
+ "Content-Type": !this.steerSubgraph.includes("subgraph-proxy-server")
874
+ ? "application/json"
875
+ : "text/plain;charset=UTF-8",
876
+ ...(this.steerSubgraph.includes("sentio")
877
+ ? { "api-key": this.sentioApiKey }
878
+ : {}),
836
879
  },
837
880
  };
838
881
  const response = await fetchData(requestSnapshot, 4);