@steerprotocol/data-connector-loader 0.1.5 → 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.
- package/lib/base/bundleBase.d.ts +27 -0
- package/lib/base/bundleBase.js +119 -0
- package/lib/base/loaderBase.d.ts +14 -0
- package/lib/base/loaderBase.js +111 -0
- package/lib/bundle/bundleApp.d.ts +6 -0
- package/lib/bundle/bundleApp.js +11 -0
- package/lib/bundle/bundleBase.d.ts +29 -0
- package/lib/bundle/bundleBase.js +150 -0
- package/lib/bundle/bundleDataConnector.d.ts +8 -0
- package/lib/bundle/bundleDataConnector.js +73 -0
- package/lib/bundle/bundleExecution.d.ts +7 -0
- package/lib/bundle/bundleExecution.js +42 -0
- package/lib/bundleDataConnector.d.ts +7 -0
- package/lib/bundleDataConnector.js +42 -0
- package/lib/bundleExecution.d.ts +7 -0
- package/lib/bundleExecution.js +42 -0
- package/lib/execution/executionApp.d.ts +17 -0
- package/lib/execution/executionApp.js +325 -0
- package/lib/execution/executionBase.d.ts +14 -0
- package/lib/execution/executionBase.js +111 -0
- package/lib/execution/executionBundle.d.ts +5 -0
- package/lib/execution/executionBundle.js +29 -0
- package/lib/execution/executionDataConnector.d.ts +9 -0
- package/lib/execution/executionDataConnector.js +92 -0
- package/lib/index.d.ts +4 -15
- package/lib/index.js +7 -198
- package/lib/loader/loaderBase.d.ts +14 -0
- package/lib/loader/loaderBase.js +111 -0
- package/lib/types.d.ts +39 -0
- package/lib/utils/blockFinder.d.ts +8 -0
- package/lib/utils/blockFinder.js +36 -0
- package/lib/utils/consts.d.ts +4 -0
- package/lib/utils/consts.js +7 -0
- package/lib/utils/pluginManager.d.ts +11 -0
- package/lib/utils/pluginManager.js +84 -0
- package/lib/utils/utils.d.ts +16 -0
- package/lib/utils/utils.js +146 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
import { DataConnector } from './
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export
|
|
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
|
|
17
|
-
Object.defineProperty(exports, "DataConnector", { enumerable: true, get: function () { return
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
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
|
+
// })();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Candle } from "@steerprotocol/app-loader";
|
|
2
|
+
import { AxiosRequestConfig } from "axios";
|
|
3
|
+
import { ExecutionContext, ViewContractConfig } from "../types";
|
|
4
|
+
import { providers } from "ethers";
|
|
5
|
+
export declare const extendOHLCV: (rawData: Candle[], period: number, endTimestamp: number) => Candle[];
|
|
6
|
+
export declare function fetchData(request: AxiosRequestConfig, attempts: number): Promise<any>;
|
|
7
|
+
export declare function readSlot0Contract({ address, abi, currentExecutionContext, functionName, provider, rpc, chainId }: {
|
|
8
|
+
address: string;
|
|
9
|
+
abi: any;
|
|
10
|
+
currentExecutionContext: ExecutionContext;
|
|
11
|
+
functionName: string;
|
|
12
|
+
provider: providers.Provider;
|
|
13
|
+
rpc: string;
|
|
14
|
+
chainId: number;
|
|
15
|
+
}): Promise<any>;
|
|
16
|
+
export declare function callWithRetry(config: ViewContractConfig): Promise<any>;
|