@steerprotocol/data-connector-loader 5.0.0-next.1 → 5.0.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/lib/bundle/bundleBase.d.ts +11 -14
- package/lib/bundle/bundleBase.js +56 -88
- package/lib/bundle/bundleDataConnector.d.ts +2 -6
- package/lib/bundle/bundleDataConnector.js +22 -47
- package/lib/esm/bundle/bundleBase.d.ts +11 -14
- package/lib/esm/bundle/bundleBase.js +77 -91
- package/lib/esm/bundle/bundleDataConnector.d.ts +2 -6
- package/lib/esm/bundle/bundleDataConnector.js +26 -49
- package/lib/esm/execution/executionApp.d.ts +16 -15
- package/lib/esm/execution/executionApp.js +364 -321
- package/lib/esm/execution/executionBase.d.ts +7 -7
- package/lib/esm/execution/executionBase.js +27 -13
- package/lib/esm/execution/executionDataConnector.d.ts +6 -3
- package/lib/esm/execution/executionDataConnector.js +128 -69
- package/lib/esm/index.d.ts +7 -7
- package/lib/esm/index.js +4 -4
- package/lib/esm/types.d.ts +20 -24
- package/lib/esm/types.js +5 -5
- package/lib/esm/utils/blockFinder.d.ts +2 -2
- package/lib/esm/utils/blockFinder.js +3 -3
- package/lib/esm/utils/consts.js +39 -39
- package/lib/esm/utils/pluginManager.d.ts +1 -1
- package/lib/esm/utils/pluginManager.js +6 -5
- package/lib/esm/utils/replace-old-subgraphs.js +79 -61
- package/lib/esm/utils/rpc.d.ts +4 -0
- package/lib/esm/utils/rpc.js +32 -0
- package/lib/esm/utils/utils.d.ts +8 -11
- package/lib/esm/utils/utils.js +61 -55
- package/lib/execution/executionApp.d.ts +16 -15
- package/lib/execution/executionApp.js +353 -315
- package/lib/execution/executionBase.d.ts +7 -7
- package/lib/execution/executionBase.js +27 -13
- package/lib/execution/executionDataConnector.d.ts +6 -3
- package/lib/execution/executionDataConnector.js +130 -64
- package/lib/index.d.ts +7 -7
- package/lib/index.js +1 -1
- package/lib/types.d.ts +20 -24
- package/lib/types.js +5 -5
- package/lib/utils/blockFinder.d.ts +2 -2
- package/lib/utils/blockFinder.js +3 -3
- package/lib/utils/consts.js +39 -39
- package/lib/utils/pluginManager.d.ts +1 -1
- package/lib/utils/pluginManager.js +5 -4
- package/lib/utils/replace-old-subgraphs.js +79 -61
- package/lib/utils/rpc.d.ts +4 -0
- package/lib/utils/rpc.js +47 -0
- package/lib/utils/utils.d.ts +8 -11
- package/lib/utils/utils.js +55 -60
- package/package.json +15 -15
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { DataConnector } from
|
|
3
|
-
import type {
|
|
1
|
+
import type { PublicClient } from "viem";
|
|
2
|
+
import type { DataConnector } from "../bundle/bundleDataConnector.js";
|
|
3
|
+
import type { ExecutionContext, RpcAccess, 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<
|
|
10
|
-
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>,
|
|
9
|
+
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<ExecutionContext>;
|
|
10
|
+
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, rpc?: RpcAccess): Promise<T | Array<T> | "continue">;
|
|
11
11
|
protected getDataConnectorVersion(dataConnector: DataConnector): Promise<number>;
|
|
12
|
-
getAverageBlockTime(provider:
|
|
13
|
-
getBlockNumberFromAvgBlockTime(provider:
|
|
12
|
+
getAverageBlockTime(provider: PublicClient, blockCount?: number): Promise<number>;
|
|
13
|
+
getBlockNumberFromAvgBlockTime(provider: PublicClient, targetTimestamp: number, avgBlockTime: number): Promise<number>;
|
|
14
14
|
}
|
|
@@ -19,13 +19,19 @@ class ExecutionBase {
|
|
|
19
19
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
20
20
|
}
|
|
21
21
|
log(...args) {
|
|
22
|
-
if (process.env.DEBUG ===
|
|
22
|
+
if (process.env.DEBUG === "true") {
|
|
23
23
|
console.log(...args);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
getExecutionContext(dataConnector, vaultConfig) {
|
|
27
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
const
|
|
28
|
+
const chainId = dataConnector.executionAppConfig.chainId;
|
|
29
|
+
if (!Number.isSafeInteger(chainId))
|
|
30
|
+
throw new Error("Invalid execution chain ID");
|
|
31
|
+
const provider = dataConnector.getClient();
|
|
32
|
+
if (provider && (yield provider.getChainId()) !== chainId) {
|
|
33
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: provider chain does not match supplied context.");
|
|
34
|
+
}
|
|
29
35
|
let blockTime = 0;
|
|
30
36
|
let blockNumber = 9;
|
|
31
37
|
// Use anchorBlockNumber if provided, otherwise calculate from average block time
|
|
@@ -41,6 +47,7 @@ class ExecutionBase {
|
|
|
41
47
|
blockNumber);
|
|
42
48
|
}
|
|
43
49
|
const context = {
|
|
50
|
+
chainId,
|
|
44
51
|
executionTimestamp: new Date().getTime(),
|
|
45
52
|
epochTimestamp: vaultConfig.epochTimestamp,
|
|
46
53
|
epochLength: Number(vaultConfig.strategyConfigData.epochLength),
|
|
@@ -51,9 +58,9 @@ class ExecutionBase {
|
|
|
51
58
|
return context;
|
|
52
59
|
});
|
|
53
60
|
}
|
|
54
|
-
execute(_wasmFile, _vaultConfig, _data,
|
|
61
|
+
execute(_wasmFile, _vaultConfig, _data, rpc) {
|
|
55
62
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
throw new Error(
|
|
63
|
+
throw new Error("Not implemented");
|
|
57
64
|
});
|
|
58
65
|
}
|
|
59
66
|
getDataConnectorVersion(dataConnector) {
|
|
@@ -70,20 +77,27 @@ class ExecutionBase {
|
|
|
70
77
|
}
|
|
71
78
|
getAverageBlockTime(provider, blockCount = 5) {
|
|
72
79
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
-
const latestBlock = yield provider.getBlock(
|
|
80
|
+
const latestBlock = yield provider.getBlock({ blockTag: "latest" });
|
|
74
81
|
if (latestBlock) {
|
|
75
|
-
const startBlockNumber = Math.max(0, latestBlock.number - blockCount + 1);
|
|
82
|
+
const startBlockNumber = Math.max(0, Number(latestBlock.number) - blockCount + 1);
|
|
76
83
|
let totalTimeDiff = 0;
|
|
77
|
-
let previousBlock = yield provider.getBlock(
|
|
84
|
+
let previousBlock = yield provider.getBlock({
|
|
85
|
+
blockNumber: BigInt(startBlockNumber),
|
|
86
|
+
});
|
|
78
87
|
if (!previousBlock) {
|
|
79
88
|
return 0;
|
|
80
89
|
}
|
|
81
90
|
for (let i = startBlockNumber + 1; i <= latestBlock.number; i++) {
|
|
82
|
-
const currentBlock = yield provider.getBlock(
|
|
83
|
-
|
|
91
|
+
const currentBlock = yield provider.getBlock({
|
|
92
|
+
blockNumber: BigInt(i),
|
|
93
|
+
});
|
|
94
|
+
if (!currentBlock ||
|
|
95
|
+
!previousBlock ||
|
|
96
|
+
!currentBlock.timestamp ||
|
|
97
|
+
!previousBlock.timestamp) {
|
|
84
98
|
continue;
|
|
85
99
|
}
|
|
86
|
-
const timeDiff = currentBlock.timestamp - previousBlock.timestamp;
|
|
100
|
+
const timeDiff = Number(currentBlock.timestamp - previousBlock.timestamp);
|
|
87
101
|
totalTimeDiff += timeDiff;
|
|
88
102
|
previousBlock = currentBlock;
|
|
89
103
|
}
|
|
@@ -97,19 +111,19 @@ class ExecutionBase {
|
|
|
97
111
|
}
|
|
98
112
|
getBlockNumberFromAvgBlockTime(provider, targetTimestamp, avgBlockTime) {
|
|
99
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
const latestBlock = yield provider.getBlock(
|
|
114
|
+
const latestBlock = yield provider.getBlock({ blockTag: "latest" });
|
|
101
115
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
102
116
|
const timeDifference = currentTime - targetTimestamp;
|
|
103
117
|
if (!latestBlock) {
|
|
104
118
|
return 0;
|
|
105
119
|
}
|
|
106
120
|
if (avgBlockTime === 0) {
|
|
107
|
-
return latestBlock.number;
|
|
121
|
+
return Number(latestBlock.number);
|
|
108
122
|
}
|
|
109
123
|
// Calculate the estimated number of blocks based on the average block time
|
|
110
124
|
const estimatedBlockCount = Math.floor(timeDifference / avgBlockTime);
|
|
111
125
|
// Calculate the estimated block number
|
|
112
|
-
const estimatedBlockNumber = latestBlock.number - estimatedBlockCount;
|
|
126
|
+
const estimatedBlockNumber = Number(latestBlock.number) - estimatedBlockCount;
|
|
113
127
|
return Math.max(0, estimatedBlockNumber);
|
|
114
128
|
});
|
|
115
129
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { DataConnector } from
|
|
2
|
-
import { type ExecutionContext } from
|
|
3
|
-
import { ExecutionBase } from
|
|
1
|
+
import type { DataConnector } from "../bundle/bundleDataConnector.js";
|
|
2
|
+
import { type ExecutionContext } from "../types.js";
|
|
3
|
+
import { ExecutionBase } from "./executionBase.js";
|
|
4
4
|
export declare class DataConnectorExecution extends ExecutionBase {
|
|
5
5
|
private dataConnectors;
|
|
6
6
|
constructor(dataConnectors: Array<DataConnector>, maxRetries?: number);
|
|
@@ -12,6 +12,9 @@ export declare class DataConnectorExecution extends ExecutionBase {
|
|
|
12
12
|
*/
|
|
13
13
|
executeWithContext<T>(_vaultConfig: string, context: ExecutionContext): Promise<Array<T>>;
|
|
14
14
|
private executeV2Bundle;
|
|
15
|
+
private getConnectorVersion;
|
|
16
|
+
private executeInitializedV2Bundle;
|
|
17
|
+
private executeV1Bundle;
|
|
15
18
|
executeDynamicJob<T>(_vaultConfig: string): Promise<Array<T>>;
|
|
16
19
|
private handleRequestResponse;
|
|
17
20
|
private transformData;
|
|
@@ -8,10 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.DataConnectorExecution = void 0;
|
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
17
|
const types_js_1 = require("../types.js");
|
|
14
|
-
const pluginManager_js_1 = require("../utils/pluginManager.js");
|
|
15
18
|
const replace_old_subgraphs_js_1 = require("../utils/replace-old-subgraphs.js");
|
|
16
19
|
const utils_js_1 = require("../utils/utils.js");
|
|
17
20
|
const executionBase_js_1 = require("./executionBase.js");
|
|
@@ -24,39 +27,16 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
24
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
28
|
const vaultConfig = JSON.parse(_vaultConfig);
|
|
26
29
|
const transformationData = [];
|
|
27
|
-
const pluginManager = new pluginManager_js_1.PluginManager();
|
|
28
|
-
yield pluginManager.registerFromPublicConfig();
|
|
29
30
|
for (const dataConnector of this.dataConnectors) {
|
|
30
|
-
if (!dataConnector.module)
|
|
31
|
+
if (!dataConnector.module)
|
|
31
32
|
yield dataConnector.load();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
version = dataConnector.version();
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
version = 1;
|
|
39
|
-
}
|
|
40
|
-
if (version >= 2) {
|
|
41
|
-
const transformData = yield this.executeV2Bundle(dataConnector, vaultConfig);
|
|
42
|
-
transformationData.push(transformData);
|
|
33
|
+
if (this.getConnectorVersion(dataConnector) >= 2) {
|
|
34
|
+
transformationData.push(yield this.executeV2Bundle(dataConnector, vaultConfig));
|
|
43
35
|
}
|
|
44
36
|
else {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const initialRequest = yield dataConnector.execute();
|
|
49
|
-
if (initialRequest === null) {
|
|
50
|
-
throw new Error('Data connector returned null request');
|
|
51
|
-
}
|
|
52
|
-
const finalResponse = yield this.handleRequestResponse(dataConnector, pluginManager, initialRequest);
|
|
53
|
-
const transformedData = yield this.transformData(dataConnector, finalResponse);
|
|
54
|
-
transformationData.push(transformedData);
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
const transformData = yield this.executeV2Bundle(dataConnector, vaultConfig);
|
|
58
|
-
transformationData.push(transformData);
|
|
59
|
-
}
|
|
37
|
+
const executionContext = yield this.getExecutionContext(dataConnector, vaultConfig);
|
|
38
|
+
dataConnector.setExecutionContextDataConnector(executionContext);
|
|
39
|
+
transformationData.push(yield this.executeV1Bundle(dataConnector));
|
|
60
40
|
}
|
|
61
41
|
}
|
|
62
42
|
return transformationData;
|
|
@@ -82,34 +62,45 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
82
62
|
context.executionTimestamp !== context.epochTimestamp * 1000 ||
|
|
83
63
|
!Number.isFinite(context.epochLength) ||
|
|
84
64
|
!Number.isFinite(context.blockTime) ||
|
|
85
|
-
typeof context.vaultAddress !==
|
|
65
|
+
typeof context.vaultAddress !== "string" ||
|
|
86
66
|
context.vaultAddress.length === 0) {
|
|
87
|
-
throw new Error(
|
|
67
|
+
throw new Error("INVALID_EXECUTION_CONTEXT: supplied execution context is malformed.");
|
|
88
68
|
}
|
|
89
|
-
if (context.vaultAddress.toLowerCase() !==
|
|
90
|
-
|
|
69
|
+
if (context.vaultAddress.toLowerCase() !==
|
|
70
|
+
vaultConfig.vaultAddress.toLowerCase()) {
|
|
71
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context vault does not match vaultConfig.vaultAddress.");
|
|
91
72
|
}
|
|
92
73
|
const requestChainId = vaultConfig.chainId;
|
|
93
74
|
if (requestChainId !== undefined && requestChainId !== context.chainId) {
|
|
94
|
-
throw new Error(
|
|
75
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context chain does not match vaultConfig.chainId.");
|
|
95
76
|
}
|
|
96
77
|
if (vaultConfig.anchorBlockNumber !== undefined &&
|
|
97
78
|
String(vaultConfig.anchorBlockNumber) !== String(context.blockNumber)) {
|
|
98
|
-
throw new Error(
|
|
79
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context block does not match anchorBlockNumber.");
|
|
99
80
|
}
|
|
100
|
-
if (Number((_a = vaultConfig.strategyConfigData) === null || _a === void 0 ? void 0 : _a.epochLength) !==
|
|
101
|
-
|
|
81
|
+
if (Number((_a = vaultConfig.strategyConfigData) === null || _a === void 0 ? void 0 : _a.epochLength) !==
|
|
82
|
+
context.epochLength) {
|
|
83
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context epoch length does not match vaultConfig.");
|
|
102
84
|
}
|
|
85
|
+
const pinnedContext = Object.freeze(Object.assign({}, context));
|
|
103
86
|
const transformationData = [];
|
|
104
87
|
for (const dataConnector of this.dataConnectors) {
|
|
105
|
-
if (dataConnector.executionAppConfig.chainId !==
|
|
106
|
-
throw new Error(
|
|
88
|
+
if (dataConnector.executionAppConfig.chainId !== pinnedContext.chainId) {
|
|
89
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context chain does not match connector configuration.");
|
|
90
|
+
}
|
|
91
|
+
if (dataConnector.configObj.chainId !== undefined &&
|
|
92
|
+
Number(dataConnector.configObj.chainId) !== pinnedContext.chainId) {
|
|
93
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: supplied context chain does not match connector settings.");
|
|
107
94
|
}
|
|
108
95
|
if (!dataConnector.module)
|
|
109
96
|
yield dataConnector.load();
|
|
110
|
-
dataConnector.initializeDataConnectorWithContext(
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
dataConnector.initializeDataConnectorWithContext(pinnedContext);
|
|
98
|
+
if (this.getConnectorVersion(dataConnector) >= 2) {
|
|
99
|
+
transformationData.push(yield this.executeInitializedV2Bundle(dataConnector));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
transformationData.push(yield this.executeV1Bundle(dataConnector, pinnedContext));
|
|
103
|
+
}
|
|
113
104
|
}
|
|
114
105
|
return transformationData;
|
|
115
106
|
});
|
|
@@ -118,17 +109,39 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
118
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
119
110
|
const executionContext = yield this.getExecutionContext(dataConnector, vaultConfig);
|
|
120
111
|
dataConnector.setExecutionContextDataConnector(executionContext);
|
|
112
|
+
return this.executeInitializedV2Bundle(dataConnector);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
getConnectorVersion(dataConnector) {
|
|
116
|
+
var _a;
|
|
117
|
+
if (typeof ((_a = dataConnector.module) === null || _a === void 0 ? void 0 : _a.version) !== "function")
|
|
118
|
+
return 1;
|
|
119
|
+
const version = dataConnector.version();
|
|
120
|
+
if (!Number.isInteger(version) || version < 1)
|
|
121
|
+
throw new Error("Invalid data connector version");
|
|
122
|
+
return version;
|
|
123
|
+
}
|
|
124
|
+
executeInitializedV2Bundle(dataConnector) {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
126
|
yield dataConnector.execute();
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
return JSON.parse(yield dataConnector.transform());
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
executeV1Bundle(dataConnector, context) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
const initialRequest = yield dataConnector.execute("");
|
|
133
|
+
if (initialRequest === null)
|
|
134
|
+
throw new Error("Data connector returned null request");
|
|
135
|
+
const result = yield this.handleRequestResponse(dataConnector, initialRequest, context);
|
|
136
|
+
if (context)
|
|
137
|
+
return typeof result === "string" ? JSON.parse(result) : result;
|
|
138
|
+
return this.transformData(dataConnector, result);
|
|
124
139
|
});
|
|
125
140
|
}
|
|
126
141
|
executeDynamicJob(_vaultConfig) {
|
|
127
142
|
return __awaiter(this, void 0, void 0, function* () {
|
|
128
143
|
const vaultConfig = JSON.parse(_vaultConfig);
|
|
129
144
|
const transformationData = [];
|
|
130
|
-
const pluginManager = new pluginManager_js_1.PluginManager();
|
|
131
|
-
yield pluginManager.registerFromPublicConfig();
|
|
132
145
|
for (const dataConnector of this.dataConnectors) {
|
|
133
146
|
if (!dataConnector.module) {
|
|
134
147
|
yield dataConnector.load();
|
|
@@ -142,40 +155,92 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
142
155
|
return transformationData;
|
|
143
156
|
});
|
|
144
157
|
}
|
|
145
|
-
handleRequestResponse(dataConnector,
|
|
158
|
+
handleRequestResponse(dataConnector, initialRequest, context) {
|
|
159
|
+
var _a, _b;
|
|
146
160
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
161
|
let request = initialRequest;
|
|
148
162
|
let response;
|
|
149
163
|
try {
|
|
150
|
-
while (request !==
|
|
151
|
-
if (dataConnector.configObj.isChainRead
|
|
152
|
-
|
|
164
|
+
while (request !== "true") {
|
|
165
|
+
if (dataConnector.configObj.isChainRead === true) {
|
|
166
|
+
const view = JSON.parse(request);
|
|
167
|
+
if (context &&
|
|
168
|
+
view.chainId !== undefined &&
|
|
169
|
+
Number(view.chainId) !== context.chainId) {
|
|
170
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: contract request chain does not match supplied context.");
|
|
171
|
+
}
|
|
172
|
+
response = yield dataConnector.view(view);
|
|
153
173
|
}
|
|
154
174
|
else {
|
|
155
|
-
|
|
156
|
-
const
|
|
175
|
+
let parsedRequest = typeof request === "string" ? JSON.parse(request) : request;
|
|
176
|
+
const graphApiKey = (_a = dataConnector.executionAppConfig.apiKeys) === null || _a === void 0 ? void 0 : _a.subgraphStudioKey;
|
|
177
|
+
const url = (0, replace_old_subgraphs_js_1.changeUrlIfOld)(parsedRequest.url, graphApiKey ? undefined : dataConnector.configObj.subgraphStudioKey);
|
|
157
178
|
parsedRequest.url = url;
|
|
158
|
-
|
|
179
|
+
let sentio = false;
|
|
180
|
+
let graph = false;
|
|
181
|
+
try {
|
|
182
|
+
const destination = new URL(axios_1.default.getUri(parsedRequest));
|
|
183
|
+
const hostname = destination.hostname.toLowerCase();
|
|
184
|
+
graph =
|
|
185
|
+
(destination.origin === "https://gateway.thegraph.com" ||
|
|
186
|
+
destination.origin ===
|
|
187
|
+
"https://gateway-arbitrum.network.thegraph.com") &&
|
|
188
|
+
/^\/api\/(subgraphs|deployments)\/id\/[a-zA-Z0-9]+$/.test(destination.pathname) &&
|
|
189
|
+
!destination.username &&
|
|
190
|
+
!destination.password;
|
|
191
|
+
sentio =
|
|
192
|
+
destination.protocol === "https:" &&
|
|
193
|
+
(hostname === "sentio.xyz" || hostname.endsWith(".sentio.xyz"));
|
|
194
|
+
}
|
|
195
|
+
catch (_c) {
|
|
196
|
+
/* Axios will report an invalid URL when sending the request. */
|
|
197
|
+
}
|
|
198
|
+
const sentioApiKey = (_b = dataConnector.executionAppConfig.apiKeys) === null || _b === void 0 ? void 0 : _b.sentioApiKey;
|
|
199
|
+
parsedRequest.headers = Object.assign(Object.assign(Object.assign({ "Content-Type": url && !url.includes("subgraph-proxy-server")
|
|
200
|
+
? "application/json"
|
|
201
|
+
: "text/plain;charset=UTF-8" }, (sentio && sentioApiKey
|
|
202
|
+
? {
|
|
203
|
+
"api-key": sentioApiKey,
|
|
204
|
+
}
|
|
205
|
+
: {})), (graph && graphApiKey
|
|
206
|
+
? { Authorization: `Bearer ${graphApiKey}` }
|
|
207
|
+
: {})), parsedRequest.headers);
|
|
208
|
+
if (sentio || (graph && graphApiKey)) {
|
|
209
|
+
const { url, baseURL, method, params, data, headers, timeout, responseType, allowAbsoluteUrls, } = parsedRequest;
|
|
210
|
+
parsedRequest = {
|
|
211
|
+
url,
|
|
212
|
+
baseURL,
|
|
213
|
+
method,
|
|
214
|
+
params,
|
|
215
|
+
data,
|
|
216
|
+
headers,
|
|
217
|
+
timeout,
|
|
218
|
+
responseType,
|
|
219
|
+
allowAbsoluteUrls,
|
|
220
|
+
proxy: false,
|
|
221
|
+
maxRedirects: 0,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
159
224
|
yield this.delay(1000);
|
|
160
225
|
try {
|
|
161
226
|
response = yield (0, utils_js_1.fetchData)(parsedRequest, 0);
|
|
162
227
|
}
|
|
163
228
|
catch (error) {
|
|
164
229
|
const message = error instanceof Error ? error.message : String(error);
|
|
165
|
-
throw new types_js_1.DataConnectorTransportError(message.replace(/https?:\/\/[^\s@/]+(?::[^\s@/]+)?@/gi,
|
|
230
|
+
throw new types_js_1.DataConnectorTransportError(message.replace(/https?:\/\/[^\s@/]+(?::[^\s@/]+)?@/gi, "https://[REDACTED]@"));
|
|
166
231
|
}
|
|
167
232
|
}
|
|
168
|
-
const nextRequest = yield dataConnector.execute(JSON.stringify(response));
|
|
233
|
+
const nextRequest = yield dataConnector.execute(JSON.stringify(response, (_key, value) => typeof value === "bigint" ? value.toString() : value));
|
|
169
234
|
if (nextRequest === null) {
|
|
170
|
-
throw new Error(
|
|
235
|
+
throw new Error("Data connector returned null request");
|
|
171
236
|
}
|
|
172
237
|
request = nextRequest;
|
|
173
238
|
}
|
|
174
239
|
}
|
|
175
240
|
catch (e) {
|
|
176
241
|
// process.env.SILENT_ERRORS
|
|
177
|
-
if (process.env.DATA_LOADER_SILENT_ERRORS !==
|
|
178
|
-
console.error(
|
|
242
|
+
if (process.env.DATA_LOADER_SILENT_ERRORS !== "true") {
|
|
243
|
+
console.error("Data connector failed to process.", e);
|
|
179
244
|
}
|
|
180
245
|
throw e;
|
|
181
246
|
}
|
|
@@ -185,15 +250,16 @@ class DataConnectorExecution extends executionBase_js_1.ExecutionBase {
|
|
|
185
250
|
transformData(dataConnector, rawData) {
|
|
186
251
|
var _a, _b, _c;
|
|
187
252
|
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
-
let transformedData = typeof rawData ===
|
|
189
|
-
|
|
190
|
-
|
|
253
|
+
let transformedData = typeof rawData === "string" ? JSON.parse(rawData) : rawData;
|
|
254
|
+
if (Array.isArray(transformedData) &&
|
|
255
|
+
transformedData.length > 0 &&
|
|
256
|
+
transformedData[0] != null) {
|
|
191
257
|
const keys = Object.keys(transformedData[0]);
|
|
192
|
-
const requiredKeys = [
|
|
258
|
+
const requiredKeys = ["timestamp", "open", "high", "low", "close"];
|
|
193
259
|
const hasAllKeys = requiredKeys.every((key) => keys.includes(key));
|
|
194
260
|
// has the 'lookback' key
|
|
195
261
|
const lookback = (_a = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.configObj) === null || _a === void 0 ? void 0 : _a.lookback;
|
|
196
|
-
if (hasAllKeys &&
|
|
262
|
+
if (hasAllKeys && lookback) {
|
|
197
263
|
// Now that we have identified a v1 data connector, we need to transform the data so that the data is up to the current execution epoch timestamp
|
|
198
264
|
if ((_b = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _b === void 0 ? void 0 : _b.epochTimestamp) {
|
|
199
265
|
const extended = (0, utils_js_1.extendOHLCV)(transformedData, lookback, ((_c = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _c === void 0 ? void 0 : _c.epochTimestamp) * 1000);
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DataConnector } from
|
|
2
|
-
import { ExecutionApp, type ExecutionAppConfig } from
|
|
3
|
-
import { DataConnectorExecution } from
|
|
4
|
-
import type { ExecuteWithContextOptions, VaultConfigPayload } from
|
|
5
|
-
export type * from
|
|
1
|
+
import { DataConnector } from "./bundle/bundleDataConnector.js";
|
|
2
|
+
import { ExecutionApp, type ExecutionAppConfig } from "./execution/executionApp.js";
|
|
3
|
+
import { DataConnectorExecution } from "./execution/executionDataConnector.js";
|
|
4
|
+
import type { ExecuteWithContextOptions, VaultConfigPayload } from "./types.js";
|
|
5
|
+
export type * from "./types.js";
|
|
6
|
+
export { DataConnectorTransportError, ExecutionContextError, StrategyExecutionError, } from "./types.js";
|
|
7
|
+
export type { ExecuteWithContextOptions, ExecutionAppConfig, VaultConfigPayload, };
|
|
6
8
|
export { DataConnector, DataConnectorExecution, ExecutionApp };
|
|
7
|
-
export { DataConnectorTransportError, ExecutionContextError, StrategyExecutionError } from './types.js';
|
|
8
|
-
export type { ExecuteWithContextOptions, ExecutionAppConfig, VaultConfigPayload };
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ExecutionApp = exports.DataConnectorExecution = exports.DataConnector = exports.StrategyExecutionError = exports.ExecutionContextError = exports.DataConnectorTransportError = void 0;
|
|
4
4
|
const bundleDataConnector_js_1 = require("./bundle/bundleDataConnector.js");
|
|
5
5
|
Object.defineProperty(exports, "DataConnector", { enumerable: true, get: function () { return bundleDataConnector_js_1.DataConnector; } });
|
|
6
6
|
const executionApp_js_1 = require("./execution/executionApp.js");
|
package/lib/types.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Abi, PublicClient } from "viem";
|
|
2
|
+
import type { ExecutionAppConfig } from "./execution/executionApp.js";
|
|
2
3
|
/** Error raised before a strategy is invoked when its supplied SDK anchor is unusable. */
|
|
3
4
|
export declare class ExecutionContextError extends Error {
|
|
4
|
-
readonly code:
|
|
5
|
-
constructor(code: ExecutionContextError[
|
|
5
|
+
readonly code: "INVALID_EXECUTION_CONTEXT" | "EXECUTION_CONTEXT_MISMATCH";
|
|
6
|
+
constructor(code: ExecutionContextError["code"], message: string);
|
|
6
7
|
}
|
|
7
8
|
/** Error classification for failures in a connector transport request. */
|
|
8
9
|
export declare class DataConnectorTransportError extends Error {
|
|
@@ -21,8 +22,6 @@ export interface ExecuteWithContextOptions {
|
|
|
21
22
|
data: Array<unknown>;
|
|
22
23
|
/** Resolved strategy execution context. */
|
|
23
24
|
executionContext: SmartPoolExecutionContext;
|
|
24
|
-
identity?: ethers.Provider;
|
|
25
|
-
etherRpcConfig?: EtherRpcConfig;
|
|
26
25
|
forceDeposit?: boolean;
|
|
27
26
|
}
|
|
28
27
|
export type VaultInput = {
|
|
@@ -84,8 +83,6 @@ export interface ExecutionContext {
|
|
|
84
83
|
blockNumber: number;
|
|
85
84
|
epochTimestamp: number;
|
|
86
85
|
}
|
|
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'>>;
|
|
89
86
|
export interface Position {
|
|
90
87
|
startTick: number;
|
|
91
88
|
endTick: number;
|
|
@@ -99,17 +96,25 @@ export interface SmartPoolExecutionContext extends ExecutionContext {
|
|
|
99
96
|
totalAmount1: string;
|
|
100
97
|
tickSpacing: number;
|
|
101
98
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
/** RPC access for one execution chain. URL endpoints are validated individually. */
|
|
100
|
+
export type RpcAccess = {
|
|
101
|
+
client: PublicClient;
|
|
102
|
+
urls?: never;
|
|
103
|
+
} | {
|
|
104
|
+
urls: readonly string[];
|
|
105
|
+
client?: never;
|
|
109
106
|
};
|
|
107
|
+
export interface DataConnectorOptions {
|
|
108
|
+
wasmFile: string | ArrayBuffer;
|
|
109
|
+
config: string;
|
|
110
|
+
executionConfig: ExecutionAppConfig;
|
|
111
|
+
rpc?: RpcAccess;
|
|
112
|
+
}
|
|
113
|
+
export type ContractAbi = Abi | readonly string[] | string;
|
|
110
114
|
export interface ViewConfig {
|
|
115
|
+
chainId?: number;
|
|
111
116
|
address: string;
|
|
112
|
-
abi:
|
|
117
|
+
abi: ContractAbi;
|
|
113
118
|
method: string;
|
|
114
119
|
arguments: Array<unknown>;
|
|
115
120
|
}
|
|
@@ -127,15 +132,6 @@ export interface Slot0 {
|
|
|
127
132
|
timepointIndex?: number;
|
|
128
133
|
communityFee?: number;
|
|
129
134
|
}
|
|
130
|
-
export type ViewContractConfig = {
|
|
131
|
-
epochTimestamp?: number;
|
|
132
|
-
blockNumber?: number;
|
|
133
|
-
address: string;
|
|
134
|
-
abi: any;
|
|
135
|
-
arguments: Array<any>;
|
|
136
|
-
method: string;
|
|
137
|
-
rpcUrl?: string;
|
|
138
|
-
};
|
|
139
135
|
export type JobDetails = {
|
|
140
136
|
id: string;
|
|
141
137
|
name: string;
|
package/lib/types.js
CHANGED
|
@@ -5,7 +5,7 @@ exports.StrategyExecutionError = exports.DataConnectorTransportError = exports.E
|
|
|
5
5
|
class ExecutionContextError extends Error {
|
|
6
6
|
constructor(code, message) {
|
|
7
7
|
super(message);
|
|
8
|
-
this.name =
|
|
8
|
+
this.name = "ExecutionContextError";
|
|
9
9
|
this.code = code;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -14,8 +14,8 @@ exports.ExecutionContextError = ExecutionContextError;
|
|
|
14
14
|
class DataConnectorTransportError extends Error {
|
|
15
15
|
constructor(message) {
|
|
16
16
|
super(message);
|
|
17
|
-
this.code =
|
|
18
|
-
this.name =
|
|
17
|
+
this.code = "DATA_CONNECTOR_TRANSPORT_ERROR";
|
|
18
|
+
this.name = "DataConnectorTransportError";
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.DataConnectorTransportError = DataConnectorTransportError;
|
|
@@ -23,8 +23,8 @@ exports.DataConnectorTransportError = DataConnectorTransportError;
|
|
|
23
23
|
class StrategyExecutionError extends Error {
|
|
24
24
|
constructor(message) {
|
|
25
25
|
super(message);
|
|
26
|
-
this.code =
|
|
27
|
-
this.name =
|
|
26
|
+
this.code = "STRATEGY_EXECUTION_ERROR";
|
|
27
|
+
this.name = "StrategyExecutionError";
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
exports.StrategyExecutionError = StrategyExecutionError;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PublicClient } from "viem";
|
|
2
2
|
/**
|
|
3
3
|
* Iterates down from current block to find the block previous or equal to the given timestamp
|
|
4
4
|
* Not the most efficient for far past timestamps, a binary search could be used for better performance
|
|
5
5
|
* @param timestamp
|
|
6
6
|
* @param Idenity
|
|
7
7
|
*/
|
|
8
|
-
export declare function getBlockFromTimestamp(timestamp: number, provider:
|
|
8
|
+
export declare function getBlockFromTimestamp(timestamp: number, provider: PublicClient): Promise<number>;
|
package/lib/utils/blockFinder.js
CHANGED
|
@@ -19,13 +19,13 @@ exports.getBlockFromTimestamp = void 0;
|
|
|
19
19
|
function getBlockFromTimestamp(timestamp, provider) {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
let currentBlock = (yield provider.getBlockNumber()) - 1;
|
|
23
|
-
let runningTimestamp = (_a = (yield provider.getBlock(currentBlock))) === null || _a === void 0 ? void 0 : _a.timestamp;
|
|
22
|
+
let currentBlock = Number(yield provider.getBlockNumber()) - 1;
|
|
23
|
+
let runningTimestamp = (_a = (yield provider.getBlock({ blockNumber: BigInt(currentBlock) }))) === null || _a === void 0 ? void 0 : _a.timestamp;
|
|
24
24
|
if (!runningTimestamp)
|
|
25
25
|
return currentBlock;
|
|
26
26
|
while (runningTimestamp > timestamp) {
|
|
27
27
|
currentBlock -= 1;
|
|
28
|
-
runningTimestamp = (_b = (yield provider.getBlock(currentBlock))) === null || _b === void 0 ? void 0 : _b.timestamp;
|
|
28
|
+
runningTimestamp = (_b = (yield provider.getBlock({ blockNumber: BigInt(currentBlock) }))) === null || _b === void 0 ? void 0 : _b.timestamp;
|
|
29
29
|
if (!runningTimestamp)
|
|
30
30
|
return currentBlock;
|
|
31
31
|
}
|