@steerprotocol/data-connector-loader 3.1.1 → 3.2.1
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 +30 -1
- package/lib/bundle/bundleBase.d.ts +10 -5
- package/lib/bundle/bundleBase.js +65 -11
- package/lib/bundle/bundleDataConnector.d.ts +11 -4
- package/lib/bundle/bundleDataConnector.js +49 -13
- package/lib/esm/bundle/bundleBase.d.ts +10 -5
- package/lib/esm/bundle/bundleBase.js +60 -11
- package/lib/esm/bundle/bundleDataConnector.d.ts +11 -4
- package/lib/esm/bundle/bundleDataConnector.js +46 -11
- package/lib/esm/execution/executionApp.d.ts +52 -7
- package/lib/esm/execution/executionApp.js +557 -113
- package/lib/esm/execution/executionBase.d.ts +4 -4
- package/lib/esm/execution/executionBase.js +11 -12
- package/lib/esm/execution/executionDataConnector.d.ts +4 -2
- package/lib/esm/execution/executionDataConnector.js +56 -25
- package/lib/esm/index.d.ts +6 -4
- package/lib/esm/index.js +3 -4
- package/lib/esm/types.d.ts +17 -4
- package/lib/esm/utils/blockFinder.d.ts +1 -1
- package/lib/esm/utils/consts.js +43 -1
- package/lib/esm/utils/pluginManager.d.ts +1 -1
- package/lib/esm/utils/providerUtils.d.ts +4 -0
- package/lib/esm/utils/providerUtils.js +37 -0
- package/lib/esm/utils/replace-old-subgraphs.d.ts +23 -0
- package/lib/esm/utils/replace-old-subgraphs.js +123 -0
- package/lib/esm/utils/utils.d.ts +7 -6
- package/lib/esm/utils/utils.js +8 -9
- package/lib/execution/executionApp.d.ts +52 -7
- package/lib/execution/executionApp.js +556 -117
- package/lib/execution/executionBase.d.ts +4 -4
- package/lib/execution/executionBase.js +11 -12
- package/lib/execution/executionDataConnector.d.ts +4 -2
- package/lib/execution/executionDataConnector.js +61 -29
- package/lib/index.d.ts +6 -4
- package/lib/index.js +6 -21
- package/lib/types.d.ts +17 -4
- package/lib/utils/blockFinder.d.ts +1 -1
- package/lib/utils/consts.js +43 -1
- package/lib/utils/pluginManager.d.ts +1 -1
- package/lib/utils/providerUtils.d.ts +4 -0
- package/lib/utils/providerUtils.js +43 -0
- package/lib/utils/replace-old-subgraphs.d.ts +23 -0
- package/lib/utils/replace-old-subgraphs.js +129 -0
- package/lib/utils/utils.d.ts +7 -6
- package/lib/utils/utils.js +15 -16
- package/package.json +12 -3
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
|
-
import { DataConnector } from '../bundle/bundleDataConnector';
|
|
3
|
-
import {
|
|
1
|
+
import type { ethers } from 'ethers';
|
|
2
|
+
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
3
|
+
import type { EtherRpcConfig, ExecutionContext, 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
|
-
protected log(...args: any
|
|
8
|
+
protected log(...args: Array<any>): void;
|
|
9
9
|
protected getExecutionContext(dataConnector: DataConnector, vaultConfig: VaultConfigPayload): Promise<ExecutionContext>;
|
|
10
10
|
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _identity?: ethers.Provider, _etherRpcConfig?: EtherRpcConfig): Promise<Array<T>>;
|
|
11
11
|
protected getDataConnectorVersion(dataConnector: DataConnector): Promise<number>;
|
|
@@ -6,7 +6,6 @@ export class ExecutionBase {
|
|
|
6
6
|
delay(ms) {
|
|
7
7
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
8
|
}
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
9
|
log(...args) {
|
|
11
10
|
if (process.env.DEBUG === 'true') {
|
|
12
11
|
console.log(...args);
|
|
@@ -16,25 +15,25 @@ export class ExecutionBase {
|
|
|
16
15
|
const provider = dataConnector.getProvider({});
|
|
17
16
|
let blockTime = 0;
|
|
18
17
|
let blockNumber = 9;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
blockNumber = await this.getBlockNumberFromAvgBlockTime(provider, vaultConfig.epochTimestamp / 1000, // convert to seconds
|
|
25
|
-
blockTime);
|
|
18
|
+
// Use anchorBlockNumber if provided, otherwise calculate from average block time
|
|
19
|
+
if (vaultConfig.anchorBlockNumber !== undefined) {
|
|
20
|
+
blockNumber = vaultConfig.anchorBlockNumber;
|
|
21
|
+
if (provider) {
|
|
22
|
+
blockTime = await this.getAverageBlockTime(provider);
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
|
-
if (
|
|
29
|
-
|
|
25
|
+
else if (provider) {
|
|
26
|
+
blockTime = await this.getAverageBlockTime(provider);
|
|
27
|
+
blockNumber = await this.getBlockNumberFromAvgBlockTime(provider, vaultConfig.epochTimestamp / 1000, // convert to seconds
|
|
28
|
+
blockNumber);
|
|
30
29
|
}
|
|
31
30
|
const context = {
|
|
32
31
|
executionTimestamp: new Date().getTime(),
|
|
33
32
|
epochTimestamp: vaultConfig.epochTimestamp,
|
|
34
33
|
epochLength: Number(vaultConfig.strategyConfigData.epochLength),
|
|
35
34
|
vaultAddress: vaultConfig.vaultAddress,
|
|
36
|
-
blockTime
|
|
37
|
-
blockNumber
|
|
35
|
+
blockTime,
|
|
36
|
+
blockNumber,
|
|
38
37
|
};
|
|
39
38
|
return context;
|
|
40
39
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { DataConnector } from '../bundle/bundleDataConnector.js';
|
|
2
|
+
import { ExecutionBase } from './executionBase.js';
|
|
3
3
|
export declare class DataConnectorExecution extends ExecutionBase {
|
|
4
4
|
private dataConnectors;
|
|
5
5
|
constructor(dataConnectors: Array<DataConnector>, maxRetries?: number);
|
|
6
6
|
execute<T>(_vaultConfig: string): Promise<Array<T>>;
|
|
7
|
+
private executeV2Bundle;
|
|
8
|
+
executeDynamicJob<T>(_vaultConfig: string): Promise<Array<T>>;
|
|
7
9
|
private handleRequestResponse;
|
|
8
10
|
private transformData;
|
|
9
11
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { extendOHLCV, fetchData } from '../utils/utils';
|
|
1
|
+
import { PluginManager } from '../utils/pluginManager.js';
|
|
2
|
+
import { changeUrlIfOld } from '../utils/replace-old-subgraphs.js';
|
|
3
|
+
import { extendOHLCV, fetchData } from '../utils/utils.js';
|
|
4
|
+
import { ExecutionBase } from './executionBase.js';
|
|
4
5
|
export class DataConnectorExecution extends ExecutionBase {
|
|
5
6
|
constructor(dataConnectors, maxRetries = 3) {
|
|
6
7
|
super(maxRetries);
|
|
@@ -15,20 +16,55 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
15
16
|
if (!dataConnector.module) {
|
|
16
17
|
await dataConnector.load();
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
let version = 1;
|
|
20
|
+
try {
|
|
21
|
+
version = dataConnector.version();
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
version = 1;
|
|
25
|
+
}
|
|
26
|
+
if (version >= 2) {
|
|
27
|
+
const transformData = await this.executeV2Bundle(dataConnector, vaultConfig);
|
|
28
|
+
transformationData.push(transformData);
|
|
26
29
|
}
|
|
27
30
|
else {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
try {
|
|
32
|
+
const executionContext = await this.getExecutionContext(dataConnector, vaultConfig);
|
|
33
|
+
dataConnector.setExecutionContextDataConnector(executionContext);
|
|
34
|
+
const initialRequest = await dataConnector.execute('');
|
|
35
|
+
const finalResponse = await this.handleRequestResponse(dataConnector, pluginManager, initialRequest);
|
|
36
|
+
const transformedData = await this.transformData(dataConnector, finalResponse);
|
|
37
|
+
transformationData.push(transformedData);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
const transformData = await this.executeV2Bundle(dataConnector, vaultConfig);
|
|
41
|
+
transformationData.push(transformData);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return transformationData;
|
|
46
|
+
}
|
|
47
|
+
async executeV2Bundle(dataConnector, vaultConfig) {
|
|
48
|
+
const executionContext = await this.getExecutionContext(dataConnector, vaultConfig);
|
|
49
|
+
dataConnector.setExecutionContextDataConnector(executionContext);
|
|
50
|
+
await dataConnector.execute('');
|
|
51
|
+
const result = await dataConnector.transform();
|
|
52
|
+
return JSON.parse(result);
|
|
53
|
+
}
|
|
54
|
+
async executeDynamicJob(_vaultConfig) {
|
|
55
|
+
const vaultConfig = JSON.parse(_vaultConfig);
|
|
56
|
+
const transformationData = [];
|
|
57
|
+
const pluginManager = new PluginManager();
|
|
58
|
+
await pluginManager.registerFromPublicConfig();
|
|
59
|
+
for (const dataConnector of this.dataConnectors) {
|
|
60
|
+
if (!dataConnector.module) {
|
|
61
|
+
await dataConnector.load();
|
|
31
62
|
}
|
|
63
|
+
const executionContext = await this.getExecutionContext(dataConnector, vaultConfig);
|
|
64
|
+
dataConnector.setExecutionContextDataConnector(executionContext);
|
|
65
|
+
await dataConnector.execute('');
|
|
66
|
+
const result = await dataConnector.transform();
|
|
67
|
+
transformationData.push(JSON.parse(result));
|
|
32
68
|
}
|
|
33
69
|
return transformationData;
|
|
34
70
|
}
|
|
@@ -42,6 +78,12 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
42
78
|
}
|
|
43
79
|
else {
|
|
44
80
|
const parsedRequest = await pluginManager.process(typeof request == 'string' ? JSON.parse(request) : request);
|
|
81
|
+
const url = changeUrlIfOld(parsedRequest.url, dataConnector.configObj.subgraphStudioKey);
|
|
82
|
+
parsedRequest.url = url;
|
|
83
|
+
parsedRequest.headers = {
|
|
84
|
+
'Content-Type': url && !url.includes('subgraph-proxy-server') ? 'application/json' : 'text/plain;charset=UTF-8',
|
|
85
|
+
...(url?.includes('sentio') ? { 'api-key': dataConnector.executionAppConfig.apiKeys.sentioApiKey } : {}),
|
|
86
|
+
};
|
|
45
87
|
await this.delay(1000);
|
|
46
88
|
response = await fetchData(parsedRequest, 0);
|
|
47
89
|
}
|
|
@@ -57,19 +99,8 @@ export class DataConnectorExecution extends ExecutionBase {
|
|
|
57
99
|
}
|
|
58
100
|
return dataConnector.getResults();
|
|
59
101
|
}
|
|
60
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
102
|
async transformData(dataConnector, rawData) {
|
|
62
103
|
let transformedData = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
|
|
63
|
-
if (transformedData == null || transformedData.length == 0) {
|
|
64
|
-
const results = dataConnector.getResults();
|
|
65
|
-
const parsedResults = JSON.parse(results);
|
|
66
|
-
if (parsedResults.length == null) {
|
|
67
|
-
transformedData = results;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
transformedData = parsedResults;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
104
|
const version = await this.getDataConnectorVersion(dataConnector);
|
|
74
105
|
if (version == 1 && transformedData.length > 0) {
|
|
75
106
|
const keys = Object.keys(transformedData[0]);
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { DataConnector } from './bundle/bundleDataConnector';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
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 { VaultConfigPayload } from './types.js';
|
|
5
|
+
export type * from './types.js';
|
|
5
6
|
export { DataConnector, DataConnectorExecution, ExecutionApp };
|
|
7
|
+
export type { ExecutionAppConfig, VaultConfigPayload };
|
package/lib/esm/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { DataConnector } from './bundle/bundleDataConnector';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export * from './types';
|
|
1
|
+
import { DataConnector } from './bundle/bundleDataConnector.js';
|
|
2
|
+
import { ExecutionApp } from './execution/executionApp.js';
|
|
3
|
+
import { DataConnectorExecution } from './execution/executionDataConnector.js';
|
|
5
4
|
export { DataConnector, DataConnectorExecution, ExecutionApp };
|
package/lib/esm/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InterfaceAbi } from 'ethers';
|
|
1
|
+
import type { InterfaceAbi } from 'ethers';
|
|
2
2
|
export type VaultInput = {
|
|
3
3
|
_id?: string;
|
|
4
4
|
tokenId: string;
|
|
@@ -23,7 +23,7 @@ export type VaultInput = {
|
|
|
23
23
|
export interface VaultConfigPayload {
|
|
24
24
|
strategyConfigData: StrategyConfigData;
|
|
25
25
|
vaultPayload: VaultPayload;
|
|
26
|
-
dataConnectorsData: DataConnectorsDaum
|
|
26
|
+
dataConnectorsData: Array<DataConnectorsDaum>;
|
|
27
27
|
vaultAddress: string;
|
|
28
28
|
epochTimestamp: number;
|
|
29
29
|
anchorBlockNumber?: number;
|
|
@@ -63,12 +63,16 @@ export interface Position {
|
|
|
63
63
|
weight: number;
|
|
64
64
|
}
|
|
65
65
|
export interface SmartPoolExecutionContext extends ExecutionContext {
|
|
66
|
-
positions: Position
|
|
66
|
+
positions: Array<Position>;
|
|
67
67
|
currentTick: number;
|
|
68
68
|
lastExecutionTime: number;
|
|
69
|
+
totalAmount0: string;
|
|
70
|
+
totalAmount1: string;
|
|
71
|
+
tickSpacing: number;
|
|
69
72
|
}
|
|
70
73
|
export type RpcConfig = {
|
|
71
74
|
url: string;
|
|
75
|
+
urls?: ReadonlyArray<string>;
|
|
72
76
|
network?: string;
|
|
73
77
|
};
|
|
74
78
|
export type EtherRpcConfig = {
|
|
@@ -78,7 +82,7 @@ export interface ViewConfig {
|
|
|
78
82
|
address: string;
|
|
79
83
|
abi: InterfaceAbi;
|
|
80
84
|
method: string;
|
|
81
|
-
arguments: unknown
|
|
85
|
+
arguments: Array<unknown>;
|
|
82
86
|
}
|
|
83
87
|
export interface Slot0 {
|
|
84
88
|
sqrtPriceX96?: bigint;
|
|
@@ -102,3 +106,12 @@ export type ViewContractConfig = {
|
|
|
102
106
|
method: string;
|
|
103
107
|
rpcUrl?: string;
|
|
104
108
|
};
|
|
109
|
+
export type JobDetails = {
|
|
110
|
+
id: string;
|
|
111
|
+
name?: string;
|
|
112
|
+
timestamp?: string;
|
|
113
|
+
jobInfo?: ReadonlyArray<unknown>;
|
|
114
|
+
targetAddresses?: ReadonlyArray<string>;
|
|
115
|
+
ipfsHash?: string;
|
|
116
|
+
status?: string;
|
|
117
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
1
|
+
import type { ethers } from 'ethers';
|
|
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
|
package/lib/esm/utils/consts.js
CHANGED
|
@@ -1,4 +1,46 @@
|
|
|
1
1
|
export const API_BASE_URL = 'https://cvrlulno2m.execute-api.ap-southeast-1.amazonaws.com/dev/contract-view-call';
|
|
2
|
+
// export const API_BASE_URL = "http://localhost:3000/dev/contract-view-call";
|
|
2
3
|
export const API_MAX_RETRIES = 3;
|
|
3
4
|
export const API_INITIAL_DELAY = 1000;
|
|
4
|
-
export const CENTRALIZE_CONTRACT_INTERACTION_CHAINS = [
|
|
5
|
+
export const CENTRALIZE_CONTRACT_INTERACTION_CHAINS = [
|
|
6
|
+
'999',
|
|
7
|
+
'43114',
|
|
8
|
+
'6900',
|
|
9
|
+
'5464',
|
|
10
|
+
'2020',
|
|
11
|
+
'747474',
|
|
12
|
+
'1116',
|
|
13
|
+
'43111',
|
|
14
|
+
'80094',
|
|
15
|
+
'129399',
|
|
16
|
+
'130',
|
|
17
|
+
'146',
|
|
18
|
+
'1868',
|
|
19
|
+
'1',
|
|
20
|
+
'80084',
|
|
21
|
+
'2222',
|
|
22
|
+
'1329',
|
|
23
|
+
'1284',
|
|
24
|
+
'42161',
|
|
25
|
+
'9001',
|
|
26
|
+
'137',
|
|
27
|
+
'56',
|
|
28
|
+
'5000',
|
|
29
|
+
'250',
|
|
30
|
+
'3776',
|
|
31
|
+
'81457',
|
|
32
|
+
'592',
|
|
33
|
+
'1088',
|
|
34
|
+
'34443',
|
|
35
|
+
// "8453",
|
|
36
|
+
'30',
|
|
37
|
+
// "8453",
|
|
38
|
+
'167000',
|
|
39
|
+
'196',
|
|
40
|
+
'810180',
|
|
41
|
+
'137',
|
|
42
|
+
'314',
|
|
43
|
+
'33139',
|
|
44
|
+
'7000',
|
|
45
|
+
'3338',
|
|
46
|
+
];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
export declare const prioritizeRpcUrls: (urls: ReadonlyArray<string>) => Array<string>;
|
|
3
|
+
export declare const getPrimaryRpcUrl: (urls: ReadonlyArray<string>) => string;
|
|
4
|
+
export declare const createFallbackRpcProvider: (urls: ReadonlyArray<string>) => ethers.Provider;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
const UNSTABLE_RPC_PATTERNS = [/drpc\.org/i];
|
|
3
|
+
const uniqueUrls = (urls) => {
|
|
4
|
+
const seen = new Set();
|
|
5
|
+
const normalized = [];
|
|
6
|
+
for (const url of urls) {
|
|
7
|
+
const trimmed = url.trim();
|
|
8
|
+
if (trimmed.length === 0 || seen.has(trimmed)) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
seen.add(trimmed);
|
|
12
|
+
normalized.push(trimmed);
|
|
13
|
+
}
|
|
14
|
+
return normalized;
|
|
15
|
+
};
|
|
16
|
+
const isDeprioritizedRpcUrl = (url) => UNSTABLE_RPC_PATTERNS.some((pattern) => pattern.test(url));
|
|
17
|
+
export const prioritizeRpcUrls = (urls) => {
|
|
18
|
+
const normalized = uniqueUrls(urls);
|
|
19
|
+
const preferred = normalized.filter((url) => !isDeprioritizedRpcUrl(url));
|
|
20
|
+
const deprioritized = normalized.filter((url) => isDeprioritizedRpcUrl(url));
|
|
21
|
+
return preferred.length > 0 ? [...preferred, ...deprioritized] : normalized;
|
|
22
|
+
};
|
|
23
|
+
export const getPrimaryRpcUrl = (urls) => {
|
|
24
|
+
const prioritized = prioritizeRpcUrls(urls);
|
|
25
|
+
if (prioritized.length === 0) {
|
|
26
|
+
throw new Error('No RPC URLs configured');
|
|
27
|
+
}
|
|
28
|
+
return prioritized[0];
|
|
29
|
+
};
|
|
30
|
+
export const createFallbackRpcProvider = (urls) => {
|
|
31
|
+
const prioritized = prioritizeRpcUrls(urls);
|
|
32
|
+
if (prioritized.length === 0) {
|
|
33
|
+
throw new Error('No RPC URLs configured');
|
|
34
|
+
}
|
|
35
|
+
const providers = prioritized.map((url) => new ethers.JsonRpcProvider(url));
|
|
36
|
+
return providers.length === 1 ? providers[0] : new ethers.FallbackProvider(providers);
|
|
37
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface SubgraphUrlConfig {
|
|
2
|
+
chain: string;
|
|
3
|
+
protocol: string;
|
|
4
|
+
newUrl: string;
|
|
5
|
+
oldUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SubgraphReplacerConfig {
|
|
8
|
+
subgraphStudioKey?: string;
|
|
9
|
+
customConfigs?: Array<SubgraphUrlConfig>;
|
|
10
|
+
}
|
|
11
|
+
export declare class SubgraphUrlReplacer {
|
|
12
|
+
private readonly subgraphStudioKey;
|
|
13
|
+
private readonly subgraphUrlConfigs;
|
|
14
|
+
constructor(config?: SubgraphReplacerConfig);
|
|
15
|
+
changeUrlIfOld(url?: string): string | undefined;
|
|
16
|
+
private getArbitrumSubgraphUrl;
|
|
17
|
+
private getDefaultConfigs;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convenience function that uses the default SubgraphUrlReplacer instance
|
|
21
|
+
* For custom configuration, create a new SubgraphUrlReplacer instance
|
|
22
|
+
*/
|
|
23
|
+
export declare const changeUrlIfOld: (url?: string, subgraphStudioKey?: string) => string | undefined;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export class SubgraphUrlReplacer {
|
|
2
|
+
constructor(config) {
|
|
3
|
+
this.subgraphStudioKey = config?.subgraphStudioKey ?? '';
|
|
4
|
+
this.subgraphUrlConfigs = config?.customConfigs || this.getDefaultConfigs();
|
|
5
|
+
}
|
|
6
|
+
changeUrlIfOld(url) {
|
|
7
|
+
const subgraphUrl = this.subgraphUrlConfigs.find(({ oldUrl }) => url === oldUrl);
|
|
8
|
+
if (subgraphUrl) {
|
|
9
|
+
return subgraphUrl.newUrl;
|
|
10
|
+
}
|
|
11
|
+
return url;
|
|
12
|
+
}
|
|
13
|
+
getArbitrumSubgraphUrl(subgraphId, isDeploymentId) {
|
|
14
|
+
return `https://gateway-arbitrum.network.thegraph.com/api/${this.subgraphStudioKey}/${isDeploymentId ? 'deployments' : 'subgraphs'}/id/${subgraphId}`;
|
|
15
|
+
}
|
|
16
|
+
getDefaultConfigs() {
|
|
17
|
+
return [
|
|
18
|
+
{
|
|
19
|
+
chain: 'polygon',
|
|
20
|
+
protocol: 'quickswap',
|
|
21
|
+
newUrl: this.getArbitrumSubgraphUrl(`FqsRcH1XqSjqVx9GRTvEJe959aCbKrcyGgDWBrUkG24g`, false),
|
|
22
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sameepsi/quickswap-v3',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
chain: 'polygon',
|
|
26
|
+
protocol: 'uniswap',
|
|
27
|
+
newUrl: this.getArbitrumSubgraphUrl(`3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm`, false),
|
|
28
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
chain: 'optimism',
|
|
32
|
+
protocol: 'uniswap',
|
|
33
|
+
newUrl: this.getArbitrumSubgraphUrl(`Cghf4LfVqPiFw6fp6Y5X5Ubc8UpmUhSfJL82zwiBFLaj`, false),
|
|
34
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
chain: 'arbitrum',
|
|
38
|
+
protocol: 'uniswap',
|
|
39
|
+
newUrl: this.getArbitrumSubgraphUrl(`FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM`, false),
|
|
40
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/ianlapham/arbitrum-dev',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
chain: 'celo',
|
|
44
|
+
protocol: 'uniswap',
|
|
45
|
+
newUrl: this.getArbitrumSubgraphUrl(`ESdrTJ3twMwWVoQ1hUE2u7PugEHX3QkenudD6aXCkDQ4`, false),
|
|
46
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
chain: 'base',
|
|
50
|
+
protocol: 'baseswap',
|
|
51
|
+
newUrl: 'https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/v3-base/prod/gn',
|
|
52
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/harleen-m/basex',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
chain: 'arbitrum',
|
|
56
|
+
protocol: 'sushi',
|
|
57
|
+
newUrl: this.getArbitrumSubgraphUrl('QmevuQAmgiou1UX7Z2BQf6RKdX1WunQjH8VtawhkzSLj4V', true),
|
|
58
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-arbitrum',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
chain: 'avalanche',
|
|
62
|
+
protocol: 'sushi',
|
|
63
|
+
newUrl: this.getArbitrumSubgraphUrl('Qmcdd4SGVwG9VY4itrXBnBPWBVsQvsxfzaib9bVny9C8jT', true),
|
|
64
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-avalanche',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
chain: 'bsc',
|
|
68
|
+
protocol: 'sushi',
|
|
69
|
+
newUrl: this.getArbitrumSubgraphUrl('QmXsPN4TD4PUhT1ZWd5d1mdQPePFNMdJwUr6guSh1z9ZzA', true),
|
|
70
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-bsc',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
chain: 'base',
|
|
74
|
+
protocol: 'sushi',
|
|
75
|
+
newUrl: this.getArbitrumSubgraphUrl('QmZ2R9ABG9ienaZdGyPLcDWDNDkG187RhXmh6fFuEtUaaS', true),
|
|
76
|
+
oldUrl: 'https://api.studio.thegraph.com/query/32073/v3-base/v0.0.1',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
chain: 'optimism',
|
|
80
|
+
protocol: 'sushi',
|
|
81
|
+
newUrl: this.getArbitrumSubgraphUrl('QmbT6ZsxJEZKUrbzLrAWV5EnQfSKZeYtZ265mQUaB552vK', true),
|
|
82
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-optimism',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
chain: 'polygon',
|
|
86
|
+
protocol: 'sushi',
|
|
87
|
+
newUrl: this.getArbitrumSubgraphUrl('QmPbbjK9vtY69kSxMJRVLVz1dRzUBNwYbWTRYMiFzp9Tzm', true),
|
|
88
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-polygon',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
chain: 'zkevm',
|
|
92
|
+
protocol: 'sushi',
|
|
93
|
+
newUrl: this.getArbitrumSubgraphUrl('QmWH5ChjmF4Yp5Yhiaxczh5QwbG6HFSEi8bRwbKaUrJA6C', true),
|
|
94
|
+
oldUrl: 'https://api.studio.thegraph.com/query/32073/v3-polygon-zkevm/v0.0.2',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
chain: 'arbitrum',
|
|
98
|
+
protocol: 'camelot',
|
|
99
|
+
newUrl: 'https://subgraph-proxy-server-xf2uthetka-as.a.run.app/gateway-arbitrum/3utanEBA9nqMjPnuQP1vMCCys6enSM3EawBpKTVwnUw2',
|
|
100
|
+
oldUrl: 'https://api.thegraph.com/subgraphs/name/camelotlabs/camelot-amm-v3',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
chain: 'mode',
|
|
104
|
+
protocol: 'swapmode',
|
|
105
|
+
newUrl: 'https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/swapmode-v3/prod/gn',
|
|
106
|
+
oldUrl: 'https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/swapmode-v3/1.0.0/gn',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
chain: 'linea',
|
|
110
|
+
protocol: 'lynex',
|
|
111
|
+
newUrl: 'https://api.goldsky.com/api/public/project_cltyhthusbmxp01s95k9l8a1u/subgraphs/lynex-cl/v1.0.2/gn',
|
|
112
|
+
oldUrl: 'https://graph-query.linea.build/subgraphs/name/cryptoalgebra/analytics',
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Convenience function that uses the default SubgraphUrlReplacer instance
|
|
119
|
+
* For custom configuration, create a new SubgraphUrlReplacer instance
|
|
120
|
+
*/
|
|
121
|
+
export const changeUrlIfOld = (url, subgraphStudioKey) => {
|
|
122
|
+
return new SubgraphUrlReplacer({ subgraphStudioKey }).changeUrlIfOld(url);
|
|
123
|
+
};
|
package/lib/esm/utils/utils.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { Candle } from '@steerprotocol/app-loader';
|
|
2
|
-
import { AxiosRequestConfig } from 'axios';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export declare const extendOHLCV: (rawData: Candle
|
|
1
|
+
import type { Candle } from '@steerprotocol/app-loader';
|
|
2
|
+
import type { AxiosRequestConfig } from 'axios';
|
|
3
|
+
import { type Provider } from 'ethers';
|
|
4
|
+
import type { ExecutionContext, ViewContractConfig } from '../types.js';
|
|
5
|
+
export declare const extendOHLCV: (rawData: Array<Candle>, period: number, endTimestamp: number) => Array<Candle>;
|
|
6
6
|
export declare function fetchData(request: AxiosRequestConfig, attempts: number): Promise<any>;
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function readContract({ abi, address, chainId, contractArguments, currentExecutionContext, functionName, provider, rpc, }: {
|
|
8
8
|
address: string;
|
|
9
9
|
abi: any;
|
|
10
10
|
currentExecutionContext: ExecutionContext;
|
|
11
11
|
functionName: string;
|
|
12
12
|
provider: Provider;
|
|
13
13
|
rpc: string;
|
|
14
|
+
contractArguments?: Array<any>;
|
|
14
15
|
chainId: number;
|
|
15
16
|
}): Promise<any>;
|
|
16
17
|
export declare function callWithRetry(config: ViewContractConfig): Promise<any>;
|
package/lib/esm/utils/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { Contract } from 'ethers';
|
|
3
|
-
import { API_BASE_URL, API_INITIAL_DELAY, API_MAX_RETRIES, CENTRALIZE_CONTRACT_INTERACTION_CHAINS } from './consts';
|
|
3
|
+
import { API_BASE_URL, API_INITIAL_DELAY, API_MAX_RETRIES, CENTRALIZE_CONTRACT_INTERACTION_CHAINS } from './consts.js';
|
|
4
4
|
// The purpose of this function is to look at the end timestamp and extend the current candle array so that it backfills any missing candles up to the end timestamp
|
|
5
5
|
export const extendOHLCV = (rawData, period, endTimestamp) => {
|
|
6
6
|
// Sort rawData by timestamp
|
|
@@ -61,14 +61,13 @@ export async function fetchData(request, attempts) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
export async function
|
|
64
|
+
export async function readContract({ abi, address, chainId, contractArguments = [], currentExecutionContext, functionName, provider, rpc, }) {
|
|
65
65
|
// Create a new contract instance
|
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
66
|
if (!provider)
|
|
68
67
|
throw new Error('Provider not initialized');
|
|
69
68
|
const contract = new Contract(address, abi, provider);
|
|
70
69
|
// For formatting the parameters if needed
|
|
71
|
-
const paramsArray = [];
|
|
70
|
+
const paramsArray = contractArguments || [];
|
|
72
71
|
// Calculate block number for determinism
|
|
73
72
|
// Best way to handle contextually non-null values?
|
|
74
73
|
// const syncedBlock = await getBlockFromTimestamp(this.executionContext!.epochTimestamp, this.providerIdentity!) //@note uncomment for deterministic blocks
|
|
@@ -78,13 +77,14 @@ export async function readSlot0Contract({ address, abi, currentExecutionContext,
|
|
|
78
77
|
if (CENTRALIZE_CONTRACT_INTERACTION_CHAINS.indexOf(chainId.toString()) === -1) {
|
|
79
78
|
result = await contract[functionName](...paramsArray, {
|
|
80
79
|
blockTag: currentExecutionContext?.blockNumber,
|
|
81
|
-
});
|
|
80
|
+
}); // @note uncomment for deterministic blocks
|
|
82
81
|
}
|
|
83
82
|
else {
|
|
83
|
+
console.log('Calling the centralized view');
|
|
84
84
|
const viewContractConfig = {
|
|
85
85
|
epochTimestamp: currentExecutionContext.epochTimestamp,
|
|
86
|
-
address
|
|
87
|
-
abi
|
|
86
|
+
address,
|
|
87
|
+
abi,
|
|
88
88
|
arguments: paramsArray,
|
|
89
89
|
method: functionName,
|
|
90
90
|
rpcUrl: rpc,
|
|
@@ -103,7 +103,7 @@ export async function callWithRetry(config) {
|
|
|
103
103
|
return JSON.parse(response.data); // Return the data if the call was successful
|
|
104
104
|
}
|
|
105
105
|
catch (error) {
|
|
106
|
-
console.error(`Attempt ${retries + 1} failed. Retrying in to fetch the contract method ${config.method} ${delay / 1000} seconds
|
|
106
|
+
console.error(`Attempt ${retries + 1} failed. Retrying in to fetch the contract method ${config.method} ${delay / 1000} seconds...`, error);
|
|
107
107
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
108
108
|
delay *= 2; // Double the delay for the next retry
|
|
109
109
|
retries++;
|
|
@@ -111,7 +111,6 @@ export async function callWithRetry(config) {
|
|
|
111
111
|
}
|
|
112
112
|
throw new Error(`Failed after ${API_MAX_RETRIES} attempts. to call method ${config.method}`);
|
|
113
113
|
}
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
114
|
function log(...args) {
|
|
116
115
|
if (process.env.DEBUG === 'true') {
|
|
117
116
|
console.log(...args);
|