@steerprotocol/data-connector-loader 4.1.0 → 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 (51) hide show
  1. package/README.md +136 -20
  2. package/lib/bundle/bundleBase.d.ts +11 -14
  3. package/lib/bundle/bundleBase.js +58 -90
  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 +79 -93
  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 +18 -17
  11. package/lib/esm/execution/executionApp.js +390 -370
  12. package/lib/esm/execution/executionBase.d.ts +6 -6
  13. package/lib/esm/execution/executionBase.js +27 -13
  14. package/lib/esm/execution/executionDataConnector.d.ts +7 -4
  15. package/lib/esm/execution/executionDataConnector.js +143 -76
  16. package/lib/esm/index.d.ts +7 -7
  17. package/lib/esm/index.js +4 -4
  18. package/lib/esm/types.d.ts +23 -25
  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 +18 -17
  31. package/lib/execution/executionApp.js +379 -364
  32. package/lib/execution/executionBase.d.ts +6 -6
  33. package/lib/execution/executionBase.js +27 -13
  34. package/lib/execution/executionDataConnector.d.ts +7 -4
  35. package/lib/execution/executionDataConnector.js +146 -71
  36. package/lib/index.d.ts +7 -7
  37. package/lib/index.js +1 -1
  38. package/lib/package.json +1 -0
  39. package/lib/types.d.ts +23 -25
  40. package/lib/types.js +5 -5
  41. package/lib/utils/blockFinder.d.ts +2 -2
  42. package/lib/utils/blockFinder.js +3 -3
  43. package/lib/utils/consts.js +39 -39
  44. package/lib/utils/pluginManager.d.ts +1 -1
  45. package/lib/utils/pluginManager.js +5 -4
  46. package/lib/utils/replace-old-subgraphs.js +79 -61
  47. package/lib/utils/rpc.d.ts +4 -0
  48. package/lib/utils/rpc.js +47 -0
  49. package/lib/utils/utils.d.ts +8 -11
  50. package/lib/utils/utils.js +55 -60
  51. package/package.json +22 -17
package/README.md CHANGED
@@ -22,37 +22,153 @@ pnpm add @steerprotocol/data-connector-loader
22
22
 
23
23
  This package publishes both CommonJS and ESM entrypoints via `exports`.
24
24
 
25
+ ## Prereleases
26
+
27
+ The `next` branch publishes prereleases under the npm `next` tag after CI passes.
28
+ The release workflow can also be run manually on `next` with `dry_run` enabled.
29
+ Versions are calculated from Git tags and conventional commits; a breaking
30
+ change must be marked as such for the first prerelease of a new major version.
31
+ The npm package must authorize `next-publish.yml` as a trusted publisher before
32
+ that workflow can publish.
33
+
34
+ ## CI checks
35
+
36
+ The shared `next-ci.yml` matrix verifies Node 22 and Node 24. Each job runs
37
+ `npm ci` (which builds CommonJS and ESM through `prepare`), tests, Biome,
38
+ and packed-consumer checks. Node 24 collects coverage during its test run;
39
+ coverage comments are posted on same-repository pull requests with write access.
40
+ Fork and Dependabot pull requests still run coverage without posting comments.
41
+
42
+ Pull requests and non-release branch pushes run the shared CI directly.
43
+ Pushes to `next` or `main` run it once through their release workflow, and
44
+ publishing waits for both Node jobs. The release workflow filenames remain
45
+ unchanged for npm trusted publishing. The packed-consumer check installs into
46
+ a fresh temporary directory while reusing npm's download cache.
47
+
25
48
  ## Block-pinned strategy execution (recommended)
26
49
 
27
- Resolve the vault context with `@steerprotocol/sdk` 3.3+ and pass its successful
28
- `VaultExecutionContext` straight to `executeWithContext`. This path makes no
29
- pool, vault, subgraph, latest-block, average-block-time, or wall-clock reads.
30
- Uniswap v3-compatible, Algebra Integral, Aerodrome CL, and normalized Uniswap
31
- v4 contexts are supported. PoolShark remains unsupported by the SDK context API.
50
+ Supply a resolved `SmartPoolExecutionContext` to `ExecutionApp.executeWithContext`.
51
+ Strategy entrypoints return the exact string `"continue"` when no action is needed,
52
+ or the decoded JSON result. Their generic `T` describes the complete JSON result
53
+ (an action object or array), and the return type is `Promise<T | "continue">`.
54
+ All other non-JSON output is rejected as `StrategyExecutionError`.
32
55
 
33
- ```ts
34
- import { ExecutionApp } from '@steerprotocol/data-connector-loader';
35
- import { getVaultExecutionContext } from '@steerprotocol/sdk';
56
+ The offline `strategyWasm.integration.test.ts` suite runs retained Liquid Arc and
57
+ Static Stable binaries through the loader, covering both `continue` and JSON
58
+ actions with supplied contexts. It checks binary hashes and runs with `npm test`
59
+ in CI. To run just these cases:
60
+
61
+ ```sh
62
+ npm test -- --runInBand strategyWasm.integration.test.ts
63
+ ```
64
+
65
+ For connectors, pass an `ExecutionContext` to `DataConnectorExecution.executeWithContext`.
66
+ `SmartPoolExecutionContext` extends `ExecutionContext`, so the same resolved
67
+ context can be used for both. Both contexts include the chain ID for comparison
68
+ against the execution configuration. This path does not resolve vault or pool
69
+ state or infer the block or execution time.
36
70
 
37
- const response = await getVaultExecutionContext({ publicClient, vaultAddress, blockNumber, epochTimestamp });
38
- if (!response.success || !response.data) throw new Error(response.error ?? 'Context resolution failed');
71
+ ```ts
72
+ import { DataConnectorExecution, ExecutionApp } from '@steerprotocol/data-connector-loader';
39
73
 
40
- const app = new ExecutionApp(legacyCompatibleConfig);
41
- const actions = await app.executeWithContext({
74
+ // context is a previously resolved SmartPoolExecutionContext.
75
+ const vaultConfig = JSON.stringify({
76
+ vaultAddress: context.vaultAddress,
77
+ anchorBlockNumber: context.blockNumber,
78
+ strategyConfigData: { epochLength: String(context.epochLength) },
79
+ });
80
+ const connectorOutputs = await new DataConnectorExecution(connectors).executeWithContext(vaultConfig, context);
81
+ const actions = await new ExecutionApp(executionAppConfig).executeWithContext({
42
82
  wasmFile: strategyWasmBytes,
43
- vaultConfig: JSON.stringify({ vaultAddress, anchorBlockNumber: Number(blockNumber), strategyConfigData: { epochLength: '3600' } }),
83
+ vaultConfig,
44
84
  data: connectorOutputs,
45
- executionContext: response.data,
85
+ executionContext: context,
46
86
  });
47
87
  ```
48
88
 
49
- `vaultConfig` must include `vaultAddress`, `anchorBlockNumber`, and
50
- `strategyConfigData.epochLength`. Positions are translated at the WASM boundary
51
- from SDK `lowerTick`/`upperTick`/`relativeWeight` to
52
- `startTick`/`endTick`/`weight`; totals remain decimal strings. If SDK reports no
53
- last execution, WASM receives `lastExecutionTime: 0` (deterministic, no
54
- wall-clock fallback). Errors are `ExecutionContextError`
89
+ Contexts must have matching vault, chain, block and epoch length values. Block
90
+ and timestamp fields are safe integer numbers, with `executionTimestamp` in
91
+ milliseconds and `epochTimestamp` in seconds. Positions use `startTick`,
92
+ `endTick`, and `weight`; totals remain decimal strings. The former stable SDK
93
+ `VaultExecutionContext` shape is not accepted by these entry points.
94
+ Callers migrating from that shape must supply the resolved chain ID and use
95
+ `SmartPoolExecutionContext` for strategies or `ExecutionContext` for connectors.
96
+ Connector execution supports both v1 request/response loops and v2 bundles.
97
+ The pinned path keeps contract reads on the supplied chain and block. A missing
98
+ version export selects v1; version and connector execution errors are propagated.
99
+ V1 connectors start with an empty response; v2 connectors execute without one.
100
+ Use a separate connector instance for each concurrent execution. A connector holds mutable WASM state and execution context, so sharing one across concurrent runs can produce incorrect results.
101
+ Errors are `ExecutionContextError`
55
102
  (`INVALID_EXECUTION_CONTEXT` or `EXECUTION_CONTEXT_MISMATCH`) and
56
103
  `StrategyExecutionError` (`STRATEGY_EXECUTION_ERROR`); neither is retryable
57
104
  until its input or strategy failure is corrected. External connector HTTP data
58
105
  remains external and unpinned.
106
+
107
+ ## vNext RPC configuration
108
+
109
+ The loader uses viem for RPC and ABI handling. Construct connectors with an
110
+ options object and either RPC URLs or an existing viem `PublicClient`:
111
+
112
+ ```ts
113
+ import { DataConnector } from '@steerprotocol/data-connector-loader';
114
+
115
+ const connector = new DataConnector({
116
+ wasmFile: connectorWasmBytes,
117
+ config: connectorConfigJson,
118
+ executionConfig: executionAppConfig,
119
+ rpc: { urls: ['https://your-primary-rpc', 'https://your-backup-rpc'] },
120
+ // Alternatively: rpc: { client: publicClient }
121
+ });
122
+ ```
123
+
124
+ URLs belong to `executionConfig.chainId`. The loader tries them in order and
125
+ checks each endpoint's chain before sending a read, including during failover.
126
+ This uses first-success failover, not ethers quorum voting. A supplied client
127
+ is chain-checked by the execution path; the caller owns its transport setup and
128
+ must ensure every endpoint in a custom fallback client serves that same chain.
129
+ RPC configuration can be omitted for connectors that make no chain reads.
130
+
131
+ This is a breaking TypeScript API change: the positional `DataConnector`
132
+ constructor, ethers provider argument, `EtherRpcConfig`, and `getProvider()`
133
+ are replaced by the options object, `RpcAccess`, and `getClient()`.
134
+ The older `ExecutionApp.execute`, `executeStabilityVault`, and `executeDynamicJobs`
135
+ methods accept one `rpc` argument in place of the old provider and RPC map
136
+ arguments; `forceDeposit` follows it. Supplied-context strategy execution needs
137
+ no RPC configuration.
138
+
139
+ Existing WASM exports and initialization payloads are unchanged. ABI responses
140
+ retain positional tuples, small integer numbers, and decimal strings for large
141
+ integers when serialized into WASM. JSON and human-readable ABIs are supported,
142
+ including the existing `tuple(...)` syntax and explicit overload signatures.
143
+ `@steerprotocol/app-loader` is unchanged and still brings ethers transitively.
144
+ The loader itself imports ethers only in tests as an ABI encoding reference.
145
+
146
+ ## Code quality system
147
+
148
+ We use [Biome](https://biomejs.dev/) with its recommended lint rules, formatter,
149
+ and import organization. `biome.json` is the shared configuration for local
150
+ commands, editors, and CI. The exact version is pinned in `package.json`.
151
+
152
+ The formatter uses Biome defaults (80-column preferred width, double quotes,
153
+ semicolons, and trailing commas), with two-space indentation matching
154
+ `.editorconfig`. There is no separate ESLint or Prettier configuration.
155
+
156
+ - `npm run fix`: apply formatting, import organization, and safe lint fixes.
157
+ - `npm run check:code`: verify all three without changing files, as CI does.
158
+ - `npm run check`: run code checks, both builds, and all tests.
159
+ - `npm run format` / `npm run format:check`: write/check formatting only.
160
+ - `npm run lint` / `npm run lint:fix`: check/apply safe lint fixes only.
161
+
162
+ Recommended lint errors, formatting differences, and import-order violations
163
+ block CI and publication. Existing recommended warnings remain visible and
164
+ advisory. Focused tests are errors; skipped tests are warnings. TypeScript
165
+ compilation and Jest remain separate checks: Biome is not a type checker or a
166
+ one-for-one replacement for every ESLint plugin rule.
167
+
168
+ Avoid blanket rule overrides or unsafe automatic fixes.
169
+
170
+ Checks cover source, tests, helpers, scripts, and root JSON/CommonJS config.
171
+ Generated files, dependencies, lockfiles, and WASM binaries are excluded.
172
+ Markdown and workflow YAML are outside this configuration's scope.
173
+ In VS Code, install the recommended Biome extension; workspace settings apply
174
+ formatting and import organization on save for JavaScript and TypeScript.
@@ -1,7 +1,7 @@
1
- import type { WasmModule } from '@steerprotocol/app-loader';
2
- import { ethers } from 'ethers';
3
- import type { ExecutionAppConfig } from '../execution/executionApp.js';
4
- import type { EtherRpcConfig, ExecutionContext } from '../types.js';
1
+ import type { WasmModule } from "@steerprotocol/app-loader";
2
+ import type { PublicClient } from "viem";
3
+ import type { ExecutionAppConfig } from "../execution/executionApp.js";
4
+ import type { DataConnectorOptions, ExecutionContext, RpcAccess } from "../types.js";
5
5
  export declare class BundleBase {
6
6
  module?: WasmModule;
7
7
  protected wasmFile: ArrayBuffer | string;
@@ -9,14 +9,11 @@ export declare class BundleBase {
9
9
  configObj: {
10
10
  [key: string]: any;
11
11
  };
12
- protected etherRpcConfig?: EtherRpcConfig;
13
- protected providerIdentity?: ethers.Provider;
14
- executionContext?: ExecutionContext & {
15
- epochTimestamp: number;
16
- };
17
- protected scheduleEpochTimestamp?: number;
12
+ protected rpc?: RpcAccess;
13
+ private rpcClient?;
14
+ executionContext?: ExecutionContext;
18
15
  executionAppConfig: ExecutionAppConfig;
19
- constructor(wasmFile: string | ArrayBuffer, _config: string, executionAppConfig: ExecutionAppConfig, identity?: ethers.Provider, etherRpcConfig?: EtherRpcConfig);
16
+ constructor({ wasmFile, config, executionConfig, rpc, }: DataConnectorOptions);
20
17
  load(): Promise<WasmModule>;
21
18
  loadSync(): WasmModule;
22
19
  execute(response?: string): Promise<string | null>;
@@ -29,13 +26,13 @@ export declare class BundleBase {
29
26
  * Initializes a strategy from an already resolved SDK context. Unlike the
30
27
  * legacy setter this deliberately does not derive a timestamp or block.
31
28
  */
32
- setExecutionContextStrategyExecutionPinned(executionContext: ExecutionContext, forceDeposit?: boolean): void;
29
+ initializeStrategyWithContext(executionContext: ExecutionContext, forceDeposit?: boolean): void;
33
30
  setExecutionContextDataConnector(executionContext: ExecutionContext): void;
34
31
  /** Initializes a data connector with an immutable SDK anchor. */
35
- setExecutionContextDataConnectorPinned(executionContext: ExecutionContext): void;
32
+ initializeDataConnectorWithContext(executionContext: ExecutionContext): void;
36
33
  protected executeModule(response: string): Promise<string | null>;
37
34
  protected executeModuleWithResult(...params: Array<number | string | ArrayBuffer | null>): Promise<string | null>;
38
- getProvider(config: any): ethers.Provider | undefined;
35
+ getClient(): PublicClient | undefined;
39
36
  getResults(): string;
40
37
  version(): number;
41
38
  private subtractDate;
@@ -11,43 +11,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BundleBase = void 0;
13
13
  const app_loader_1 = require("@steerprotocol/app-loader");
14
- const ethers_1 = require("ethers");
15
- const UNSTABLE_RPC_PATTERNS = [/drpc\.org/i];
16
- function createFallbackRpcProvider(urls) {
17
- const seen = new Set();
18
- const preferred = [];
19
- const deprioritized = [];
20
- for (const url of urls) {
21
- const trimmed = url.trim();
22
- if (trimmed.length === 0 || seen.has(trimmed)) {
23
- continue;
24
- }
25
- seen.add(trimmed);
26
- if (UNSTABLE_RPC_PATTERNS.some((pattern) => pattern.test(trimmed))) {
27
- deprioritized.push(trimmed);
28
- }
29
- else {
30
- preferred.push(trimmed);
31
- }
32
- }
33
- const prioritized = preferred.length > 0 ? [...preferred, ...deprioritized] : [...preferred, ...deprioritized];
34
- if (prioritized.length === 0) {
35
- throw new Error('No RPC URLs configured');
36
- }
37
- const providers = prioritized.map((url) => new ethers_1.ethers.JsonRpcProvider(url));
38
- return providers.length === 1 ? providers[0] : new ethers_1.ethers.FallbackProvider(providers);
39
- }
14
+ const rpc_js_1 = require("../utils/rpc.js");
40
15
  function bigIntReplacer(_key, value) {
41
- return typeof value === 'bigint' ? value.toString() : value;
16
+ return typeof value === "bigint" ? value.toString() : value;
42
17
  }
43
18
  class BundleBase {
44
- constructor(wasmFile, _config, executionAppConfig, identity, etherRpcConfig) {
19
+ constructor({ wasmFile, config, executionConfig, rpc, }) {
45
20
  this.wasmFile = wasmFile;
46
- this.config = _config;
47
- this.configObj = JSON.parse(_config);
48
- this.providerIdentity = identity;
49
- this.etherRpcConfig = etherRpcConfig;
50
- this.executionAppConfig = executionAppConfig;
21
+ this.config = config;
22
+ this.configObj = JSON.parse(config);
23
+ this.rpc = rpc;
24
+ this.executionAppConfig = executionConfig;
51
25
  }
52
26
  load() {
53
27
  return __awaiter(this, void 0, void 0, function* () {
@@ -58,8 +32,8 @@ class BundleBase {
58
32
  });
59
33
  }
60
34
  loadSync() {
61
- if (typeof this.wasmFile === 'string') {
62
- throw new Error('Cannot load module synchronously unless wasmFile is of type ArrayBuffer');
35
+ if (typeof this.wasmFile === "string") {
36
+ throw new Error("Cannot load module synchronously unless wasmFile is of type ArrayBuffer");
63
37
  }
64
38
  this.module = (0, app_loader_1.loadWasmSync)(this.wasmFile, {});
65
39
  return this.module;
@@ -67,7 +41,7 @@ class BundleBase {
67
41
  execute(response) {
68
42
  return __awaiter(this, void 0, void 0, function* () {
69
43
  if (!this.executionContext) {
70
- throw new Error('Execution context missing');
44
+ throw new Error("Execution context missing");
71
45
  }
72
46
  // If the module is not initialized, try to load it
73
47
  if (!this.module) {
@@ -75,20 +49,22 @@ class BundleBase {
75
49
  yield this.load();
76
50
  }
77
51
  catch (_a) {
78
- throw new Error('Module not initialized');
52
+ throw new Error("Module not initialized");
79
53
  }
80
54
  }
81
55
  // If the module is still not initialized, throw an error
82
56
  if (!this.module)
83
- throw new Error('Module not initialized');
84
- return response === undefined ? yield this.executeModuleWithResult() : yield this.executeModuleWithResult(response);
57
+ throw new Error("Module not initialized");
58
+ return response === undefined
59
+ ? yield this.executeModuleWithResult()
60
+ : yield this.executeModuleWithResult(response);
85
61
  });
86
62
  }
87
63
  // For dynamic job data connector
88
64
  transform() {
89
65
  return __awaiter(this, void 0, void 0, function* () {
90
66
  if (!this.executionContext) {
91
- throw new Error('Execution context missing');
67
+ throw new Error("Execution context missing");
92
68
  }
93
69
  // If the module is not initialized, try to load it
94
70
  if (!this.module) {
@@ -96,12 +72,12 @@ class BundleBase {
96
72
  yield this.load();
97
73
  }
98
74
  catch (_a) {
99
- throw new Error('Module not initialized');
75
+ throw new Error("Module not initialized");
100
76
  }
101
77
  }
102
78
  // If the module is still not initialized, throw an error
103
79
  if (!this.module)
104
- throw new Error('Module not initialized');
80
+ throw new Error("Module not initialized");
105
81
  // Call the main function with the response
106
82
  return yield this.module.transform();
107
83
  });
@@ -109,7 +85,7 @@ class BundleBase {
109
85
  executeBundle(data) {
110
86
  return __awaiter(this, void 0, void 0, function* () {
111
87
  if (!this.executionContext) {
112
- throw new Error('Execution context missing');
88
+ throw new Error("Execution context missing");
113
89
  }
114
90
  // If the module is not initialized, try to load it
115
91
  if (!this.module) {
@@ -117,15 +93,15 @@ class BundleBase {
117
93
  yield this.load();
118
94
  }
119
95
  catch (_a) {
120
- throw new Error('Module not initialized');
96
+ throw new Error("Module not initialized");
121
97
  }
122
98
  }
123
99
  // If the module is still not initialized, throw an error
124
100
  if (!this.module)
125
- throw new Error('Module not initialized');
101
+ throw new Error("Module not initialized");
126
102
  const result = yield this.executeModuleWithResult(...data);
127
103
  if (result === null) {
128
- throw new Error('Module execution returned null');
104
+ throw new Error("Module execution returned null");
129
105
  }
130
106
  return result;
131
107
  });
@@ -133,7 +109,7 @@ class BundleBase {
133
109
  executeDynamicJobBundle(data) {
134
110
  return __awaiter(this, void 0, void 0, function* () {
135
111
  if (!this.executionContext) {
136
- throw new Error('Execution context missing');
112
+ throw new Error("Execution context missing");
137
113
  }
138
114
  // If the module is not initialized, try to load it
139
115
  if (!this.module) {
@@ -141,51 +117,57 @@ class BundleBase {
141
117
  yield this.load();
142
118
  }
143
119
  catch (_a) {
144
- throw new Error('Module not initialized');
120
+ throw new Error("Module not initialized");
145
121
  }
146
122
  }
147
123
  // If the module is still not initialized, throw an error
148
124
  if (!this.module)
149
- throw new Error('Module not initialized');
125
+ throw new Error("Module not initialized");
150
126
  const result = yield this.executeModuleWithResult(...data);
151
127
  if (result === null) {
152
- throw new Error('Module execution returned null');
128
+ throw new Error("Module execution returned null");
153
129
  }
154
130
  return result;
155
131
  });
156
132
  }
157
133
  reset() {
158
- if (this.module && this.module['reset']) {
134
+ if (this.module && this.module["reset"]) {
159
135
  this.module.reset();
160
136
  }
161
137
  }
162
138
  setExecutionContextStrategyExecution(executionContext, forceDeposit) {
163
- var _a;
139
+ if (!this.module)
140
+ throw new Error("Module not initialized");
164
141
  // Determine the timestamp for epoch
165
142
  const timestamp = this.subtractDate(executionContext.executionTimestamp, Number(executionContext.epochLength)).getTime();
166
143
  // Divide milliseconds data to seconds for transformation bundle
167
144
  const timestampInSecs = Math.floor(timestamp / 1000);
168
145
  this.executionContext = Object.assign(Object.assign({}, executionContext), { epochTimestamp: timestampInSecs });
169
146
  const completeConfig = Object.assign(Object.assign({}, JSON.parse(this.config)), this.executionContext);
170
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
171
147
  if (completeConfig.triggerStyle && forceDeposit === true) {
172
- completeConfig.triggerStyle = 'None';
148
+ completeConfig.triggerStyle = "None";
149
+ }
150
+ if (this.module.initialize(JSON.stringify(completeConfig, bigIntReplacer)) ===
151
+ false) {
152
+ throw new Error("Strategy initialization failed");
173
153
  }
174
- (_a = this.module) === null || _a === void 0 ? void 0 : _a.initialize(JSON.stringify(completeConfig, bigIntReplacer));
175
154
  }
176
155
  /**
177
156
  * Initializes a strategy from an already resolved SDK context. Unlike the
178
157
  * legacy setter this deliberately does not derive a timestamp or block.
179
158
  */
180
- setExecutionContextStrategyExecutionPinned(executionContext, forceDeposit) {
181
- var _a;
159
+ initializeStrategyWithContext(executionContext, forceDeposit) {
160
+ if (!this.module)
161
+ throw new Error("Module not initialized");
182
162
  this.executionContext = executionContext;
183
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
184
163
  const completeConfig = Object.assign(Object.assign({}, JSON.parse(this.config)), executionContext);
185
164
  if (completeConfig.triggerStyle && forceDeposit === true) {
186
- completeConfig.triggerStyle = 'None';
165
+ completeConfig.triggerStyle = "None";
166
+ }
167
+ if (this.module.initialize(JSON.stringify(completeConfig, bigIntReplacer)) ===
168
+ false) {
169
+ throw new Error("Strategy initialization failed");
187
170
  }
188
- (_a = this.module) === null || _a === void 0 ? void 0 : _a.initialize(JSON.stringify(completeConfig, bigIntReplacer));
189
171
  }
190
172
  setExecutionContextDataConnector(executionContext) {
191
173
  var _a;
@@ -195,21 +177,23 @@ class BundleBase {
195
177
  const timestampInSecs = Math.floor(timestamp / 1000);
196
178
  this.executionContext = Object.assign(Object.assign({}, executionContext), { epochTimestamp: timestampInSecs });
197
179
  const completeConfig = Object.assign(Object.assign({}, JSON.parse(this.config)), { executionContext: this.executionContext });
198
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
199
180
  (_a = this.module) === null || _a === void 0 ? void 0 : _a.initialize(JSON.stringify(completeConfig, bigIntReplacer));
200
181
  }
201
182
  /** Initializes a data connector with an immutable SDK anchor. */
202
- setExecutionContextDataConnectorPinned(executionContext) {
203
- var _a;
183
+ initializeDataConnectorWithContext(executionContext) {
184
+ if (!this.module)
185
+ throw new Error("Module not initialized");
204
186
  this.executionContext = executionContext;
205
- this.scheduleEpochTimestamp = executionContext.epochTimestamp;
206
187
  const completeConfig = Object.assign(Object.assign({}, JSON.parse(this.config)), { executionContext });
207
- (_a = this.module) === null || _a === void 0 ? void 0 : _a.initialize(JSON.stringify(completeConfig, bigIntReplacer));
188
+ if (this.module.initialize(JSON.stringify(completeConfig, bigIntReplacer)) ===
189
+ false) {
190
+ throw new Error("Data connector initialization failed");
191
+ }
208
192
  }
209
193
  executeModule(response) {
210
194
  return __awaiter(this, void 0, void 0, function* () {
211
195
  if (!this.module) {
212
- throw new Error('Module not initialized');
196
+ throw new Error("Module not initialized");
213
197
  }
214
198
  return yield this.executeModuleWithResult(response);
215
199
  });
@@ -217,42 +201,26 @@ class BundleBase {
217
201
  executeModuleWithResult(...params) {
218
202
  return __awaiter(this, void 0, void 0, function* () {
219
203
  if (!this.module) {
220
- throw new Error('Module not initialized');
204
+ throw new Error("Module not initialized");
221
205
  }
222
206
  return yield this.module.execute(...params);
223
207
  });
224
208
  }
225
- // This function returns a provider based on the chainId of the request
226
- // The chainId is first checked in the data connector config, and if not found
227
- // it is checked in the request config. If the chainId is found in either of
228
- // these places, the provider is returned from the etherRpcConfig object
229
- getProvider(config) {
209
+ getClient() {
230
210
  var _a;
231
- let chainId;
232
- // check if chainId is configured in data connector config
233
- if (this.configObj.chainId) {
234
- chainId = this.configObj.chainId;
235
- }
236
- else if (config && config.chainId) {
237
- // if chainId is in the request config from dataconnector execution
238
- chainId = config.chainId;
239
- }
240
- if (chainId && this.etherRpcConfig && this.etherRpcConfig[chainId]) {
241
- const rpcConfig = this.etherRpcConfig[chainId];
242
- return createFallbackRpcProvider((_a = rpcConfig.urls) !== null && _a !== void 0 ? _a : [rpcConfig.url]);
243
- }
244
- else {
245
- return this.providerIdentity;
246
- }
211
+ if (!this.rpc)
212
+ return undefined;
213
+ (_a = this.rpcClient) !== null && _a !== void 0 ? _a : (this.rpcClient = (0, rpc_js_1.createRpcClient)(this.rpc, this.executionAppConfig.chainId));
214
+ return this.rpcClient;
247
215
  }
248
216
  getResults() {
249
217
  if (!this.module)
250
- throw new Error('Module not initialized');
218
+ throw new Error("Module not initialized");
251
219
  return this.module.transform();
252
220
  }
253
221
  version() {
254
222
  if (!this.module)
255
- throw new Error('Module not initialized');
223
+ throw new Error("Module not initialized");
256
224
  return Number(this.module.version());
257
225
  }
258
226
  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
  }
@@ -10,62 +10,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.DataConnector = void 0;
13
- const ethers_1 = require("ethers");
14
- const consts_js_1 = require("../utils/consts.js");
15
13
  const utils_js_1 = require("../utils/utils.js");
16
14
  const bundleBase_js_1 = require("./bundleBase.js");
17
15
  class DataConnector extends bundleBase_js_1.BundleBase {
18
- // Identity should come from the node's IdentityManager.wallet
19
- constructor(wasmFile, _config, executionAppConfig, identity, etherRpcConfig) {
20
- super(wasmFile, _config, executionAppConfig, identity, etherRpcConfig);
21
- }
22
- // get rpc url from configuration
23
- getRpcUrl(config) {
24
- let chainId;
25
- // check if chainId is configured in data connector config
26
- if (this.configObj.chainId) {
27
- chainId = this.configObj.chainId;
28
- }
29
- else if (config && config.chainId) {
30
- // if chainId is in the request config from dataconnector execution
31
- chainId = config.chainId;
32
- }
33
- if (chainId && this.etherRpcConfig && this.etherRpcConfig[chainId]) {
34
- return this.etherRpcConfig[chainId].url;
35
- }
36
- else {
37
- return undefined;
38
- }
39
- }
40
16
  // Makes contract instance and calls, returns stringified result
41
17
  view(config) {
42
18
  var _a, _b;
43
19
  return __awaiter(this, void 0, void 0, function* () {
44
- const provider = this.getProvider(config);
45
- if (!provider)
46
- throw new Error('Provider not initialized');
47
- const contract = new ethers_1.Contract(config.address, config.abi, provider);
48
- const paramsArray = config.arguments;
49
- let result;
50
- if (consts_js_1.CENTRALIZE_CONTRACT_INTERACTION_CHAINS.indexOf(this.configObj.chainId.toString()) === -1) {
51
- result = yield contract[config.method](...paramsArray, {
52
- blockTag: (_a = this.executionContext) === null || _a === void 0 ? void 0 : _a.blockNumber,
53
- });
20
+ const executionContext = this.executionContext && Object.assign({}, this.executionContext);
21
+ const pinnedChainId = executionContext === null || executionContext === void 0 ? void 0 : executionContext.chainId;
22
+ const chainId = (_b = (_a = this.configObj.chainId) !== null && _a !== void 0 ? _a : config.chainId) !== null && _b !== void 0 ? _b : pinnedChainId;
23
+ if (pinnedChainId !== undefined &&
24
+ ((chainId !== undefined && Number(chainId) !== pinnedChainId) ||
25
+ (config.chainId !== undefined &&
26
+ Number(config.chainId) !== pinnedChainId))) {
27
+ throw new Error("EXECUTION_CONTEXT_MISMATCH: contract request chain does not match supplied context.");
54
28
  }
55
- else {
56
- const viewContractConfig = {
57
- epochTimestamp: this.scheduleEpochTimestamp,
58
- blockNumber: (_b = this.executionContext) === null || _b === void 0 ? void 0 : _b.blockNumber,
59
- address: this.configObj.address || config.address,
60
- abi: config.abi,
61
- arguments: paramsArray,
62
- method: config.method,
63
- rpcUrl: this.getRpcUrl(config),
64
- };
65
- result = yield (0, utils_js_1.callWithRetry)(viewContractConfig);
29
+ const provider = this.getClient();
30
+ if (!provider)
31
+ throw new Error("Provider not initialized");
32
+ if (pinnedChainId !== undefined &&
33
+ (yield provider.getChainId()) !== pinnedChainId) {
34
+ throw new Error("EXECUTION_CONTEXT_MISMATCH: provider chain does not match supplied context.");
66
35
  }
67
- // This gets stringified before calling main
68
- return result;
36
+ return (0, utils_js_1.readContract)({
37
+ address: config.address,
38
+ abi: config.abi,
39
+ functionName: config.method,
40
+ contractArguments: config.arguments,
41
+ provider,
42
+ currentExecutionContext: executionContext,
43
+ });
69
44
  });
70
45
  }
71
46
  }