@steerprotocol/data-connector-loader 0.1.4 → 0.2.0

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 (40) hide show
  1. package/lib/base/bundleBase.d.ts +27 -0
  2. package/lib/base/bundleBase.js +119 -0
  3. package/lib/base/loaderBase.d.ts +14 -0
  4. package/lib/base/loaderBase.js +111 -0
  5. package/lib/bundle/bundleApp.d.ts +6 -0
  6. package/lib/bundle/bundleApp.js +11 -0
  7. package/lib/bundle/bundleBase.d.ts +29 -0
  8. package/lib/bundle/bundleBase.js +150 -0
  9. package/lib/bundle/bundleDataConnector.d.ts +8 -0
  10. package/lib/bundle/bundleDataConnector.js +73 -0
  11. package/lib/bundle/bundleExecution.d.ts +7 -0
  12. package/lib/bundle/bundleExecution.js +42 -0
  13. package/lib/bundleDataConnector.d.ts +7 -0
  14. package/lib/bundleDataConnector.js +42 -0
  15. package/lib/bundleExecution.d.ts +7 -0
  16. package/lib/bundleExecution.js +42 -0
  17. package/lib/dataConnector.d.ts +2 -0
  18. package/lib/dataConnector.js +14 -1
  19. package/lib/execution/executionApp.d.ts +17 -0
  20. package/lib/execution/executionApp.js +325 -0
  21. package/lib/execution/executionBase.d.ts +14 -0
  22. package/lib/execution/executionBase.js +111 -0
  23. package/lib/execution/executionBundle.d.ts +5 -0
  24. package/lib/execution/executionBundle.js +29 -0
  25. package/lib/execution/executionDataConnector.d.ts +9 -0
  26. package/lib/execution/executionDataConnector.js +92 -0
  27. package/lib/index.d.ts +4 -15
  28. package/lib/index.js +7 -198
  29. package/lib/loader/loaderBase.d.ts +14 -0
  30. package/lib/loader/loaderBase.js +111 -0
  31. package/lib/types.d.ts +39 -0
  32. package/lib/utils/blockFinder.d.ts +8 -0
  33. package/lib/utils/blockFinder.js +36 -0
  34. package/lib/utils/consts.d.ts +4 -0
  35. package/lib/utils/consts.js +7 -0
  36. package/lib/utils/pluginManager.d.ts +11 -0
  37. package/lib/utils/pluginManager.js +84 -0
  38. package/lib/utils/utils.d.ts +16 -0
  39. package/lib/utils/utils.js +146 -0
  40. package/package.json +4 -4
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DataConnectorExecution = void 0;
13
+ const executionBase_1 = require("./executionBase");
14
+ const pluginManager_1 = require("../utils/pluginManager");
15
+ const utils_1 = require("../utils/utils");
16
+ class DataConnectorExecution extends executionBase_1.ExecutionBase {
17
+ constructor(dataConnectors, maxRetries = 3) {
18
+ super(maxRetries);
19
+ this.dataConnectors = dataConnectors;
20
+ }
21
+ execute(_vaultConfig) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const vaultConfig = JSON.parse(_vaultConfig);
24
+ const transformationData = [];
25
+ const pluginManager = new pluginManager_1.PluginManager();
26
+ yield pluginManager.registerFromPublicConfig();
27
+ for (const dataConnector of this.dataConnectors) {
28
+ if (!dataConnector.module) {
29
+ yield dataConnector.load();
30
+ }
31
+ const executionContext = yield this.getExecutionContext(dataConnector, vaultConfig);
32
+ dataConnector.setExecutionContextDataConnector(executionContext);
33
+ const initialRequest = yield dataConnector.execute('');
34
+ const finalResponse = yield this.handleRequestResponse(dataConnector, pluginManager, initialRequest);
35
+ const transformedData = yield this.transformData(dataConnector, finalResponse);
36
+ transformationData.push(transformedData);
37
+ }
38
+ return transformationData;
39
+ });
40
+ }
41
+ handleRequestResponse(dataConnector, pluginManager, initialRequest) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ let request = initialRequest;
44
+ let response;
45
+ try {
46
+ while (request !== 'true') {
47
+ if (dataConnector.configObj.isChainRead == true) {
48
+ response = yield dataConnector.view(JSON.parse(request));
49
+ }
50
+ else {
51
+ const parsedRequest = yield pluginManager.process(typeof request == 'string' ? JSON.parse(request) : request);
52
+ yield this.delay(1000);
53
+ response = yield (0, utils_1.fetchData)(parsedRequest, 0);
54
+ }
55
+ request = yield dataConnector.execute(JSON.stringify(response));
56
+ }
57
+ }
58
+ catch (e) {
59
+ // process.env.SILENT_ERRORS
60
+ if (process.env.DATA_LOADER_SILENT_ERRORS !== 'true') {
61
+ console.error('Data connector failed to process.', e);
62
+ }
63
+ throw e;
64
+ }
65
+ return dataConnector.getResults();
66
+ });
67
+ }
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ transformData(dataConnector, rawData) {
70
+ var _a, _b, _c;
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ let transformedData = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
73
+ const version = yield this.getDataConnectorVersion(dataConnector);
74
+ if (version == 1 && transformedData.length > 0) {
75
+ const keys = Object.keys(transformedData[0]);
76
+ const requiredKeys = ['timestamp', 'open', 'high', 'low', 'close'];
77
+ const hasAllKeys = requiredKeys.every((key) => keys.includes(key));
78
+ // has the 'lookback' key
79
+ const lookback = (_a = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.configObj) === null || _a === void 0 ? void 0 : _a.lookback;
80
+ if (hasAllKeys && !!lookback) {
81
+ // 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
82
+ if ((_b = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _b === void 0 ? void 0 : _b.epochTimestamp) {
83
+ const extended = (0, utils_1.extendOHLCV)(transformedData, lookback, ((_c = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _c === void 0 ? void 0 : _c.epochTimestamp) * 1000);
84
+ transformedData = extended;
85
+ }
86
+ }
87
+ }
88
+ return transformedData;
89
+ });
90
+ }
91
+ }
92
+ exports.DataConnectorExecution = DataConnectorExecution;
package/lib/index.d.ts CHANGED
@@ -1,15 +1,4 @@
1
- import { DataConnector } from './dataConnector';
2
- import { ethers } from 'ethers';
3
- export { DataConnector };
4
- export declare class DataConnectorExecution {
5
- private dataConnectors;
6
- constructor(dataConnectors: Array<DataConnector>);
7
- private delay;
8
- private log;
9
- private fetchData;
10
- private exponentialBackoffDelay;
11
- execute<T>(_vaultConfig: string): Promise<Array<T>>;
12
- getAverageBlockTime(provider: ethers.providers.Provider, blockCount?: number): Promise<number>;
13
- getBlockNumberFromAvgBlockTime(provider: ethers.providers.Provider, targetTimestamp: number, avgBlockTime: number): Promise<number>;
14
- private downloadWasmBundle;
15
- }
1
+ import { DataConnector } from './bundle/bundleDataConnector';
2
+ import { DataConnectorExecution } from './execution/executionDataConnector';
3
+ import { ExecutionApp } from './execution/executionApp';
4
+ export { DataConnector, DataConnectorExecution, ExecutionApp };
package/lib/index.js CHANGED
@@ -1,200 +1,9 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
2
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.DataConnectorExecution = exports.DataConnector = void 0;
16
- const dataConnector_1 = require("./dataConnector");
17
- Object.defineProperty(exports, "DataConnector", { enumerable: true, get: function () { return dataConnector_1.DataConnector; } });
18
- const axios_1 = __importDefault(require("axios"));
19
- const pluginManager_1 = require("./pluginManager");
20
- const utils_1 = require("./utils");
21
- class DataConnectorExecution {
22
- constructor(dataConnectors) {
23
- this.dataConnectors = dataConnectors;
24
- }
25
- delay(ms) {
26
- return new Promise((resolve) => setTimeout(resolve, ms));
27
- }
28
- log(...args) {
29
- if (process.env.DEBUG === 'true') {
30
- console.log(...args);
31
- }
32
- }
33
- fetchData(request, attempts) {
34
- return __awaiter(this, void 0, void 0, function* () {
35
- this.log('Request payload: =============', request);
36
- attempts = attempts + 1;
37
- try {
38
- const response = (yield (0, axios_1.default)(request)).data;
39
- this.log('API Response: =============', response);
40
- if ('errors' in response && response['errors'].length > 0) {
41
- if (attempts < 3) {
42
- yield this.delay(this.exponentialBackoffDelay(attempts));
43
- return yield this.fetchData(request, attempts);
44
- }
45
- else {
46
- throw new Error('Maximum retry attempts reached');
47
- }
48
- }
49
- return response;
50
- }
51
- catch (error) {
52
- if (attempts < 3) {
53
- yield this.delay(this.exponentialBackoffDelay(attempts));
54
- return yield this.fetchData(request, attempts);
55
- }
56
- else {
57
- throw error;
58
- }
59
- }
60
- });
61
- }
62
- exponentialBackoffDelay(attempts) {
63
- const baseDelay = 1000; // 1 second
64
- const maxDelay = 30000; // 30 seconds
65
- const delay = Math.min(baseDelay * Math.pow(2, attempts - 1), maxDelay);
66
- return delay;
67
- }
68
- execute(_vaultConfig) {
69
- var _a, _b, _c;
70
- return __awaiter(this, void 0, void 0, function* () {
71
- const executionTimestamp = new Date().getTime();
72
- const vaultConfig = JSON.parse(_vaultConfig);
73
- const transformationData = [];
74
- const pluginManager = new pluginManager_1.PluginManager();
75
- yield pluginManager.registerFromPublicConfig();
76
- for (const dataConnector of this.dataConnectors) {
77
- if (!dataConnector.module) {
78
- yield dataConnector.load();
79
- }
80
- const provider = dataConnector.getProvider({});
81
- let blockTime = 0;
82
- let blockNumber = 9;
83
- if (provider) {
84
- blockTime = yield this.getAverageBlockTime(provider);
85
- blockNumber = yield this.getBlockNumberFromAvgBlockTime(provider, vaultConfig.epochTimestamp / 1000, // convert to seconds
86
- blockTime);
87
- }
88
- dataConnector.setExecutionContext({
89
- executionTimestamp,
90
- epochTimestamp: vaultConfig.epochTimestamp,
91
- epochLength: Number(vaultConfig.strategyConfigData.epochLength),
92
- vaultAddress: vaultConfig.vaultAddress,
93
- blockTime,
94
- blockNumber,
95
- });
96
- let version = 1;
97
- try {
98
- version = yield dataConnector.version();
99
- }
100
- catch (e) {
101
- // Data connector is missing version function, fallback to v1 logic
102
- }
103
- let request = yield dataConnector.execute('');
104
- let response;
105
- try {
106
- while (request !== 'true') {
107
- if (dataConnector.configObj.isChainRead == true) {
108
- response = yield dataConnector.view(JSON.parse(request));
109
- }
110
- else {
111
- const parsedRequest = yield pluginManager.process(typeof request == 'string' ? JSON.parse(request) : request);
112
- yield this.delay(1000);
113
- response = yield this.fetchData(parsedRequest, 0);
114
- }
115
- request = yield dataConnector.execute(JSON.stringify(response));
116
- }
117
- }
118
- catch (e) {
119
- // process.env.SILENT_ERRORS
120
- if (process.env.DATA_LOADER_SILENT_ERRORS !== 'true') {
121
- console.error('Data connector failed to process.', e);
122
- }
123
- throw e;
124
- }
125
- let transformedData = JSON.parse(dataConnector.getResults());
126
- if (version == 1 && transformedData.length > 0) {
127
- const keys = Object.keys(transformedData[0]);
128
- const requiredKeys = ['timestamp', 'open', 'high', 'low', 'close'];
129
- const hasAllKeys = requiredKeys.every((key) => keys.includes(key));
130
- // has the 'lookback' key
131
- const lookback = (_a = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.configObj) === null || _a === void 0 ? void 0 : _a.lookback;
132
- if (hasAllKeys && !!lookback) {
133
- // 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
134
- if ((_b = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _b === void 0 ? void 0 : _b.epochTimestamp) {
135
- const extended = (0, utils_1.extendOHLCV)(transformedData, lookback, ((_c = dataConnector === null || dataConnector === void 0 ? void 0 : dataConnector.executionContext) === null || _c === void 0 ? void 0 : _c.epochTimestamp) * 1000);
136
- transformedData = extended;
137
- }
138
- }
139
- }
140
- transformationData.push(transformedData);
141
- }
142
- return transformationData;
143
- });
144
- }
145
- getAverageBlockTime(provider, blockCount = 5) {
146
- return __awaiter(this, void 0, void 0, function* () {
147
- const latestBlock = yield provider.getBlock('latest');
148
- if (latestBlock) {
149
- const startBlockNumber = Math.max(0, latestBlock.number - blockCount + 1);
150
- let totalTimeDiff = 0;
151
- let previousBlock = yield provider.getBlock(startBlockNumber);
152
- if (!previousBlock) {
153
- return 0;
154
- }
155
- for (let i = startBlockNumber + 1; i <= latestBlock.number; i++) {
156
- const currentBlock = yield provider.getBlock(i);
157
- if (!currentBlock || !previousBlock || !currentBlock.timestamp || !previousBlock.timestamp) {
158
- continue;
159
- }
160
- const timeDiff = currentBlock.timestamp - previousBlock.timestamp;
161
- totalTimeDiff += timeDiff;
162
- previousBlock = currentBlock;
163
- }
164
- const averageBlockTime = totalTimeDiff / (blockCount - 1);
165
- return averageBlockTime;
166
- }
167
- else {
168
- return 0;
169
- }
170
- });
171
- }
172
- getBlockNumberFromAvgBlockTime(provider, targetTimestamp, avgBlockTime) {
173
- return __awaiter(this, void 0, void 0, function* () {
174
- const latestBlock = yield provider.getBlock('latest');
175
- const currentTime = Math.floor(Date.now() / 1000);
176
- const timeDifference = currentTime - targetTimestamp;
177
- if (!latestBlock) {
178
- return 0;
179
- }
180
- if (avgBlockTime === 0) {
181
- return latestBlock.number;
182
- }
183
- // Calculate the estimated number of blocks based on the average block time
184
- const estimatedBlockCount = Math.floor(timeDifference / avgBlockTime);
185
- // Calculate the estimated block number
186
- const estimatedBlockNumber = latestBlock.number - estimatedBlockCount;
187
- return Math.max(0, estimatedBlockNumber);
188
- });
189
- }
190
- downloadWasmBundle(ipfsHash) {
191
- return __awaiter(this, void 0, void 0, function* () {
192
- const response = yield axios_1.default.get(`https://steerprotocol.mypinata.cloud/ipfs/${ipfsHash}`, {
193
- responseType: 'arraybuffer',
194
- });
195
- const wasmFile = new Uint8Array(response.data);
196
- return wasmFile;
197
- });
198
- }
199
- }
200
- exports.DataConnectorExecution = DataConnectorExecution;
3
+ exports.ExecutionApp = exports.DataConnectorExecution = exports.DataConnector = void 0;
4
+ const bundleDataConnector_1 = require("./bundle/bundleDataConnector");
5
+ Object.defineProperty(exports, "DataConnector", { enumerable: true, get: function () { return bundleDataConnector_1.DataConnector; } });
6
+ const executionDataConnector_1 = require("./execution/executionDataConnector");
7
+ Object.defineProperty(exports, "DataConnectorExecution", { enumerable: true, get: function () { return executionDataConnector_1.DataConnectorExecution; } });
8
+ const executionApp_1 = require("./execution/executionApp");
9
+ Object.defineProperty(exports, "ExecutionApp", { enumerable: true, get: function () { return executionApp_1.ExecutionApp; } });
@@ -0,0 +1,14 @@
1
+ import { ethers } from 'ethers';
2
+ import { DataConnector } from '../bundle/bundleDataConnector';
3
+ import { VaultConfigPayload, ExecutionContext } from '../types';
4
+ export declare class ExecutionBase {
5
+ maxRetries: number;
6
+ constructor(maxRetries?: number);
7
+ protected delay(ms: number): Promise<void>;
8
+ protected log(...args: any[]): void;
9
+ protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<ExecutionContext>;
10
+ execute<T>(_vaultConfig: string): Promise<Array<T>>;
11
+ protected getDataConnectorVersion(dataConnector: DataConnector): Promise<number>;
12
+ getAverageBlockTime(provider: ethers.providers.Provider, blockCount?: number): Promise<number>;
13
+ getBlockNumberFromAvgBlockTime(provider: ethers.providers.Provider, targetTimestamp: number, avgBlockTime: number): Promise<number>;
14
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ExecutionBase = void 0;
13
+ class ExecutionBase {
14
+ constructor(maxRetries = 3) {
15
+ this.maxRetries = 0;
16
+ this.maxRetries = maxRetries;
17
+ }
18
+ delay(ms) {
19
+ return new Promise((resolve) => setTimeout(resolve, ms));
20
+ }
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ log(...args) {
23
+ if (process.env.DEBUG === 'true') {
24
+ console.log(...args);
25
+ }
26
+ }
27
+ getExecutionContext(dataConnector, vaultConfig) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const provider = dataConnector.getProvider({});
30
+ let blockTime = 0;
31
+ let blockNumber = 9;
32
+ if (provider) {
33
+ blockTime = yield this.getAverageBlockTime(provider);
34
+ blockNumber = yield this.getBlockNumberFromAvgBlockTime(provider, vaultConfig.epochTimestamp / 1000, // convert to seconds
35
+ blockNumber);
36
+ }
37
+ const context = {
38
+ executionTimestamp: new Date().getTime(),
39
+ epochTimestamp: vaultConfig.epochTimestamp,
40
+ epochLength: Number(vaultConfig.strategyConfigData.epochLength),
41
+ vaultAddress: vaultConfig.vaultAddress,
42
+ blockTime: blockTime,
43
+ blockNumber: blockNumber,
44
+ };
45
+ return context;
46
+ });
47
+ }
48
+ execute(_vaultConfig) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ throw new Error('Not implemented');
51
+ });
52
+ }
53
+ getDataConnectorVersion(dataConnector) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ let version = 1;
56
+ try {
57
+ version = yield dataConnector.version();
58
+ }
59
+ catch (e) {
60
+ // Data connector is missing version function, fallback to v1 logic
61
+ }
62
+ return version;
63
+ });
64
+ }
65
+ getAverageBlockTime(provider, blockCount = 5) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ const latestBlock = yield provider.getBlock('latest');
68
+ if (latestBlock) {
69
+ const startBlockNumber = Math.max(0, latestBlock.number - blockCount + 1);
70
+ let totalTimeDiff = 0;
71
+ let previousBlock = yield provider.getBlock(startBlockNumber);
72
+ if (!previousBlock) {
73
+ return 0;
74
+ }
75
+ for (let i = startBlockNumber + 1; i <= latestBlock.number; i++) {
76
+ const currentBlock = yield provider.getBlock(i);
77
+ if (!currentBlock || !previousBlock || !currentBlock.timestamp || !previousBlock.timestamp) {
78
+ continue;
79
+ }
80
+ const timeDiff = currentBlock.timestamp - previousBlock.timestamp;
81
+ totalTimeDiff += timeDiff;
82
+ previousBlock = currentBlock;
83
+ }
84
+ const averageBlockTime = totalTimeDiff / (blockCount - 1);
85
+ return averageBlockTime;
86
+ }
87
+ else {
88
+ return 0;
89
+ }
90
+ });
91
+ }
92
+ getBlockNumberFromAvgBlockTime(provider, targetTimestamp, avgBlockTime) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ const latestBlock = yield provider.getBlock('latest');
95
+ const currentTime = Math.floor(Date.now() / 1000);
96
+ const timeDifference = currentTime - targetTimestamp;
97
+ if (!latestBlock) {
98
+ return 0;
99
+ }
100
+ if (avgBlockTime === 0) {
101
+ return latestBlock.number;
102
+ }
103
+ // Calculate the estimated number of blocks based on the average block time
104
+ const estimatedBlockCount = Math.floor(timeDifference / avgBlockTime);
105
+ // Calculate the estimated block number
106
+ const estimatedBlockNumber = latestBlock.number - estimatedBlockCount;
107
+ return Math.max(0, estimatedBlockNumber);
108
+ });
109
+ }
110
+ }
111
+ exports.ExecutionBase = ExecutionBase;
package/lib/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ContractInterface } from "ethers";
1
2
  export type VaultInput = {
2
3
  _id?: string;
3
4
  tokenId: string;
@@ -55,6 +56,16 @@ export interface ExecutionContext {
55
56
  blockNumber: number;
56
57
  epochTimestamp: number;
57
58
  }
59
+ export interface Position {
60
+ startTick: number;
61
+ endTick: number;
62
+ weight: number;
63
+ }
64
+ export interface SmartPoolExecutionContext extends ExecutionContext {
65
+ positions: Position[];
66
+ currentTick: number;
67
+ lastExecutionTime: number;
68
+ }
58
69
  export type RpcConfig = {
59
70
  url: string;
60
71
  network?: string;
@@ -62,3 +73,31 @@ export type RpcConfig = {
62
73
  export type EtherRpcConfig = {
63
74
  [key: string]: RpcConfig;
64
75
  };
76
+ export interface ViewConfig {
77
+ address: string;
78
+ abi: ContractInterface;
79
+ method: string;
80
+ arguments: unknown[];
81
+ }
82
+ export interface Slot0 {
83
+ sqrtPriceX96?: bigint;
84
+ tick: number;
85
+ observationIndex?: number;
86
+ observationCardinality?: number;
87
+ observationCardinalityNext?: number;
88
+ feeProtocol?: number;
89
+ unlocked: boolean;
90
+ price?: bigint;
91
+ prevInitializedTick?: number;
92
+ fee?: number;
93
+ timepointIndex?: number;
94
+ communityFee?: number;
95
+ }
96
+ export type ViewContractConfig = {
97
+ epochTimestamp?: number;
98
+ address: string;
99
+ abi: any;
100
+ arguments: Array<any>;
101
+ method: string;
102
+ rpcUrl?: string;
103
+ };
@@ -0,0 +1,8 @@
1
+ import { ethers } from 'ethers';
2
+ /**
3
+ * Iterates down from current block to find the block previous or equal to the given timestamp
4
+ * Not the most efficient for far past timestamps, a binary search could be used for better performance
5
+ * @param timestamp
6
+ * @param Idenity
7
+ */
8
+ export declare function getBlockFromTimestamp(timestamp: number, provider: ethers.providers.Provider): Promise<number>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getBlockFromTimestamp = void 0;
13
+ // import { providers, } from "ethers";
14
+ /**
15
+ * Iterates down from current block to find the block previous or equal to the given timestamp
16
+ * Not the most efficient for far past timestamps, a binary search could be used for better performance
17
+ * @param timestamp
18
+ * @param Idenity
19
+ */
20
+ function getBlockFromTimestamp(timestamp, provider) {
21
+ var _a, _b;
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ let currentBlock = (yield provider.getBlockNumber()) - 1;
24
+ let runningTimestamp = (_a = (yield provider.getBlock(currentBlock))) === null || _a === void 0 ? void 0 : _a.timestamp;
25
+ if (!runningTimestamp)
26
+ return currentBlock;
27
+ while (runningTimestamp > timestamp) {
28
+ currentBlock -= 1;
29
+ runningTimestamp = (_b = (yield provider.getBlock(currentBlock))) === null || _b === void 0 ? void 0 : _b.timestamp;
30
+ if (!runningTimestamp)
31
+ return currentBlock;
32
+ }
33
+ return currentBlock;
34
+ });
35
+ }
36
+ exports.getBlockFromTimestamp = getBlockFromTimestamp;
@@ -0,0 +1,4 @@
1
+ export declare const API_BASE_URL = "https://cvrlulno2m.execute-api.ap-southeast-1.amazonaws.com/dev/contract-view-call";
2
+ export declare const API_MAX_RETRIES = 3;
3
+ export declare const API_INITIAL_DELAY = 1000;
4
+ export declare const CENTRALIZE_CONTRACT_INTERACTION_CHAINS: string[];
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CENTRALIZE_CONTRACT_INTERACTION_CHAINS = exports.API_INITIAL_DELAY = exports.API_MAX_RETRIES = exports.API_BASE_URL = void 0;
4
+ exports.API_BASE_URL = "https://cvrlulno2m.execute-api.ap-southeast-1.amazonaws.com/dev/contract-view-call";
5
+ exports.API_MAX_RETRIES = 3;
6
+ exports.API_INITIAL_DELAY = 1000;
7
+ exports.CENTRALIZE_CONTRACT_INTERACTION_CHAINS = ["2222", "42161", "9001", "137", "56"];
@@ -0,0 +1,11 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+ export declare class PluginManager {
3
+ private registeredPluginConfigs;
4
+ constructor();
5
+ registerFromPublicConfig(): Promise<void>;
6
+ registerPluginConfig(name: string, domain: string, headers: object): void;
7
+ private findMatchingPluginConfigs;
8
+ private interpolateEnvVars;
9
+ private interpolateHeaders;
10
+ process(config: AxiosRequestConfig): Promise<AxiosRequestConfig>;
11
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PluginManager = void 0;
16
+ const axios_1 = __importDefault(require("axios"));
17
+ class PluginManager {
18
+ constructor() {
19
+ this.registeredPluginConfigs = [];
20
+ }
21
+ registerFromPublicConfig() {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const { data: dataConnectorPlugins } = yield axios_1.default.get('https://ro81h8hq6b.execute-api.us-east-1.amazonaws.com/data-connector-plugins');
24
+ for (const plugin of dataConnectorPlugins) {
25
+ this.registerPluginConfig(plugin.name, plugin.domain, plugin.headers);
26
+ }
27
+ });
28
+ }
29
+ registerPluginConfig(name, domain, headers) {
30
+ this.registeredPluginConfigs.push({ name, domain, headers });
31
+ }
32
+ findMatchingPluginConfigs(url) {
33
+ const matchingHeaders = {};
34
+ for (const pluginConfig of this.registeredPluginConfigs) {
35
+ if (url.includes(pluginConfig.domain)) {
36
+ Object.assign(matchingHeaders, pluginConfig.headers);
37
+ }
38
+ }
39
+ return matchingHeaders;
40
+ }
41
+ interpolateEnvVars(str) {
42
+ return str.replace(/\{\{(\w+)\}\}/g, (_match, envVar) => {
43
+ const envValue = process.env[envVar];
44
+ if (envValue === undefined) {
45
+ console.log(`Environment variable '${envVar}' not found.`);
46
+ return '';
47
+ }
48
+ return envValue;
49
+ });
50
+ }
51
+ interpolateHeaders(headers) {
52
+ const interpolatedHeaders = {};
53
+ for (const [key, value] of Object.entries(headers)) {
54
+ interpolatedHeaders[key] = typeof value === 'string' ? this.interpolateEnvVars(value) : value;
55
+ }
56
+ return interpolatedHeaders;
57
+ }
58
+ process(config) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ if (!config.url) {
61
+ throw new Error('Request URL is not provided');
62
+ }
63
+ const matchingHeaders = this.findMatchingPluginConfigs(config.url);
64
+ const interpolatedHeaders = this.interpolateHeaders(matchingHeaders);
65
+ const updatedHeaders = Object.assign(Object.assign({}, config.headers), interpolatedHeaders);
66
+ const updatedConfig = Object.assign(Object.assign({}, config), { headers: updatedHeaders });
67
+ return updatedConfig;
68
+ });
69
+ }
70
+ }
71
+ exports.PluginManager = PluginManager;
72
+ // // Usage example:
73
+ // (async () => {
74
+ // const headerMerger = new PluginManager();
75
+ // headerMerger.registerPluginConfig('Example API', 'example.com', { 'X-Custom-Header': '{{MY_ENV_VAR}}' });
76
+ // process.env['MY_ENV_VAR'] = 'ExampleValue';
77
+ // const requestConfig: AxiosRequestConfig = {
78
+ // url: 'https://example.com/api/some-resource',
79
+ // method: 'GET',
80
+ // };
81
+ // const updatedRequestConfig = await headerMerger.process(requestConfig);
82
+ // const response = await axios(updatedRequestConfig);
83
+ // console.log(response.data);
84
+ // })();