@steerprotocol/data-connector-loader 4.1.0 → 5.0.0-next.2
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.
- package/README.md +34 -20
- package/lib/bundle/bundleBase.d.ts +6 -6
- package/lib/bundle/bundleBase.js +2 -2
- package/lib/esm/bundle/bundleBase.d.ts +6 -6
- package/lib/esm/bundle/bundleBase.js +2 -2
- package/lib/esm/execution/executionApp.d.ts +2 -2
- package/lib/esm/execution/executionApp.js +36 -59
- package/lib/esm/execution/executionBase.d.ts +2 -2
- package/lib/esm/execution/executionDataConnector.d.ts +2 -2
- package/lib/esm/execution/executionDataConnector.js +20 -12
- package/lib/esm/types.d.ts +5 -3
- package/lib/esm/utils/utils.d.ts +2 -2
- package/lib/execution/executionApp.d.ts +2 -2
- package/lib/execution/executionApp.js +36 -59
- package/lib/execution/executionBase.d.ts +2 -2
- package/lib/execution/executionDataConnector.d.ts +2 -2
- package/lib/execution/executionDataConnector.js +21 -12
- package/lib/package.json +1 -0
- package/lib/types.d.ts +5 -3
- package/lib/utils/utils.d.ts +2 -2
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -22,36 +22,50 @@ 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
|
+
|
|
25
34
|
## Block-pinned strategy execution (recommended)
|
|
26
35
|
|
|
27
|
-
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
Supply a resolved `SmartPoolExecutionContext` to `ExecutionApp.executeWithContext`.
|
|
37
|
+
For connectors, pass an `ExecutionContext` to `DataConnectorExecution.executeWithContext`.
|
|
38
|
+
`SmartPoolExecutionContext` extends `ExecutionContext`, so the same resolved
|
|
39
|
+
context can be used for both. Both contexts include the chain ID for comparison
|
|
40
|
+
against the execution configuration. This path does not resolve vault or pool
|
|
41
|
+
state or infer the block or execution time.
|
|
32
42
|
|
|
33
43
|
```ts
|
|
34
|
-
import { ExecutionApp } from '@steerprotocol/data-connector-loader';
|
|
35
|
-
import { getVaultExecutionContext } from '@steerprotocol/sdk';
|
|
44
|
+
import { DataConnectorExecution, ExecutionApp } from '@steerprotocol/data-connector-loader';
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
// context is a previously resolved SmartPoolExecutionContext.
|
|
47
|
+
const vaultConfig = JSON.stringify({
|
|
48
|
+
vaultAddress: context.vaultAddress,
|
|
49
|
+
anchorBlockNumber: context.blockNumber,
|
|
50
|
+
strategyConfigData: { epochLength: String(context.epochLength) },
|
|
51
|
+
});
|
|
52
|
+
const connectorOutputs = await new DataConnectorExecution(connectors).executeWithContext(vaultConfig, context);
|
|
53
|
+
const actions = await new ExecutionApp(executionAppConfig).executeWithContext({
|
|
42
54
|
wasmFile: strategyWasmBytes,
|
|
43
|
-
vaultConfig
|
|
55
|
+
vaultConfig,
|
|
44
56
|
data: connectorOutputs,
|
|
45
|
-
executionContext:
|
|
57
|
+
executionContext: context,
|
|
46
58
|
});
|
|
47
59
|
```
|
|
48
60
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
Contexts must have matching vault, chain, block and epoch length values. Block
|
|
62
|
+
and timestamp fields are safe integer numbers, with `executionTimestamp` in
|
|
63
|
+
milliseconds and `epochTimestamp` in seconds. Positions use `startTick`,
|
|
64
|
+
`endTick`, and `weight`; totals remain decimal strings. The former stable SDK
|
|
65
|
+
`VaultExecutionContext` shape is not accepted by these entry points.
|
|
66
|
+
Callers migrating from that shape must supply the resolved chain ID and use
|
|
67
|
+
`SmartPoolExecutionContext` for strategies or `ExecutionContext` for connectors.
|
|
68
|
+
Errors are `ExecutionContextError`
|
|
55
69
|
(`INVALID_EXECUTION_CONTEXT` or `EXECUTION_CONTEXT_MISMATCH`) and
|
|
56
70
|
`StrategyExecutionError` (`STRATEGY_EXECUTION_ERROR`); neither is retryable
|
|
57
71
|
until its input or strategy failure is corrected. External connector HTTP data
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WasmModule } from '@steerprotocol/app-loader';
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import type { ExecutionAppConfig } from '../execution/executionApp.js';
|
|
4
|
-
import type { EtherRpcConfig, ExecutionContext } from '../types.js';
|
|
4
|
+
import type { EtherRpcConfig, ExecutionContext, LegacyExecutionContext } from '../types.js';
|
|
5
5
|
export declare class BundleBase {
|
|
6
6
|
module?: WasmModule;
|
|
7
7
|
protected wasmFile: ArrayBuffer | string;
|
|
@@ -11,7 +11,7 @@ export declare class BundleBase {
|
|
|
11
11
|
};
|
|
12
12
|
protected etherRpcConfig?: EtherRpcConfig;
|
|
13
13
|
protected providerIdentity?: ethers.Provider;
|
|
14
|
-
executionContext?:
|
|
14
|
+
executionContext?: LegacyExecutionContext & {
|
|
15
15
|
epochTimestamp: number;
|
|
16
16
|
};
|
|
17
17
|
protected scheduleEpochTimestamp?: number;
|
|
@@ -24,15 +24,15 @@ export declare class BundleBase {
|
|
|
24
24
|
executeBundle(data: Array<any>): Promise<string>;
|
|
25
25
|
executeDynamicJobBundle(data: Array<any>): Promise<string>;
|
|
26
26
|
reset(): void;
|
|
27
|
-
setExecutionContextStrategyExecution(executionContext:
|
|
27
|
+
setExecutionContextStrategyExecution(executionContext: LegacyExecutionContext, forceDeposit?: boolean): void;
|
|
28
28
|
/**
|
|
29
29
|
* Initializes a strategy from an already resolved SDK context. Unlike the
|
|
30
30
|
* legacy setter this deliberately does not derive a timestamp or block.
|
|
31
31
|
*/
|
|
32
|
-
|
|
33
|
-
setExecutionContextDataConnector(executionContext:
|
|
32
|
+
initializeStrategyWithContext(executionContext: ExecutionContext, forceDeposit?: boolean): void;
|
|
33
|
+
setExecutionContextDataConnector(executionContext: LegacyExecutionContext): void;
|
|
34
34
|
/** Initializes a data connector with an immutable SDK anchor. */
|
|
35
|
-
|
|
35
|
+
initializeDataConnectorWithContext(executionContext: ExecutionContext): void;
|
|
36
36
|
protected executeModule(response: string): Promise<string | null>;
|
|
37
37
|
protected executeModuleWithResult(...params: Array<number | string | ArrayBuffer | null>): Promise<string | null>;
|
|
38
38
|
getProvider(config: any): ethers.Provider | undefined;
|
package/lib/bundle/bundleBase.js
CHANGED
|
@@ -177,7 +177,7 @@ class BundleBase {
|
|
|
177
177
|
* Initializes a strategy from an already resolved SDK context. Unlike the
|
|
178
178
|
* legacy setter this deliberately does not derive a timestamp or block.
|
|
179
179
|
*/
|
|
180
|
-
|
|
180
|
+
initializeStrategyWithContext(executionContext, forceDeposit) {
|
|
181
181
|
var _a;
|
|
182
182
|
this.executionContext = executionContext;
|
|
183
183
|
this.scheduleEpochTimestamp = executionContext.epochTimestamp;
|
|
@@ -199,7 +199,7 @@ class BundleBase {
|
|
|
199
199
|
(_a = this.module) === null || _a === void 0 ? void 0 : _a.initialize(JSON.stringify(completeConfig, bigIntReplacer));
|
|
200
200
|
}
|
|
201
201
|
/** Initializes a data connector with an immutable SDK anchor. */
|
|
202
|
-
|
|
202
|
+
initializeDataConnectorWithContext(executionContext) {
|
|
203
203
|
var _a;
|
|
204
204
|
this.executionContext = executionContext;
|
|
205
205
|
this.scheduleEpochTimestamp = executionContext.epochTimestamp;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WasmModule } from '@steerprotocol/app-loader';
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import type { ExecutionAppConfig } from '../execution/executionApp.js';
|
|
4
|
-
import type { EtherRpcConfig, ExecutionContext } from '../types.js';
|
|
4
|
+
import type { EtherRpcConfig, ExecutionContext, LegacyExecutionContext } from '../types.js';
|
|
5
5
|
export declare class BundleBase {
|
|
6
6
|
module?: WasmModule;
|
|
7
7
|
protected wasmFile: ArrayBuffer | string;
|
|
@@ -11,7 +11,7 @@ export declare class BundleBase {
|
|
|
11
11
|
};
|
|
12
12
|
protected etherRpcConfig?: EtherRpcConfig;
|
|
13
13
|
protected providerIdentity?: ethers.Provider;
|
|
14
|
-
executionContext?:
|
|
14
|
+
executionContext?: LegacyExecutionContext & {
|
|
15
15
|
epochTimestamp: number;
|
|
16
16
|
};
|
|
17
17
|
protected scheduleEpochTimestamp?: number;
|
|
@@ -24,15 +24,15 @@ export declare class BundleBase {
|
|
|
24
24
|
executeBundle(data: Array<any>): Promise<string>;
|
|
25
25
|
executeDynamicJobBundle(data: Array<any>): Promise<string>;
|
|
26
26
|
reset(): void;
|
|
27
|
-
setExecutionContextStrategyExecution(executionContext:
|
|
27
|
+
setExecutionContextStrategyExecution(executionContext: LegacyExecutionContext, forceDeposit?: boolean): void;
|
|
28
28
|
/**
|
|
29
29
|
* Initializes a strategy from an already resolved SDK context. Unlike the
|
|
30
30
|
* legacy setter this deliberately does not derive a timestamp or block.
|
|
31
31
|
*/
|
|
32
|
-
|
|
33
|
-
setExecutionContextDataConnector(executionContext:
|
|
32
|
+
initializeStrategyWithContext(executionContext: ExecutionContext, forceDeposit?: boolean): void;
|
|
33
|
+
setExecutionContextDataConnector(executionContext: LegacyExecutionContext): void;
|
|
34
34
|
/** Initializes a data connector with an immutable SDK anchor. */
|
|
35
|
-
|
|
35
|
+
initializeDataConnectorWithContext(executionContext: ExecutionContext): void;
|
|
36
36
|
protected executeModule(response: string): Promise<string | null>;
|
|
37
37
|
protected executeModuleWithResult(...params: Array<number | string | ArrayBuffer | null>): Promise<string | null>;
|
|
38
38
|
getProvider(config: any): ethers.Provider | undefined;
|
|
@@ -154,7 +154,7 @@ export class BundleBase {
|
|
|
154
154
|
* Initializes a strategy from an already resolved SDK context. Unlike the
|
|
155
155
|
* legacy setter this deliberately does not derive a timestamp or block.
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
initializeStrategyWithContext(executionContext, forceDeposit) {
|
|
158
158
|
this.executionContext = executionContext;
|
|
159
159
|
this.scheduleEpochTimestamp = executionContext.epochTimestamp;
|
|
160
160
|
const completeConfig = { ...JSON.parse(this.config), ...executionContext };
|
|
@@ -174,7 +174,7 @@ export class BundleBase {
|
|
|
174
174
|
this.module?.initialize(JSON.stringify(completeConfig, bigIntReplacer));
|
|
175
175
|
}
|
|
176
176
|
/** Initializes a data connector with an immutable SDK anchor. */
|
|
177
|
-
|
|
177
|
+
initializeDataConnectorWithContext(executionContext) {
|
|
178
178
|
this.executionContext = executionContext;
|
|
179
179
|
this.scheduleEpochTimestamp = executionContext.epochTimestamp;
|
|
180
180
|
const completeConfig = { ...JSON.parse(this.config), executionContext };
|
|
@@ -44,13 +44,13 @@ export declare class ExecutionApp extends ExecutionBase {
|
|
|
44
44
|
constructor(config: ExecutionAppConfig);
|
|
45
45
|
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
46
46
|
/**
|
|
47
|
-
* Executes a strategy against
|
|
47
|
+
* Executes a strategy against a supplied execution context.
|
|
48
48
|
* This is the recommended API for new consumers. It intentionally bypasses
|
|
49
49
|
* all legacy vault, pool, subgraph, clock, and block-estimation reads.
|
|
50
50
|
*/
|
|
51
51
|
executeWithContext<T>(options: ExecuteWithContextOptions): Promise<Array<T>>;
|
|
52
52
|
private parseVaultConfig;
|
|
53
|
-
private
|
|
53
|
+
private validateExecutionContext;
|
|
54
54
|
private redactError;
|
|
55
55
|
executeStabilityVault<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
56
56
|
executeDynamicJobs<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
@@ -486,17 +486,18 @@ export class ExecutionApp extends ExecutionBase {
|
|
|
486
486
|
return JSON.parse(result);
|
|
487
487
|
}
|
|
488
488
|
/**
|
|
489
|
-
* Executes a strategy against
|
|
489
|
+
* Executes a strategy against a supplied execution context.
|
|
490
490
|
* This is the recommended API for new consumers. It intentionally bypasses
|
|
491
491
|
* all legacy vault, pool, subgraph, clock, and block-estimation reads.
|
|
492
492
|
*/
|
|
493
493
|
async executeWithContext(options) {
|
|
494
494
|
const vaultConfig = this.parseVaultConfig(options.vaultConfig);
|
|
495
|
-
const executionContext =
|
|
495
|
+
const executionContext = options.executionContext;
|
|
496
|
+
this.validateExecutionContext(executionContext, vaultConfig);
|
|
496
497
|
const dataConnector = new DataConnector(options.wasmFile, options.vaultConfig, this.config, options.identity, options.etherRpcConfig);
|
|
497
498
|
try {
|
|
498
499
|
await dataConnector.loadSync();
|
|
499
|
-
dataConnector.
|
|
500
|
+
dataConnector.initializeStrategyWithContext(executionContext, options.forceDeposit);
|
|
500
501
|
const result = await dataConnector.executeBundle(options.data.map((item) => JSON.stringify(item)));
|
|
501
502
|
return JSON.parse(result);
|
|
502
503
|
}
|
|
@@ -514,34 +515,32 @@ export class ExecutionApp extends ExecutionBase {
|
|
|
514
515
|
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'vaultConfig must be valid JSON.');
|
|
515
516
|
}
|
|
516
517
|
}
|
|
517
|
-
|
|
518
|
+
validateExecutionContext(context, vaultConfig) {
|
|
518
519
|
if (!context || typeof context !== 'object') {
|
|
519
|
-
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', '
|
|
520
|
+
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'An execution context is required.');
|
|
520
521
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
if (!Number.isInteger(context.chainId) ||
|
|
522
|
+
if (!Number.isSafeInteger(context.chainId) ||
|
|
523
|
+
!Number.isSafeInteger(context.blockNumber) ||
|
|
524
|
+
context.blockNumber < 0 ||
|
|
525
|
+
!Number.isSafeInteger(context.epochTimestamp) ||
|
|
526
|
+
context.epochTimestamp < 0 ||
|
|
527
|
+
!Number.isSafeInteger(context.executionTimestamp) ||
|
|
528
|
+
context.executionTimestamp < 0 ||
|
|
529
|
+
context.executionTimestamp !== context.epochTimestamp * 1000 ||
|
|
530
|
+
!Number.isFinite(context.epochLength) ||
|
|
531
|
+
!Number.isFinite(context.blockTime) ||
|
|
534
532
|
!Number.isInteger(context.currentTick) ||
|
|
535
|
-
!Number.isInteger(context.tickSpacing)
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
!/^\d+$/.test(context.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
533
|
+
!Number.isInteger(context.tickSpacing) ||
|
|
534
|
+
typeof context.vaultAddress !== 'string' ||
|
|
535
|
+
context.vaultAddress.length === 0 ||
|
|
536
|
+
typeof context.totalAmount0 !== 'string' ||
|
|
537
|
+
!/^\d+$/.test(context.totalAmount0) ||
|
|
538
|
+
typeof context.totalAmount1 !== 'string' ||
|
|
539
|
+
!/^\d+$/.test(context.totalAmount1) ||
|
|
540
|
+
!Array.isArray(context.positions) ||
|
|
541
|
+
!Number.isFinite(context.lastExecutionTime) ||
|
|
542
|
+
context.lastExecutionTime < 0) {
|
|
543
|
+
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context is malformed.');
|
|
545
544
|
}
|
|
546
545
|
const sameAddress = (left, right) => left?.toLowerCase() === right?.toLowerCase();
|
|
547
546
|
if (!sameAddress(this.vault, context.vaultAddress) ||
|
|
@@ -552,43 +551,21 @@ export class ExecutionApp extends ExecutionBase {
|
|
|
552
551
|
(vaultConfig.chainId !== undefined && Number(vaultConfig.chainId) !== context.chainId)) {
|
|
553
552
|
throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context chain does not match the execution request.');
|
|
554
553
|
}
|
|
555
|
-
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
554
|
+
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
555
|
+
String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
|
|
556
556
|
throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context block does not match anchorBlockNumber.');
|
|
557
557
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'vaultConfig.strategyConfigData.epochLength is required.');
|
|
558
|
+
if (Number(vaultConfig.strategyConfigData?.epochLength) !== context.epochLength) {
|
|
559
|
+
throw new ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context epoch length does not match vaultConfig.');
|
|
561
560
|
}
|
|
562
561
|
for (const position of context.positions) {
|
|
563
|
-
if (!
|
|
564
|
-
!Number.isInteger(position.
|
|
565
|
-
!Number.
|
|
566
|
-
|
|
562
|
+
if (!position ||
|
|
563
|
+
!Number.isInteger(position.startTick) ||
|
|
564
|
+
!Number.isInteger(position.endTick) ||
|
|
565
|
+
!Number.isFinite(position.weight)) {
|
|
566
|
+
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context contains an invalid position.');
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
|
-
// Null is deterministic: WASM receives zero elapsed seconds, never wall-clock time.
|
|
570
|
-
const lastExecutionTime = context.lastExecutionTimeSeconds === null ? 0 : Number(context.lastExecutionTimeSeconds);
|
|
571
|
-
if (!Number.isFinite(lastExecutionTime) || lastExecutionTime < 0) {
|
|
572
|
-
throw new ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'SDK execution context has invalid lastExecutionTimeSeconds.');
|
|
573
|
-
}
|
|
574
|
-
return {
|
|
575
|
-
executionTimestamp: Number(context.epochTimestamp) * 1000,
|
|
576
|
-
epochTimestamp: Number(context.epochTimestamp),
|
|
577
|
-
epochLength,
|
|
578
|
-
vaultAddress: context.vaultAddress,
|
|
579
|
-
blockTime: 0,
|
|
580
|
-
blockNumber: Number(context.blockNumber),
|
|
581
|
-
currentTick: context.currentTick,
|
|
582
|
-
tickSpacing: context.tickSpacing,
|
|
583
|
-
positions: context.positions.map(({ lowerTick, upperTick, relativeWeight }) => ({
|
|
584
|
-
startTick: lowerTick,
|
|
585
|
-
endTick: upperTick,
|
|
586
|
-
weight: relativeWeight,
|
|
587
|
-
})),
|
|
588
|
-
totalAmount0: context.totalAmount0,
|
|
589
|
-
totalAmount1: context.totalAmount1,
|
|
590
|
-
lastExecutionTime,
|
|
591
|
-
};
|
|
592
569
|
}
|
|
593
570
|
redactError(error) {
|
|
594
571
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { ethers } from 'ethers';
|
|
2
2
|
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
3
|
-
import type { EtherRpcConfig,
|
|
3
|
+
import type { EtherRpcConfig, LegacyExecutionContext, VaultConfigPayload } from '../types.js';
|
|
4
4
|
export declare class ExecutionBase {
|
|
5
5
|
maxRetries: number;
|
|
6
6
|
constructor(maxRetries?: number);
|
|
7
7
|
protected delay(ms: number): Promise<void>;
|
|
8
8
|
protected log(...args: Array<any>): void;
|
|
9
|
-
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<
|
|
9
|
+
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<LegacyExecutionContext>;
|
|
10
10
|
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig): Promise<Array<T>>;
|
|
11
11
|
protected getDataConnectorVersion(dataConnector: DataConnector): Promise<number>;
|
|
12
12
|
getAverageBlockTime(provider: ethers.Provider, blockCount?: number): Promise<number>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ExecutionContext } from '../types.js';
|
|
3
3
|
import { ExecutionBase } from './executionBase.js';
|
|
4
4
|
export declare class DataConnectorExecution extends ExecutionBase {
|
|
5
5
|
private dataConnectors;
|
|
@@ -10,7 +10,7 @@ export declare class DataConnectorExecution extends ExecutionBase {
|
|
|
10
10
|
* Chain reads receive its exact blockNumber; HTTP and subgraph responses are
|
|
11
11
|
* intentionally not represented as block-pinned data.
|
|
12
12
|
*/
|
|
13
|
-
executeWithContext<T>(_vaultConfig: string, context:
|
|
13
|
+
executeWithContext<T>(_vaultConfig: string, context: ExecutionContext): Promise<Array<T>>;
|
|
14
14
|
private executeV2Bundle;
|
|
15
15
|
executeDynamicJob<T>(_vaultConfig: string): Promise<Array<T>>;
|
|
16
16
|
private handleRequestResponse;
|
|
@@ -55,8 +55,20 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
55
55
|
*/
|
|
56
56
|
async executeWithContext(_vaultConfig, context) {
|
|
57
57
|
const vaultConfig = JSON.parse(_vaultConfig);
|
|
58
|
-
if (!context ||
|
|
59
|
-
|
|
58
|
+
if (!context ||
|
|
59
|
+
!Number.isSafeInteger(context.chainId) ||
|
|
60
|
+
!Number.isSafeInteger(context.blockNumber) ||
|
|
61
|
+
context.blockNumber < 0 ||
|
|
62
|
+
!Number.isSafeInteger(context.epochTimestamp) ||
|
|
63
|
+
context.epochTimestamp < 0 ||
|
|
64
|
+
!Number.isSafeInteger(context.executionTimestamp) ||
|
|
65
|
+
context.executionTimestamp < 0 ||
|
|
66
|
+
context.executionTimestamp !== context.epochTimestamp * 1000 ||
|
|
67
|
+
!Number.isFinite(context.epochLength) ||
|
|
68
|
+
!Number.isFinite(context.blockTime) ||
|
|
69
|
+
typeof context.vaultAddress !== 'string' ||
|
|
70
|
+
context.vaultAddress.length === 0) {
|
|
71
|
+
throw new Error('INVALID_EXECUTION_CONTEXT: supplied execution context is malformed.');
|
|
60
72
|
}
|
|
61
73
|
if (context.vaultAddress.toLowerCase() !== vaultConfig.vaultAddress.toLowerCase()) {
|
|
62
74
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context vault does not match vaultConfig.vaultAddress.');
|
|
@@ -65,17 +77,13 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
65
77
|
if (requestChainId !== undefined && requestChainId !== context.chainId) {
|
|
66
78
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context chain does not match vaultConfig.chainId.');
|
|
67
79
|
}
|
|
68
|
-
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
80
|
+
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
81
|
+
String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
|
|
69
82
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context block does not match anchorBlockNumber.');
|
|
70
83
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
epochLength: Number(vaultConfig.strategyConfigData.epochLength),
|
|
75
|
-
vaultAddress: context.vaultAddress,
|
|
76
|
-
blockTime: 0,
|
|
77
|
-
blockNumber: Number(context.blockNumber),
|
|
78
|
-
};
|
|
84
|
+
if (Number(vaultConfig.strategyConfigData?.epochLength) !== context.epochLength) {
|
|
85
|
+
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context epoch length does not match vaultConfig.');
|
|
86
|
+
}
|
|
79
87
|
const transformationData = [];
|
|
80
88
|
for (const dataConnector of this.dataConnectors) {
|
|
81
89
|
if (dataConnector.executionAppConfig.chainId !== context.chainId) {
|
|
@@ -83,7 +91,7 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
83
91
|
}
|
|
84
92
|
if (!dataConnector.module)
|
|
85
93
|
await dataConnector.load();
|
|
86
|
-
dataConnector.
|
|
94
|
+
dataConnector.initializeDataConnectorWithContext(context);
|
|
87
95
|
await dataConnector.execute();
|
|
88
96
|
transformationData.push(JSON.parse(await dataConnector.transform()));
|
|
89
97
|
}
|
package/lib/esm/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ethers, InterfaceAbi } from 'ethers';
|
|
2
|
-
import type { VaultExecutionContext } from '@steerprotocol/sdk';
|
|
3
2
|
/** Error raised before a strategy is invoked when its supplied SDK anchor is unusable. */
|
|
4
3
|
export declare class ExecutionContextError extends Error {
|
|
5
4
|
readonly code: 'INVALID_EXECUTION_CONTEXT' | 'EXECUTION_CONTEXT_MISMATCH';
|
|
@@ -20,8 +19,8 @@ export interface ExecuteWithContextOptions {
|
|
|
20
19
|
wasmFile: string | ArrayBuffer;
|
|
21
20
|
vaultConfig: string;
|
|
22
21
|
data: Array<unknown>;
|
|
23
|
-
/**
|
|
24
|
-
executionContext:
|
|
22
|
+
/** Resolved strategy execution context. */
|
|
23
|
+
executionContext: SmartPoolExecutionContext;
|
|
25
24
|
identity?: ethers.Provider;
|
|
26
25
|
etherRpcConfig?: EtherRpcConfig;
|
|
27
26
|
forceDeposit?: boolean;
|
|
@@ -77,6 +76,7 @@ export interface ConfigData {
|
|
|
77
76
|
[key: string]: string | number;
|
|
78
77
|
}
|
|
79
78
|
export interface ExecutionContext {
|
|
79
|
+
chainId: number;
|
|
80
80
|
executionTimestamp: number;
|
|
81
81
|
epochLength: number;
|
|
82
82
|
vaultAddress: string;
|
|
@@ -84,6 +84,8 @@ export interface ExecutionContext {
|
|
|
84
84
|
blockNumber: number;
|
|
85
85
|
epochTimestamp: number;
|
|
86
86
|
}
|
|
87
|
+
/** Context produced by legacy execution paths, which may not have a chain binding. */
|
|
88
|
+
export type LegacyExecutionContext = Omit<ExecutionContext, 'chainId'> & Partial<Pick<ExecutionContext, 'chainId'>>;
|
|
87
89
|
export interface Position {
|
|
88
90
|
startTick: number;
|
|
89
91
|
endTick: number;
|
package/lib/esm/utils/utils.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { Candle } from '@steerprotocol/app-loader';
|
|
2
2
|
import type { AxiosRequestConfig } from 'axios';
|
|
3
3
|
import { type Provider } from 'ethers';
|
|
4
|
-
import type {
|
|
4
|
+
import type { LegacyExecutionContext, ViewContractConfig } from '../types.js';
|
|
5
5
|
export declare const extendOHLCV: (rawData: Array<Candle>, period: number, endTimestamp: number) => Array<Candle>;
|
|
6
6
|
export declare function fetchData(request: AxiosRequestConfig, attempts: number): Promise<any>;
|
|
7
7
|
export declare function readContract({ abi, address, chainId, contractArguments, currentExecutionContext, functionName, provider, rpc, }: {
|
|
8
8
|
address: string;
|
|
9
9
|
abi: any;
|
|
10
|
-
currentExecutionContext:
|
|
10
|
+
currentExecutionContext: LegacyExecutionContext;
|
|
11
11
|
functionName: string;
|
|
12
12
|
provider: Provider;
|
|
13
13
|
rpc: string;
|
|
@@ -44,13 +44,13 @@ export declare class ExecutionApp extends ExecutionBase {
|
|
|
44
44
|
constructor(config: ExecutionAppConfig);
|
|
45
45
|
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
46
46
|
/**
|
|
47
|
-
* Executes a strategy against
|
|
47
|
+
* Executes a strategy against a supplied execution context.
|
|
48
48
|
* This is the recommended API for new consumers. It intentionally bypasses
|
|
49
49
|
* all legacy vault, pool, subgraph, clock, and block-estimation reads.
|
|
50
50
|
*/
|
|
51
51
|
executeWithContext<T>(options: ExecuteWithContextOptions): Promise<Array<T>>;
|
|
52
52
|
private parseVaultConfig;
|
|
53
|
-
private
|
|
53
|
+
private validateExecutionContext;
|
|
54
54
|
private redactError;
|
|
55
55
|
executeStabilityVault<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
56
56
|
executeDynamicJobs<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig, forceDeposit?: boolean): Promise<Array<T>>;
|
|
@@ -498,18 +498,19 @@ class ExecutionApp extends executionBase_js_1.ExecutionBase {
|
|
|
498
498
|
});
|
|
499
499
|
}
|
|
500
500
|
/**
|
|
501
|
-
* Executes a strategy against
|
|
501
|
+
* Executes a strategy against a supplied execution context.
|
|
502
502
|
* This is the recommended API for new consumers. It intentionally bypasses
|
|
503
503
|
* all legacy vault, pool, subgraph, clock, and block-estimation reads.
|
|
504
504
|
*/
|
|
505
505
|
executeWithContext(options) {
|
|
506
506
|
return __awaiter(this, void 0, void 0, function* () {
|
|
507
507
|
const vaultConfig = this.parseVaultConfig(options.vaultConfig);
|
|
508
|
-
const executionContext =
|
|
508
|
+
const executionContext = options.executionContext;
|
|
509
|
+
this.validateExecutionContext(executionContext, vaultConfig);
|
|
509
510
|
const dataConnector = new bundleDataConnector_js_1.DataConnector(options.wasmFile, options.vaultConfig, this.config, options.identity, options.etherRpcConfig);
|
|
510
511
|
try {
|
|
511
512
|
yield dataConnector.loadSync();
|
|
512
|
-
dataConnector.
|
|
513
|
+
dataConnector.initializeStrategyWithContext(executionContext, options.forceDeposit);
|
|
513
514
|
const result = yield dataConnector.executeBundle(options.data.map((item) => JSON.stringify(item)));
|
|
514
515
|
return JSON.parse(result);
|
|
515
516
|
}
|
|
@@ -528,35 +529,33 @@ class ExecutionApp extends executionBase_js_1.ExecutionBase {
|
|
|
528
529
|
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'vaultConfig must be valid JSON.');
|
|
529
530
|
}
|
|
530
531
|
}
|
|
531
|
-
|
|
532
|
+
validateExecutionContext(context, vaultConfig) {
|
|
532
533
|
var _a;
|
|
533
534
|
if (!context || typeof context !== 'object') {
|
|
534
|
-
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', '
|
|
535
|
+
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'An execution context is required.');
|
|
535
536
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
if (!Number.isInteger(context.chainId) ||
|
|
537
|
+
if (!Number.isSafeInteger(context.chainId) ||
|
|
538
|
+
!Number.isSafeInteger(context.blockNumber) ||
|
|
539
|
+
context.blockNumber < 0 ||
|
|
540
|
+
!Number.isSafeInteger(context.epochTimestamp) ||
|
|
541
|
+
context.epochTimestamp < 0 ||
|
|
542
|
+
!Number.isSafeInteger(context.executionTimestamp) ||
|
|
543
|
+
context.executionTimestamp < 0 ||
|
|
544
|
+
context.executionTimestamp !== context.epochTimestamp * 1000 ||
|
|
545
|
+
!Number.isFinite(context.epochLength) ||
|
|
546
|
+
!Number.isFinite(context.blockTime) ||
|
|
549
547
|
!Number.isInteger(context.currentTick) ||
|
|
550
|
-
!Number.isInteger(context.tickSpacing)
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
!/^\d+$/.test(context.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
548
|
+
!Number.isInteger(context.tickSpacing) ||
|
|
549
|
+
typeof context.vaultAddress !== 'string' ||
|
|
550
|
+
context.vaultAddress.length === 0 ||
|
|
551
|
+
typeof context.totalAmount0 !== 'string' ||
|
|
552
|
+
!/^\d+$/.test(context.totalAmount0) ||
|
|
553
|
+
typeof context.totalAmount1 !== 'string' ||
|
|
554
|
+
!/^\d+$/.test(context.totalAmount1) ||
|
|
555
|
+
!Array.isArray(context.positions) ||
|
|
556
|
+
!Number.isFinite(context.lastExecutionTime) ||
|
|
557
|
+
context.lastExecutionTime < 0) {
|
|
558
|
+
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context is malformed.');
|
|
560
559
|
}
|
|
561
560
|
const sameAddress = (left, right) => (left === null || left === void 0 ? void 0 : left.toLowerCase()) === (right === null || right === void 0 ? void 0 : right.toLowerCase());
|
|
562
561
|
if (!sameAddress(this.vault, context.vaultAddress) ||
|
|
@@ -567,43 +566,21 @@ class ExecutionApp extends executionBase_js_1.ExecutionBase {
|
|
|
567
566
|
(vaultConfig.chainId !== undefined && Number(vaultConfig.chainId) !== context.chainId)) {
|
|
568
567
|
throw new types_js_1.ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context chain does not match the execution request.');
|
|
569
568
|
}
|
|
570
|
-
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
569
|
+
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
570
|
+
String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
|
|
571
571
|
throw new types_js_1.ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context block does not match anchorBlockNumber.');
|
|
572
572
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'vaultConfig.strategyConfigData.epochLength is required.');
|
|
573
|
+
if (Number((_a = vaultConfig.strategyConfigData) === null || _a === void 0 ? void 0 : _a.epochLength) !== context.epochLength) {
|
|
574
|
+
throw new types_js_1.ExecutionContextError('EXECUTION_CONTEXT_MISMATCH', 'Supplied context epoch length does not match vaultConfig.');
|
|
576
575
|
}
|
|
577
576
|
for (const position of context.positions) {
|
|
578
|
-
if (!
|
|
579
|
-
!Number.isInteger(position.
|
|
580
|
-
!Number.
|
|
581
|
-
|
|
577
|
+
if (!position ||
|
|
578
|
+
!Number.isInteger(position.startTick) ||
|
|
579
|
+
!Number.isInteger(position.endTick) ||
|
|
580
|
+
!Number.isFinite(position.weight)) {
|
|
581
|
+
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'Execution context contains an invalid position.');
|
|
582
582
|
}
|
|
583
583
|
}
|
|
584
|
-
// Null is deterministic: WASM receives zero elapsed seconds, never wall-clock time.
|
|
585
|
-
const lastExecutionTime = context.lastExecutionTimeSeconds === null ? 0 : Number(context.lastExecutionTimeSeconds);
|
|
586
|
-
if (!Number.isFinite(lastExecutionTime) || lastExecutionTime < 0) {
|
|
587
|
-
throw new types_js_1.ExecutionContextError('INVALID_EXECUTION_CONTEXT', 'SDK execution context has invalid lastExecutionTimeSeconds.');
|
|
588
|
-
}
|
|
589
|
-
return {
|
|
590
|
-
executionTimestamp: Number(context.epochTimestamp) * 1000,
|
|
591
|
-
epochTimestamp: Number(context.epochTimestamp),
|
|
592
|
-
epochLength,
|
|
593
|
-
vaultAddress: context.vaultAddress,
|
|
594
|
-
blockTime: 0,
|
|
595
|
-
blockNumber: Number(context.blockNumber),
|
|
596
|
-
currentTick: context.currentTick,
|
|
597
|
-
tickSpacing: context.tickSpacing,
|
|
598
|
-
positions: context.positions.map(({ lowerTick, upperTick, relativeWeight }) => ({
|
|
599
|
-
startTick: lowerTick,
|
|
600
|
-
endTick: upperTick,
|
|
601
|
-
weight: relativeWeight,
|
|
602
|
-
})),
|
|
603
|
-
totalAmount0: context.totalAmount0,
|
|
604
|
-
totalAmount1: context.totalAmount1,
|
|
605
|
-
lastExecutionTime,
|
|
606
|
-
};
|
|
607
584
|
}
|
|
608
585
|
redactError(error) {
|
|
609
586
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { ethers } from 'ethers';
|
|
2
2
|
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
3
|
-
import type { EtherRpcConfig,
|
|
3
|
+
import type { EtherRpcConfig, LegacyExecutionContext, VaultConfigPayload } from '../types.js';
|
|
4
4
|
export declare class ExecutionBase {
|
|
5
5
|
maxRetries: number;
|
|
6
6
|
constructor(maxRetries?: number);
|
|
7
7
|
protected delay(ms: number): Promise<void>;
|
|
8
8
|
protected log(...args: Array<any>): void;
|
|
9
|
-
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<
|
|
9
|
+
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<LegacyExecutionContext>;
|
|
10
10
|
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig): Promise<Array<T>>;
|
|
11
11
|
protected getDataConnectorVersion(dataConnector: DataConnector): Promise<number>;
|
|
12
12
|
getAverageBlockTime(provider: ethers.Provider, blockCount?: number): Promise<number>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ExecutionContext } from '../types.js';
|
|
3
3
|
import { ExecutionBase } from './executionBase.js';
|
|
4
4
|
export declare class DataConnectorExecution extends ExecutionBase {
|
|
5
5
|
private dataConnectors;
|
|
@@ -10,7 +10,7 @@ export declare class DataConnectorExecution extends ExecutionBase {
|
|
|
10
10
|
* Chain reads receive its exact blockNumber; HTTP and subgraph responses are
|
|
11
11
|
* intentionally not represented as block-pinned data.
|
|
12
12
|
*/
|
|
13
|
-
executeWithContext<T>(_vaultConfig: string, context:
|
|
13
|
+
executeWithContext<T>(_vaultConfig: string, context: ExecutionContext): Promise<Array<T>>;
|
|
14
14
|
private executeV2Bundle;
|
|
15
15
|
executeDynamicJob<T>(_vaultConfig: string): Promise<Array<T>>;
|
|
16
16
|
private handleRequestResponse;
|
|
@@ -68,10 +68,23 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
68
68
|
* intentionally not represented as block-pinned data.
|
|
69
69
|
*/
|
|
70
70
|
executeWithContext(_vaultConfig, context) {
|
|
71
|
+
var _a;
|
|
71
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
72
73
|
const vaultConfig = JSON.parse(_vaultConfig);
|
|
73
|
-
if (!context ||
|
|
74
|
-
|
|
74
|
+
if (!context ||
|
|
75
|
+
!Number.isSafeInteger(context.chainId) ||
|
|
76
|
+
!Number.isSafeInteger(context.blockNumber) ||
|
|
77
|
+
context.blockNumber < 0 ||
|
|
78
|
+
!Number.isSafeInteger(context.epochTimestamp) ||
|
|
79
|
+
context.epochTimestamp < 0 ||
|
|
80
|
+
!Number.isSafeInteger(context.executionTimestamp) ||
|
|
81
|
+
context.executionTimestamp < 0 ||
|
|
82
|
+
context.executionTimestamp !== context.epochTimestamp * 1000 ||
|
|
83
|
+
!Number.isFinite(context.epochLength) ||
|
|
84
|
+
!Number.isFinite(context.blockTime) ||
|
|
85
|
+
typeof context.vaultAddress !== 'string' ||
|
|
86
|
+
context.vaultAddress.length === 0) {
|
|
87
|
+
throw new Error('INVALID_EXECUTION_CONTEXT: supplied execution context is malformed.');
|
|
75
88
|
}
|
|
76
89
|
if (context.vaultAddress.toLowerCase() !== vaultConfig.vaultAddress.toLowerCase()) {
|
|
77
90
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context vault does not match vaultConfig.vaultAddress.');
|
|
@@ -80,17 +93,13 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
80
93
|
if (requestChainId !== undefined && requestChainId !== context.chainId) {
|
|
81
94
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context chain does not match vaultConfig.chainId.');
|
|
82
95
|
}
|
|
83
|
-
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
96
|
+
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
97
|
+
String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
|
|
84
98
|
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context block does not match anchorBlockNumber.');
|
|
85
99
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
epochLength: Number(vaultConfig.strategyConfigData.epochLength),
|
|
90
|
-
vaultAddress: context.vaultAddress,
|
|
91
|
-
blockTime: 0,
|
|
92
|
-
blockNumber: Number(context.blockNumber),
|
|
93
|
-
};
|
|
100
|
+
if (Number((_a = vaultConfig.strategyConfigData) === null || _a === void 0 ? void 0 : _a.epochLength) !== context.epochLength) {
|
|
101
|
+
throw new Error('EXECUTION_CONTEXT_MISMATCH: supplied context epoch length does not match vaultConfig.');
|
|
102
|
+
}
|
|
94
103
|
const transformationData = [];
|
|
95
104
|
for (const dataConnector of this.dataConnectors) {
|
|
96
105
|
if (dataConnector.executionAppConfig.chainId !== context.chainId) {
|
|
@@ -98,7 +107,7 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
98
107
|
}
|
|
99
108
|
if (!dataConnector.module)
|
|
100
109
|
yield dataConnector.load();
|
|
101
|
-
dataConnector.
|
|
110
|
+
dataConnector.initializeDataConnectorWithContext(context);
|
|
102
111
|
yield dataConnector.execute();
|
|
103
112
|
transformationData.push(JSON.parse(yield dataConnector.transform()));
|
|
104
113
|
}
|
package/lib/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type": "commonjs"}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ethers, InterfaceAbi } from 'ethers';
|
|
2
|
-
import type { VaultExecutionContext } from '@steerprotocol/sdk';
|
|
3
2
|
/** Error raised before a strategy is invoked when its supplied SDK anchor is unusable. */
|
|
4
3
|
export declare class ExecutionContextError extends Error {
|
|
5
4
|
readonly code: 'INVALID_EXECUTION_CONTEXT' | 'EXECUTION_CONTEXT_MISMATCH';
|
|
@@ -20,8 +19,8 @@ export interface ExecuteWithContextOptions {
|
|
|
20
19
|
wasmFile: string | ArrayBuffer;
|
|
21
20
|
vaultConfig: string;
|
|
22
21
|
data: Array<unknown>;
|
|
23
|
-
/**
|
|
24
|
-
executionContext:
|
|
22
|
+
/** Resolved strategy execution context. */
|
|
23
|
+
executionContext: SmartPoolExecutionContext;
|
|
25
24
|
identity?: ethers.Provider;
|
|
26
25
|
etherRpcConfig?: EtherRpcConfig;
|
|
27
26
|
forceDeposit?: boolean;
|
|
@@ -77,6 +76,7 @@ export interface ConfigData {
|
|
|
77
76
|
[key: string]: string | number;
|
|
78
77
|
}
|
|
79
78
|
export interface ExecutionContext {
|
|
79
|
+
chainId: number;
|
|
80
80
|
executionTimestamp: number;
|
|
81
81
|
epochLength: number;
|
|
82
82
|
vaultAddress: string;
|
|
@@ -84,6 +84,8 @@ export interface ExecutionContext {
|
|
|
84
84
|
blockNumber: number;
|
|
85
85
|
epochTimestamp: number;
|
|
86
86
|
}
|
|
87
|
+
/** Context produced by legacy execution paths, which may not have a chain binding. */
|
|
88
|
+
export type LegacyExecutionContext = Omit<ExecutionContext, 'chainId'> & Partial<Pick<ExecutionContext, 'chainId'>>;
|
|
87
89
|
export interface Position {
|
|
88
90
|
startTick: number;
|
|
89
91
|
endTick: number;
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { Candle } from '@steerprotocol/app-loader';
|
|
2
2
|
import type { AxiosRequestConfig } from 'axios';
|
|
3
3
|
import { type Provider } from 'ethers';
|
|
4
|
-
import type {
|
|
4
|
+
import type { LegacyExecutionContext, ViewContractConfig } from '../types.js';
|
|
5
5
|
export declare const extendOHLCV: (rawData: Array<Candle>, period: number, endTimestamp: number) => Array<Candle>;
|
|
6
6
|
export declare function fetchData(request: AxiosRequestConfig, attempts: number): Promise<any>;
|
|
7
7
|
export declare function readContract({ abi, address, chainId, contractArguments, currentExecutionContext, functionName, provider, rpc, }: {
|
|
8
8
|
address: string;
|
|
9
9
|
abi: any;
|
|
10
|
-
currentExecutionContext:
|
|
10
|
+
currentExecutionContext: LegacyExecutionContext;
|
|
11
11
|
functionName: string;
|
|
12
12
|
provider: Provider;
|
|
13
13
|
rpc: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steerprotocol/data-connector-loader",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-next.2",
|
|
4
4
|
"description": "App Loader for Steer Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "npm run build:cjs && npm run build:esm",
|
|
19
|
-
"build:cjs": "tsc -p tsconfig.json",
|
|
19
|
+
"build:cjs": "tsc -p tsconfig.json && echo '{\"type\": \"commonjs\"}' > lib/package.json",
|
|
20
20
|
"build:esm": "tsc -p tsconfig.esm.json && echo '{\"type\": \"module\"}' > lib/esm/package.json",
|
|
21
21
|
"format": "prettier --write \"src/**/*.(js|ts)\"",
|
|
22
22
|
"lint": "eslint src --ext .js,.ts",
|
|
@@ -54,7 +54,12 @@
|
|
|
54
54
|
"homepage": "https://github.com/SteerProtocol/data-connector-loader#readme",
|
|
55
55
|
"release": {
|
|
56
56
|
"branches": [
|
|
57
|
-
"main"
|
|
57
|
+
"main",
|
|
58
|
+
{
|
|
59
|
+
"name": "next",
|
|
60
|
+
"prerelease": "next",
|
|
61
|
+
"channel": "next"
|
|
62
|
+
}
|
|
58
63
|
],
|
|
59
64
|
"plugins": [
|
|
60
65
|
[
|
|
@@ -97,7 +102,6 @@
|
|
|
97
102
|
],
|
|
98
103
|
"dependencies": {
|
|
99
104
|
"@steerprotocol/app-loader": "^3.0.6",
|
|
100
|
-
"@steerprotocol/sdk": "^3.3.0",
|
|
101
105
|
"@steerprotocol/strategy-utils": "^3.1.2",
|
|
102
106
|
"axios": "^1.3.4",
|
|
103
107
|
"ethers": "^6.16.0",
|