@steerprotocol/data-connector-loader 5.0.0-next.1 → 5.0.0-next.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 (50) hide show
  1. package/README.md +74 -0
  2. package/lib/bundle/bundleBase.d.ts +11 -14
  3. package/lib/bundle/bundleBase.js +44 -84
  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 +65 -89
  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 +5 -6
  11. package/lib/esm/execution/executionApp.js +335 -309
  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 +114 -68
  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 +61 -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 +5 -6
  31. package/lib/execution/executionApp.js +323 -302
  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 +116 -63
  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 +61 -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 +14 -14
@@ -1,41 +1,15 @@
1
- import { loadWasm, loadWasmSync } from '@steerprotocol/app-loader';
2
- import { ethers } from 'ethers';
3
- const UNSTABLE_RPC_PATTERNS = [/drpc\.org/i];
4
- function createFallbackRpcProvider(urls) {
5
- const seen = new Set();
6
- const preferred = [];
7
- const deprioritized = [];
8
- for (const url of urls) {
9
- const trimmed = url.trim();
10
- if (trimmed.length === 0 || seen.has(trimmed)) {
11
- continue;
12
- }
13
- seen.add(trimmed);
14
- if (UNSTABLE_RPC_PATTERNS.some((pattern) => pattern.test(trimmed))) {
15
- deprioritized.push(trimmed);
16
- }
17
- else {
18
- preferred.push(trimmed);
19
- }
20
- }
21
- const prioritized = preferred.length > 0 ? [...preferred, ...deprioritized] : [...preferred, ...deprioritized];
22
- if (prioritized.length === 0) {
23
- throw new Error('No RPC URLs configured');
24
- }
25
- const providers = prioritized.map((url) => new ethers.JsonRpcProvider(url));
26
- return providers.length === 1 ? providers[0] : new ethers.FallbackProvider(providers);
27
- }
1
+ import { loadWasm, loadWasmSync } from "@steerprotocol/app-loader";
2
+ import { createRpcClient } from "../utils/rpc.js";
28
3
  function bigIntReplacer(_key, value) {
29
- return typeof value === 'bigint' ? value.toString() : value;
4
+ return typeof value === "bigint" ? value.toString() : value;
30
5
  }
31
6
  export class BundleBase {
32
- constructor(wasmFile, _config, executionAppConfig, identity, etherRpcConfig) {
7
+ constructor({ wasmFile, config, executionConfig, rpc, }) {
33
8
  this.wasmFile = wasmFile;
34
- this.config = _config;
35
- this.configObj = JSON.parse(_config);
36
- this.providerIdentity = identity;
37
- this.etherRpcConfig = etherRpcConfig;
38
- this.executionAppConfig = executionAppConfig;
9
+ this.config = config;
10
+ this.configObj = JSON.parse(config);
11
+ this.rpc = rpc;
12
+ this.executionAppConfig = executionConfig;
39
13
  }
40
14
  async load() {
41
15
  const instance = await loadWasm(this.wasmFile, {});
@@ -44,15 +18,15 @@ export class BundleBase {
44
18
  return this.module;
45
19
  }
46
20
  loadSync() {
47
- if (typeof this.wasmFile === 'string') {
48
- throw new Error('Cannot load module synchronously unless wasmFile is of type ArrayBuffer');
21
+ if (typeof this.wasmFile === "string") {
22
+ throw new Error("Cannot load module synchronously unless wasmFile is of type ArrayBuffer");
49
23
  }
50
24
  this.module = loadWasmSync(this.wasmFile, {});
51
25
  return this.module;
52
26
  }
53
27
  async execute(response) {
54
28
  if (!this.executionContext) {
55
- throw new Error('Execution context missing');
29
+ throw new Error("Execution context missing");
56
30
  }
57
31
  // If the module is not initialized, try to load it
58
32
  if (!this.module) {
@@ -60,18 +34,20 @@ export class BundleBase {
60
34
  await this.load();
61
35
  }
62
36
  catch {
63
- throw new Error('Module not initialized');
37
+ throw new Error("Module not initialized");
64
38
  }
65
39
  }
66
40
  // If the module is still not initialized, throw an error
67
41
  if (!this.module)
68
- throw new Error('Module not initialized');
69
- return response === undefined ? await this.executeModuleWithResult() : await this.executeModuleWithResult(response);
42
+ throw new Error("Module not initialized");
43
+ return response === undefined
44
+ ? await this.executeModuleWithResult()
45
+ : await this.executeModuleWithResult(response);
70
46
  }
71
47
  // For dynamic job data connector
72
48
  async transform() {
73
49
  if (!this.executionContext) {
74
- throw new Error('Execution context missing');
50
+ throw new Error("Execution context missing");
75
51
  }
76
52
  // If the module is not initialized, try to load it
77
53
  if (!this.module) {
@@ -79,18 +55,18 @@ export class BundleBase {
79
55
  await this.load();
80
56
  }
81
57
  catch {
82
- throw new Error('Module not initialized');
58
+ throw new Error("Module not initialized");
83
59
  }
84
60
  }
85
61
  // If the module is still not initialized, throw an error
86
62
  if (!this.module)
87
- throw new Error('Module not initialized');
63
+ throw new Error("Module not initialized");
88
64
  // Call the main function with the response
89
65
  return await this.module.transform();
90
66
  }
91
67
  async executeBundle(data) {
92
68
  if (!this.executionContext) {
93
- throw new Error('Execution context missing');
69
+ throw new Error("Execution context missing");
94
70
  }
95
71
  // If the module is not initialized, try to load it
96
72
  if (!this.module) {
@@ -98,21 +74,21 @@ export class BundleBase {
98
74
  await this.load();
99
75
  }
100
76
  catch {
101
- throw new Error('Module not initialized');
77
+ throw new Error("Module not initialized");
102
78
  }
103
79
  }
104
80
  // If the module is still not initialized, throw an error
105
81
  if (!this.module)
106
- throw new Error('Module not initialized');
82
+ throw new Error("Module not initialized");
107
83
  const result = await this.executeModuleWithResult(...data);
108
84
  if (result === null) {
109
- throw new Error('Module execution returned null');
85
+ throw new Error("Module execution returned null");
110
86
  }
111
87
  return result;
112
88
  }
113
89
  async executeDynamicJobBundle(data) {
114
90
  if (!this.executionContext) {
115
- throw new Error('Execution context missing');
91
+ throw new Error("Execution context missing");
116
92
  }
117
93
  // If the module is not initialized, try to load it
118
94
  if (!this.module) {
@@ -120,20 +96,20 @@ export class BundleBase {
120
96
  await this.load();
121
97
  }
122
98
  catch {
123
- throw new Error('Module not initialized');
99
+ throw new Error("Module not initialized");
124
100
  }
125
101
  }
126
102
  // If the module is still not initialized, throw an error
127
103
  if (!this.module)
128
- throw new Error('Module not initialized');
104
+ throw new Error("Module not initialized");
129
105
  const result = await this.executeModuleWithResult(...data);
130
106
  if (result === null) {
131
- throw new Error('Module execution returned null');
107
+ throw new Error("Module execution returned null");
132
108
  }
133
109
  return result;
134
110
  }
135
111
  reset() {
136
- if (this.module && this.module['reset']) {
112
+ if (this.module && this.module["reset"]) {
137
113
  this.module.reset();
138
114
  }
139
115
  }
@@ -142,11 +118,16 @@ export class BundleBase {
142
118
  const timestamp = this.subtractDate(executionContext.executionTimestamp, Number(executionContext.epochLength)).getTime();
143
119
  // Divide milliseconds data to seconds for transformation bundle
144
120
  const timestampInSecs = Math.floor(timestamp / 1000);
145
- this.executionContext = { ...executionContext, epochTimestamp: timestampInSecs };
146
- const completeConfig = { ...JSON.parse(this.config), ...this.executionContext };
147
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
121
+ this.executionContext = {
122
+ ...executionContext,
123
+ epochTimestamp: timestampInSecs,
124
+ };
125
+ const completeConfig = {
126
+ ...JSON.parse(this.config),
127
+ ...this.executionContext,
128
+ };
148
129
  if (completeConfig.triggerStyle && forceDeposit === true) {
149
- completeConfig.triggerStyle = 'None';
130
+ completeConfig.triggerStyle = "None";
150
131
  }
151
132
  this.module?.initialize(JSON.stringify(completeConfig, bigIntReplacer));
152
133
  }
@@ -156,10 +137,12 @@ export class BundleBase {
156
137
  */
157
138
  initializeStrategyWithContext(executionContext, forceDeposit) {
158
139
  this.executionContext = executionContext;
159
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
160
- const completeConfig = { ...JSON.parse(this.config), ...executionContext };
140
+ const completeConfig = {
141
+ ...JSON.parse(this.config),
142
+ ...executionContext,
143
+ };
161
144
  if (completeConfig.triggerStyle && forceDeposit === true) {
162
- completeConfig.triggerStyle = 'None';
145
+ completeConfig.triggerStyle = "None";
163
146
  }
164
147
  this.module?.initialize(JSON.stringify(completeConfig, bigIntReplacer));
165
148
  }
@@ -168,60 +151,53 @@ export class BundleBase {
168
151
  const timestamp = this.subtractDate(executionContext.executionTimestamp, Number(executionContext.epochLength)).getTime();
169
152
  // Divide milliseconds data to seconds for transformation bundle
170
153
  const timestampInSecs = Math.floor(timestamp / 1000);
171
- this.executionContext = { ...executionContext, epochTimestamp: timestampInSecs };
172
- const completeConfig = { ...JSON.parse(this.config), executionContext: this.executionContext };
173
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
154
+ this.executionContext = {
155
+ ...executionContext,
156
+ epochTimestamp: timestampInSecs,
157
+ };
158
+ const completeConfig = {
159
+ ...JSON.parse(this.config),
160
+ executionContext: this.executionContext,
161
+ };
174
162
  this.module?.initialize(JSON.stringify(completeConfig, bigIntReplacer));
175
163
  }
176
164
  /** Initializes a data connector with an immutable SDK anchor. */
177
165
  initializeDataConnectorWithContext(executionContext) {
166
+ if (!this.module)
167
+ throw new Error("Module not initialized");
178
168
  this.executionContext = executionContext;
179
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
180
169
  const completeConfig = { ...JSON.parse(this.config), executionContext };
181
- this.module?.initialize(JSON.stringify(completeConfig, bigIntReplacer));
170
+ if (this.module.initialize(JSON.stringify(completeConfig, bigIntReplacer)) ===
171
+ false) {
172
+ throw new Error("Data connector initialization failed");
173
+ }
182
174
  }
183
175
  async executeModule(response) {
184
176
  if (!this.module) {
185
- throw new Error('Module not initialized');
177
+ throw new Error("Module not initialized");
186
178
  }
187
179
  return await this.executeModuleWithResult(response);
188
180
  }
189
181
  async executeModuleWithResult(...params) {
190
182
  if (!this.module) {
191
- throw new Error('Module not initialized');
183
+ throw new Error("Module not initialized");
192
184
  }
193
185
  return await this.module.execute(...params);
194
186
  }
195
- // This function returns a provider based on the chainId of the request
196
- // The chainId is first checked in the data connector config, and if not found
197
- // it is checked in the request config. If the chainId is found in either of
198
- // these places, the provider is returned from the etherRpcConfig object
199
- getProvider(config) {
200
- let chainId;
201
- // check if chainId is configured in data connector config
202
- if (this.configObj.chainId) {
203
- chainId = this.configObj.chainId;
204
- }
205
- else if (config && config.chainId) {
206
- // if chainId is in the request config from dataconnector execution
207
- chainId = config.chainId;
208
- }
209
- if (chainId && this.etherRpcConfig && this.etherRpcConfig[chainId]) {
210
- const rpcConfig = this.etherRpcConfig[chainId];
211
- return createFallbackRpcProvider(rpcConfig.urls ?? [rpcConfig.url]);
212
- }
213
- else {
214
- return this.providerIdentity;
215
- }
187
+ getClient() {
188
+ if (!this.rpc)
189
+ return undefined;
190
+ this.rpcClient ?? (this.rpcClient = createRpcClient(this.rpc, this.executionAppConfig.chainId));
191
+ return this.rpcClient;
216
192
  }
217
193
  getResults() {
218
194
  if (!this.module)
219
- throw new Error('Module not initialized');
195
+ throw new Error("Module not initialized");
220
196
  return this.module.transform();
221
197
  }
222
198
  version() {
223
199
  if (!this.module)
224
- throw new Error('Module not initialized');
200
+ throw new Error("Module not initialized");
225
201
  return Number(this.module.version());
226
202
  }
227
203
  subtractDate(timestamp, epochLength) {
@@ -1,9 +1,5 @@
1
- import type { ethers } from 'ethers';
2
- import type { ExecutionAppConfig } from '../execution/executionApp.js';
3
- import type { EtherRpcConfig, ViewConfig } from '../types.js';
4
- import { BundleBase } from './bundleBase.js';
1
+ import type { ViewConfig } from "../types.js";
2
+ import { BundleBase } from "./bundleBase.js";
5
3
  export declare class DataConnector extends BundleBase {
6
- constructor(wasmFile: string | ArrayBuffer, _config: string, executionAppConfig: ExecutionAppConfig, identity?: ethers.Provider, etherRpcConfig?: EtherRpcConfig);
7
- getRpcUrl(config: any): string | undefined;
8
4
  view(config: ViewConfig): Promise<string>;
9
5
  }
@@ -1,56 +1,33 @@
1
- import { Contract } from 'ethers';
2
- import { CENTRALIZE_CONTRACT_INTERACTION_CHAINS } from '../utils/consts.js';
3
- import { callWithRetry } from '../utils/utils.js';
4
- import { BundleBase } from './bundleBase.js';
1
+ import { readContract } from "../utils/utils.js";
2
+ import { BundleBase } from "./bundleBase.js";
5
3
  export class DataConnector extends BundleBase {
6
- // Identity should come from the node's IdentityManager.wallet
7
- constructor(wasmFile, _config, executionAppConfig, identity, etherRpcConfig) {
8
- super(wasmFile, _config, executionAppConfig, identity, etherRpcConfig);
9
- }
10
- // get rpc url from configuration
11
- getRpcUrl(config) {
12
- let chainId;
13
- // check if chainId is configured in data connector config
14
- if (this.configObj.chainId) {
15
- chainId = this.configObj.chainId;
16
- }
17
- else if (config && config.chainId) {
18
- // if chainId is in the request config from dataconnector execution
19
- chainId = config.chainId;
20
- }
21
- if (chainId && this.etherRpcConfig && this.etherRpcConfig[chainId]) {
22
- return this.etherRpcConfig[chainId].url;
23
- }
24
- else {
25
- return undefined;
26
- }
27
- }
28
4
  // Makes contract instance and calls, returns stringified result
29
5
  async view(config) {
30
- const provider = this.getProvider(config);
31
- if (!provider)
32
- throw new Error('Provider not initialized');
33
- const contract = new Contract(config.address, config.abi, provider);
34
- const paramsArray = config.arguments;
35
- let result;
36
- if (CENTRALIZE_CONTRACT_INTERACTION_CHAINS.indexOf(this.configObj.chainId.toString()) === -1) {
37
- result = await contract[config.method](...paramsArray, {
38
- blockTag: this.executionContext?.blockNumber,
39
- });
6
+ const executionContext = this.executionContext && {
7
+ ...this.executionContext,
8
+ };
9
+ const pinnedChainId = executionContext?.chainId;
10
+ const chainId = this.configObj.chainId ?? config.chainId ?? pinnedChainId;
11
+ if (pinnedChainId !== undefined &&
12
+ ((chainId !== undefined && Number(chainId) !== pinnedChainId) ||
13
+ (config.chainId !== undefined &&
14
+ Number(config.chainId) !== pinnedChainId))) {
15
+ throw new Error("EXECUTION_CONTEXT_MISMATCH: contract request chain does not match supplied context.");
40
16
  }
41
- else {
42
- const viewContractConfig = {
43
- epochTimestamp: this.scheduleEpochTimestamp,
44
- blockNumber: this.executionContext?.blockNumber,
45
- address: this.configObj.address || config.address,
46
- abi: config.abi,
47
- arguments: paramsArray,
48
- method: config.method,
49
- rpcUrl: this.getRpcUrl(config),
50
- };
51
- result = await callWithRetry(viewContractConfig);
17
+ const provider = this.getClient();
18
+ if (!provider)
19
+ throw new Error("Provider not initialized");
20
+ if (pinnedChainId !== undefined &&
21
+ (await provider.getChainId()) !== pinnedChainId) {
22
+ throw new Error("EXECUTION_CONTEXT_MISMATCH: provider chain does not match supplied context.");
52
23
  }
53
- // This gets stringified before calling main
54
- return result;
24
+ return readContract({
25
+ address: config.address,
26
+ abi: config.abi,
27
+ functionName: config.method,
28
+ contractArguments: config.arguments,
29
+ provider,
30
+ currentExecutionContext: executionContext,
31
+ });
55
32
  }
56
33
  }
@@ -1,6 +1,5 @@
1
- import type { ethers } from 'ethers';
2
- import type { EtherRpcConfig, ExecuteWithContextOptions, JobDetails } from '../types.js';
3
- import { ExecutionBase } from './executionBase.js';
1
+ import type { ExecuteWithContextOptions, JobDetails, RpcAccess } from "../types.js";
2
+ import { ExecutionBase } from "./executionBase.js";
4
3
  export interface ExecutionAppConfig {
5
4
  /** Vault address used for execution context and subgraph queries. */
6
5
  vault: string;
@@ -42,7 +41,7 @@ export declare class ExecutionApp extends ExecutionBase {
42
41
  sentioApiKey: string;
43
42
  config: ExecutionAppConfig;
44
43
  constructor(config: ExecutionAppConfig);
45
- execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
44
+ execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, rpc?: RpcAccess, forceDeposit?: boolean): Promise<Array<T>>;
46
45
  /**
47
46
  * Executes a strategy against a supplied execution context.
48
47
  * This is the recommended API for new consumers. It intentionally bypasses
@@ -52,8 +51,8 @@ export declare class ExecutionApp extends ExecutionBase {
52
51
  private parseVaultConfig;
53
52
  private validateExecutionContext;
54
53
  private redactError;
55
- executeStabilityVault<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
56
- executeDynamicJobs<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
54
+ executeStabilityVault<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, rpc?: RpcAccess, forceDeposit?: boolean): Promise<Array<T>>;
55
+ executeDynamicJobs<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails, rpc?: RpcAccess, forceDeposit?: boolean): Promise<Array<T>>;
57
56
  private getSmartPoolExecutionContext;
58
57
  private getPoolCurrentTick;
59
58
  private getTickSpacing;