@steerprotocol/data-connector-loader 4.1.0 → 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 +136 -20
- package/lib/bundle/bundleBase.d.ts +11 -14
- package/lib/bundle/bundleBase.js +58 -90
- 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 +79 -93
- package/lib/esm/bundle/bundleDataConnector.d.ts +2 -6
- package/lib/esm/bundle/bundleDataConnector.js +26 -49
- package/lib/esm/execution/executionApp.d.ts +18 -17
- package/lib/esm/execution/executionApp.js +390 -370
- package/lib/esm/execution/executionBase.d.ts +6 -6
- package/lib/esm/execution/executionBase.js +27 -13
- package/lib/esm/execution/executionDataConnector.d.ts +7 -4
- package/lib/esm/execution/executionDataConnector.js +143 -76
- package/lib/esm/index.d.ts +7 -7
- package/lib/esm/index.js +4 -4
- package/lib/esm/types.d.ts +23 -25
- 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 +18 -17
- package/lib/execution/executionApp.js +379 -364
- package/lib/execution/executionBase.d.ts +6 -6
- package/lib/execution/executionBase.js +27 -13
- package/lib/execution/executionDataConnector.d.ts +7 -4
- package/lib/execution/executionDataConnector.js +146 -71
- package/lib/index.d.ts +7 -7
- package/lib/index.js +1 -1
- package/lib/package.json +1 -0
- package/lib/types.d.ts +23 -25
- 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 +22 -17
package/lib/esm/utils/consts.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
export const API_BASE_URL =
|
|
1
|
+
export const API_BASE_URL = "https://cvrlulno2m.execute-api.ap-southeast-1.amazonaws.com/dev/contract-view-call";
|
|
2
2
|
// export const API_BASE_URL = "http://localhost:3000/dev/contract-view-call";
|
|
3
3
|
export const API_MAX_RETRIES = 3;
|
|
4
4
|
export const API_INITIAL_DELAY = 1000;
|
|
5
5
|
export const CENTRALIZE_CONTRACT_INTERACTION_CHAINS = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
35
|
// "8453",
|
|
36
|
-
|
|
36
|
+
"30",
|
|
37
37
|
// "8453",
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
"167000",
|
|
39
|
+
"196",
|
|
40
|
+
"810180",
|
|
41
|
+
"137",
|
|
42
|
+
"314",
|
|
43
|
+
"33139",
|
|
44
|
+
"7000",
|
|
45
|
+
"3338",
|
|
46
46
|
];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import axios from
|
|
1
|
+
import axios from "axios";
|
|
2
2
|
export class PluginManager {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.registeredPluginConfigs = [];
|
|
5
5
|
}
|
|
6
6
|
async registerFromPublicConfig() {
|
|
7
|
-
const { data: dataConnectorPlugins } = await axios.get(
|
|
7
|
+
const { data: dataConnectorPlugins } = await axios.get("https://ro81h8hq6b.execute-api.us-east-1.amazonaws.com/data-connector-plugins");
|
|
8
8
|
for (const plugin of dataConnectorPlugins) {
|
|
9
9
|
this.registerPluginConfig(plugin.name, plugin.domain, plugin.headers);
|
|
10
10
|
}
|
|
@@ -26,7 +26,7 @@ export class PluginManager {
|
|
|
26
26
|
const envValue = process.env[envVar];
|
|
27
27
|
if (envValue === undefined) {
|
|
28
28
|
console.log(`Environment variable '${envVar}' not found.`);
|
|
29
|
-
return
|
|
29
|
+
return "";
|
|
30
30
|
}
|
|
31
31
|
return envValue;
|
|
32
32
|
});
|
|
@@ -34,13 +34,14 @@ export class PluginManager {
|
|
|
34
34
|
interpolateHeaders(headers) {
|
|
35
35
|
const interpolatedHeaders = {};
|
|
36
36
|
for (const [key, value] of Object.entries(headers)) {
|
|
37
|
-
interpolatedHeaders[key] =
|
|
37
|
+
interpolatedHeaders[key] =
|
|
38
|
+
typeof value === "string" ? this.interpolateEnvVars(value) : value;
|
|
38
39
|
}
|
|
39
40
|
return interpolatedHeaders;
|
|
40
41
|
}
|
|
41
42
|
async process(config) {
|
|
42
43
|
if (!config.url) {
|
|
43
|
-
throw new Error(
|
|
44
|
+
throw new Error("Request URL is not provided");
|
|
44
45
|
}
|
|
45
46
|
const matchingHeaders = this.findMatchingPluginConfigs(config.url);
|
|
46
47
|
const interpolatedHeaders = this.interpolateHeaders(matchingHeaders);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export class SubgraphUrlReplacer {
|
|
2
2
|
constructor(config) {
|
|
3
|
-
this.subgraphStudioKey = config?.subgraphStudioKey ??
|
|
3
|
+
this.subgraphStudioKey = config?.subgraphStudioKey ?? "";
|
|
4
4
|
this.subgraphUrlConfigs = config?.customConfigs || this.getDefaultConfigs();
|
|
5
5
|
}
|
|
6
6
|
changeUrlIfOld(url) {
|
|
@@ -8,108 +8,126 @@ export class SubgraphUrlReplacer {
|
|
|
8
8
|
if (subgraphUrl) {
|
|
9
9
|
return subgraphUrl.newUrl;
|
|
10
10
|
}
|
|
11
|
+
// This retired Arbitrum Uniswap subgraph also appears in credential-bearing
|
|
12
|
+
// gateway URLs. Replace only its exact ID; never carry the embedded key over.
|
|
13
|
+
if (url) {
|
|
14
|
+
try {
|
|
15
|
+
const source = new URL(url);
|
|
16
|
+
if ((source.origin === "https://gateway.thegraph.com" ||
|
|
17
|
+
source.origin ===
|
|
18
|
+
"https://gateway-arbitrum.network.thegraph.com") &&
|
|
19
|
+
!source.username &&
|
|
20
|
+
!source.password &&
|
|
21
|
+
/^\/api\/(?:[^/]+\/)?subgraphs\/id\/Fo8QBLpEGfXHWkGMD3jSM4vVLk4JxvxxQD3v3U4fsrbh$/.test(source.pathname)) {
|
|
22
|
+
return this.getArbitrumSubgraphUrl("FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM", false);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Leave malformed or relative URLs for the request handler to process.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
return url;
|
|
12
30
|
}
|
|
13
31
|
getArbitrumSubgraphUrl(subgraphId, isDeploymentId) {
|
|
14
|
-
return `https://gateway-arbitrum.network.thegraph.com/api/${this.subgraphStudioKey}
|
|
32
|
+
return `https://gateway-arbitrum.network.thegraph.com/api/${this.subgraphStudioKey ? `${this.subgraphStudioKey}/` : ""}${isDeploymentId ? "deployments" : "subgraphs"}/id/${subgraphId}`;
|
|
15
33
|
}
|
|
16
34
|
getDefaultConfigs() {
|
|
17
35
|
return [
|
|
18
36
|
{
|
|
19
|
-
chain:
|
|
20
|
-
protocol:
|
|
37
|
+
chain: "polygon",
|
|
38
|
+
protocol: "quickswap",
|
|
21
39
|
newUrl: this.getArbitrumSubgraphUrl(`FqsRcH1XqSjqVx9GRTvEJe959aCbKrcyGgDWBrUkG24g`, false),
|
|
22
|
-
oldUrl:
|
|
40
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sameepsi/quickswap-v3",
|
|
23
41
|
},
|
|
24
42
|
{
|
|
25
|
-
chain:
|
|
26
|
-
protocol:
|
|
43
|
+
chain: "polygon",
|
|
44
|
+
protocol: "uniswap",
|
|
27
45
|
newUrl: this.getArbitrumSubgraphUrl(`3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm`, false),
|
|
28
|
-
oldUrl:
|
|
46
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon",
|
|
29
47
|
},
|
|
30
48
|
{
|
|
31
|
-
chain:
|
|
32
|
-
protocol:
|
|
49
|
+
chain: "optimism",
|
|
50
|
+
protocol: "uniswap",
|
|
33
51
|
newUrl: this.getArbitrumSubgraphUrl(`Cghf4LfVqPiFw6fp6Y5X5Ubc8UpmUhSfJL82zwiBFLaj`, false),
|
|
34
|
-
oldUrl:
|
|
52
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis",
|
|
35
53
|
},
|
|
36
54
|
{
|
|
37
|
-
chain:
|
|
38
|
-
protocol:
|
|
55
|
+
chain: "arbitrum",
|
|
56
|
+
protocol: "uniswap",
|
|
39
57
|
newUrl: this.getArbitrumSubgraphUrl(`FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM`, false),
|
|
40
|
-
oldUrl:
|
|
58
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/ianlapham/arbitrum-dev",
|
|
41
59
|
},
|
|
42
60
|
{
|
|
43
|
-
chain:
|
|
44
|
-
protocol:
|
|
61
|
+
chain: "celo",
|
|
62
|
+
protocol: "uniswap",
|
|
45
63
|
newUrl: this.getArbitrumSubgraphUrl(`ESdrTJ3twMwWVoQ1hUE2u7PugEHX3QkenudD6aXCkDQ4`, false),
|
|
46
|
-
oldUrl:
|
|
64
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo",
|
|
47
65
|
},
|
|
48
66
|
{
|
|
49
|
-
chain:
|
|
50
|
-
protocol:
|
|
51
|
-
newUrl:
|
|
52
|
-
oldUrl:
|
|
67
|
+
chain: "base",
|
|
68
|
+
protocol: "baseswap",
|
|
69
|
+
newUrl: "https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/v3-base/prod/gn",
|
|
70
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/harleen-m/basex",
|
|
53
71
|
},
|
|
54
72
|
{
|
|
55
|
-
chain:
|
|
56
|
-
protocol:
|
|
57
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
58
|
-
oldUrl:
|
|
73
|
+
chain: "arbitrum",
|
|
74
|
+
protocol: "sushi",
|
|
75
|
+
newUrl: this.getArbitrumSubgraphUrl("QmevuQAmgiou1UX7Z2BQf6RKdX1WunQjH8VtawhkzSLj4V", true),
|
|
76
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sushi-v3/v3-arbitrum",
|
|
59
77
|
},
|
|
60
78
|
{
|
|
61
|
-
chain:
|
|
62
|
-
protocol:
|
|
63
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
64
|
-
oldUrl:
|
|
79
|
+
chain: "avalanche",
|
|
80
|
+
protocol: "sushi",
|
|
81
|
+
newUrl: this.getArbitrumSubgraphUrl("Qmcdd4SGVwG9VY4itrXBnBPWBVsQvsxfzaib9bVny9C8jT", true),
|
|
82
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sushi-v3/v3-avalanche",
|
|
65
83
|
},
|
|
66
84
|
{
|
|
67
|
-
chain:
|
|
68
|
-
protocol:
|
|
69
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
70
|
-
oldUrl:
|
|
85
|
+
chain: "bsc",
|
|
86
|
+
protocol: "sushi",
|
|
87
|
+
newUrl: this.getArbitrumSubgraphUrl("FiJDXMFCBv88GP17g2TtPh8BcA8jZozn5WRW7hCN7cUT", false),
|
|
88
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sushi-v3/v3-bsc",
|
|
71
89
|
},
|
|
72
90
|
{
|
|
73
|
-
chain:
|
|
74
|
-
protocol:
|
|
75
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
76
|
-
oldUrl:
|
|
91
|
+
chain: "base",
|
|
92
|
+
protocol: "sushi",
|
|
93
|
+
newUrl: this.getArbitrumSubgraphUrl("QmZ2R9ABG9ienaZdGyPLcDWDNDkG187RhXmh6fFuEtUaaS", true),
|
|
94
|
+
oldUrl: "https://api.studio.thegraph.com/query/32073/v3-base/v0.0.1",
|
|
77
95
|
},
|
|
78
96
|
{
|
|
79
|
-
chain:
|
|
80
|
-
protocol:
|
|
81
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
82
|
-
oldUrl:
|
|
97
|
+
chain: "optimism",
|
|
98
|
+
protocol: "sushi",
|
|
99
|
+
newUrl: this.getArbitrumSubgraphUrl("QmbT6ZsxJEZKUrbzLrAWV5EnQfSKZeYtZ265mQUaB552vK", true),
|
|
100
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sushi-v3/v3-optimism",
|
|
83
101
|
},
|
|
84
102
|
{
|
|
85
|
-
chain:
|
|
86
|
-
protocol:
|
|
87
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
88
|
-
oldUrl:
|
|
103
|
+
chain: "polygon",
|
|
104
|
+
protocol: "sushi",
|
|
105
|
+
newUrl: this.getArbitrumSubgraphUrl("QmPbbjK9vtY69kSxMJRVLVz1dRzUBNwYbWTRYMiFzp9Tzm", true),
|
|
106
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/sushi-v3/v3-polygon",
|
|
89
107
|
},
|
|
90
108
|
{
|
|
91
|
-
chain:
|
|
92
|
-
protocol:
|
|
93
|
-
newUrl: this.getArbitrumSubgraphUrl(
|
|
94
|
-
oldUrl:
|
|
109
|
+
chain: "zkevm",
|
|
110
|
+
protocol: "sushi",
|
|
111
|
+
newUrl: this.getArbitrumSubgraphUrl("QmWH5ChjmF4Yp5Yhiaxczh5QwbG6HFSEi8bRwbKaUrJA6C", true),
|
|
112
|
+
oldUrl: "https://api.studio.thegraph.com/query/32073/v3-polygon-zkevm/v0.0.2",
|
|
95
113
|
},
|
|
96
114
|
{
|
|
97
|
-
chain:
|
|
98
|
-
protocol:
|
|
99
|
-
newUrl:
|
|
100
|
-
oldUrl:
|
|
115
|
+
chain: "arbitrum",
|
|
116
|
+
protocol: "camelot",
|
|
117
|
+
newUrl: "https://subgraph-proxy-server-xf2uthetka-as.a.run.app/gateway-arbitrum/3utanEBA9nqMjPnuQP1vMCCys6enSM3EawBpKTVwnUw2",
|
|
118
|
+
oldUrl: "https://api.thegraph.com/subgraphs/name/camelotlabs/camelot-amm-v3",
|
|
101
119
|
},
|
|
102
120
|
{
|
|
103
|
-
chain:
|
|
104
|
-
protocol:
|
|
105
|
-
newUrl:
|
|
106
|
-
oldUrl:
|
|
121
|
+
chain: "mode",
|
|
122
|
+
protocol: "swapmode",
|
|
123
|
+
newUrl: "https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/swapmode-v3/prod/gn",
|
|
124
|
+
oldUrl: "https://api.goldsky.com/api/public/project_cltceeuudv1ij01x7ekxhfl46/subgraphs/swapmode-v3/1.0.0/gn",
|
|
107
125
|
},
|
|
108
126
|
{
|
|
109
|
-
chain:
|
|
110
|
-
protocol:
|
|
111
|
-
newUrl:
|
|
112
|
-
oldUrl:
|
|
127
|
+
chain: "linea",
|
|
128
|
+
protocol: "lynex",
|
|
129
|
+
newUrl: "https://api.goldsky.com/api/public/project_cltyhthusbmxp01s95k9l8a1u/subgraphs/lynex-cl/v1.0.2/gn",
|
|
130
|
+
oldUrl: "https://graph-query.linea.build/subgraphs/name/cryptoalgebra/analytics",
|
|
113
131
|
},
|
|
114
132
|
];
|
|
115
133
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createPublicClient, custom, fallback, http, } from "viem";
|
|
2
|
+
/** Each URL is checked on the same transport that will serve its reads. */
|
|
3
|
+
export function createRpcClient(access, chainId) {
|
|
4
|
+
if (!Number.isSafeInteger(chainId) || chainId <= 0)
|
|
5
|
+
throw new Error("Invalid execution chain ID");
|
|
6
|
+
if (access.client)
|
|
7
|
+
return access.client;
|
|
8
|
+
const urls = [
|
|
9
|
+
...new Set(access.urls.map((url) => url.trim()).filter(Boolean)),
|
|
10
|
+
];
|
|
11
|
+
if (!urls.length)
|
|
12
|
+
throw new Error("No RPC URLs configured");
|
|
13
|
+
const transports = urls.map((url) => {
|
|
14
|
+
const endpoint = createPublicClient({
|
|
15
|
+
transport: http(url, { retryCount: 0 }),
|
|
16
|
+
});
|
|
17
|
+
return custom({
|
|
18
|
+
async request({ method, params }) {
|
|
19
|
+
const actualChain = await endpoint.getChainId();
|
|
20
|
+
if (actualChain !== chainId) {
|
|
21
|
+
throw new Error("EXECUTION_CONTEXT_MISMATCH: provider chain does not match supplied context.");
|
|
22
|
+
}
|
|
23
|
+
if (method === "eth_chainId")
|
|
24
|
+
return `0x${actualChain.toString(16)}`;
|
|
25
|
+
return endpoint.request({ method, params });
|
|
26
|
+
},
|
|
27
|
+
}, { retryCount: 0 });
|
|
28
|
+
});
|
|
29
|
+
return createPublicClient({
|
|
30
|
+
transport: fallback(transports, { rank: false, retryCount: 0 }),
|
|
31
|
+
});
|
|
32
|
+
}
|
package/lib/esm/utils/utils.d.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import type { Candle } from
|
|
2
|
-
import type { AxiosRequestConfig } from
|
|
3
|
-
import { type
|
|
4
|
-
import type {
|
|
1
|
+
import type { Candle } from "@steerprotocol/app-loader";
|
|
2
|
+
import type { AxiosRequestConfig } from "axios";
|
|
3
|
+
import { type PublicClient } from "viem";
|
|
4
|
+
import type { ContractAbi, ExecutionContext } from "../types.js";
|
|
5
5
|
export declare const extendOHLCV: (rawData: Array<Candle>, period: number, endTimestamp: number) => Array<Candle>;
|
|
6
6
|
export declare function fetchData(request: AxiosRequestConfig, attempts: number): Promise<any>;
|
|
7
|
-
export declare function readContract({ abi, address,
|
|
7
|
+
export declare function readContract({ abi, address, contractArguments, currentExecutionContext, functionName, provider, }: {
|
|
8
8
|
address: string;
|
|
9
|
-
abi:
|
|
10
|
-
currentExecutionContext
|
|
9
|
+
abi: ContractAbi;
|
|
10
|
+
currentExecutionContext?: Pick<ExecutionContext, "blockNumber">;
|
|
11
11
|
functionName: string;
|
|
12
|
-
provider:
|
|
13
|
-
rpc: string;
|
|
12
|
+
provider: PublicClient;
|
|
14
13
|
contractArguments?: Array<any>;
|
|
15
|
-
chainId: number;
|
|
16
14
|
}): Promise<any>;
|
|
17
|
-
export declare function callWithRetry(config: ViewContractConfig): Promise<any>;
|
package/lib/esm/utils/utils.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import axios from
|
|
2
|
-
import {
|
|
3
|
-
import { API_BASE_URL, API_INITIAL_DELAY, API_MAX_RETRIES, CENTRALIZE_CONTRACT_INTERACTION_CHAINS } from './consts.js';
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { getAbiItem, parseAbi, parseAbiItem, toFunctionSelector, } from "viem";
|
|
4
3
|
// 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
4
|
export const extendOHLCV = (rawData, period, endTimestamp) => {
|
|
6
5
|
// Sort rawData by timestamp
|
|
@@ -31,22 +30,25 @@ async function delay(ms) {
|
|
|
31
30
|
function exponentialBackoffDelay(attempts) {
|
|
32
31
|
const baseDelay = 1000; // 1 second
|
|
33
32
|
const maxDelay = 30000; // 30 seconds
|
|
34
|
-
const delay = Math.min(baseDelay *
|
|
33
|
+
const delay = Math.min(baseDelay * 2 ** (attempts - 1), maxDelay);
|
|
35
34
|
return delay;
|
|
36
35
|
}
|
|
37
36
|
export async function fetchData(request, attempts) {
|
|
38
|
-
log(
|
|
37
|
+
log("Request payload: =============", request);
|
|
39
38
|
attempts = attempts + 1;
|
|
40
39
|
try {
|
|
41
40
|
const response = (await axios(request)).data;
|
|
42
41
|
// this.log('API Response: =============', response);
|
|
43
|
-
if (
|
|
42
|
+
if (response !== null &&
|
|
43
|
+
typeof response === "object" &&
|
|
44
|
+
Array.isArray(response.errors) &&
|
|
45
|
+
response.errors.length > 0) {
|
|
44
46
|
if (attempts < 3) {
|
|
45
47
|
await delay(exponentialBackoffDelay(attempts));
|
|
46
48
|
return await fetchData(request, attempts);
|
|
47
49
|
}
|
|
48
50
|
else {
|
|
49
|
-
throw new Error(
|
|
51
|
+
throw new Error("Maximum retry attempts reached");
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
return response;
|
|
@@ -61,59 +63,63 @@ export async function fetchData(request, attempts) {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// For formatting the parameters if needed
|
|
70
|
-
const paramsArray = contractArguments || [];
|
|
71
|
-
// Calculate block number for determinism
|
|
72
|
-
// Best way to handle contextually non-null values?
|
|
73
|
-
// const syncedBlock = await getBlockFromTimestamp(this.executionContext!.epochTimestamp, this.providerIdentity!) //@note uncomment for deterministic blocks
|
|
74
|
-
// Call the desired method with the specified arguments at synced block
|
|
75
|
-
// , {blockTag: syncedBlock}
|
|
76
|
-
let result;
|
|
77
|
-
if (CENTRALIZE_CONTRACT_INTERACTION_CHAINS.indexOf(chainId.toString()) === -1) {
|
|
78
|
-
result = await contract[functionName](...paramsArray, {
|
|
79
|
-
blockTag: currentExecutionContext?.blockNumber,
|
|
80
|
-
}); // @note uncomment for deterministic blocks
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
console.log('Calling the centralized view');
|
|
84
|
-
const viewContractConfig = {
|
|
85
|
-
epochTimestamp: currentExecutionContext.epochTimestamp,
|
|
86
|
-
blockNumber: currentExecutionContext.blockNumber,
|
|
87
|
-
address,
|
|
88
|
-
abi,
|
|
89
|
-
arguments: paramsArray,
|
|
90
|
-
method: functionName,
|
|
91
|
-
rpcUrl: rpc,
|
|
66
|
+
function positionalTuple(value, parameter) {
|
|
67
|
+
if (/\[[0-9]*\]$/.test(parameter.type)) {
|
|
68
|
+
const item = {
|
|
69
|
+
...parameter,
|
|
70
|
+
type: parameter.type.replace(/\[[0-9]*\]$/, ""),
|
|
92
71
|
};
|
|
93
|
-
|
|
72
|
+
return value.map((entry) => positionalTuple(entry, item));
|
|
94
73
|
}
|
|
95
|
-
|
|
96
|
-
|
|
74
|
+
if (parameter.type !== "tuple" || !("components" in parameter))
|
|
75
|
+
return value;
|
|
76
|
+
return parameter.components.map((component, index) => positionalTuple(Array.isArray(value) ? value[index] : value[component.name], component));
|
|
97
77
|
}
|
|
98
|
-
export async function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
78
|
+
export async function readContract({ abi, address, contractArguments = [], currentExecutionContext, functionName, provider, }) {
|
|
79
|
+
if (!provider)
|
|
80
|
+
throw new Error("Provider not initialized");
|
|
81
|
+
const input = typeof abi === "string" ? JSON.parse(abi) : abi;
|
|
82
|
+
// Existing bundles may use ethers' optional tuple keyword.
|
|
83
|
+
const normalizeSignature = (signature) => signature.replace(/\btuple\s*\(/g, "(");
|
|
84
|
+
const normalizedAbi = (input.every((item) => typeof item === "string")
|
|
85
|
+
? parseAbi(input.map(normalizeSignature))
|
|
86
|
+
: input);
|
|
87
|
+
const explicit = functionName.includes("(")
|
|
88
|
+
? parseAbiItem(`function ${normalizeSignature(functionName)}`)
|
|
89
|
+
: undefined;
|
|
90
|
+
if (explicit && explicit.type !== "function")
|
|
91
|
+
throw new Error("Expected a function signature");
|
|
92
|
+
const selectedAbi = explicit
|
|
93
|
+
? normalizedAbi.filter((item) => item.type === "function" &&
|
|
94
|
+
toFunctionSelector(item) === toFunctionSelector(explicit))
|
|
95
|
+
: normalizedAbi;
|
|
96
|
+
if (explicit && !selectedAbi.length)
|
|
97
|
+
throw new Error(`Function ${functionName} not found in ABI`);
|
|
98
|
+
const resolvedName = explicit && "name" in explicit ? explicit.name : functionName;
|
|
99
|
+
const result = await provider.readContract({
|
|
100
|
+
address: address,
|
|
101
|
+
abi: selectedAbi,
|
|
102
|
+
functionName: resolvedName,
|
|
103
|
+
args: contractArguments,
|
|
104
|
+
...(currentExecutionContext?.blockNumber !== undefined
|
|
105
|
+
? { blockNumber: BigInt(currentExecutionContext.blockNumber) }
|
|
106
|
+
: {}),
|
|
107
|
+
});
|
|
108
|
+
const item = getAbiItem({
|
|
109
|
+
abi: selectedAbi,
|
|
110
|
+
name: resolvedName,
|
|
111
|
+
args: contractArguments,
|
|
112
|
+
});
|
|
113
|
+
if (!item || item.type !== "function")
|
|
114
|
+
return result;
|
|
115
|
+
if (!item.outputs?.length)
|
|
116
|
+
return [];
|
|
117
|
+
return item.outputs.length === 1
|
|
118
|
+
? positionalTuple(result, item.outputs[0])
|
|
119
|
+
: item.outputs.map((output, index) => positionalTuple(result[index], output));
|
|
114
120
|
}
|
|
115
121
|
function log(...args) {
|
|
116
|
-
if (process.env.DEBUG ===
|
|
122
|
+
if (process.env.DEBUG === "true") {
|
|
117
123
|
console.log(...args);
|
|
118
124
|
}
|
|
119
125
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
3
|
-
import { ExecutionBase } from './executionBase.js';
|
|
1
|
+
import type { ExecuteWithContextOptions, JobDetails, RpcAccess } from "../types.js";
|
|
2
|
+
import { ExecutionBase } from "./executionBase.js";
|
|
4
3
|
export interface ExecutionAppConfig {
|
|
5
4
|
/** Vault address used for execution context and subgraph queries. */
|
|
6
5
|
vault: string;
|
|
7
6
|
/** Chain ID used to resolve RPC configuration and on-chain reads. */
|
|
8
7
|
chainId: number;
|
|
9
|
-
/**
|
|
10
|
-
steerSubgraph
|
|
11
|
-
|
|
8
|
+
/** Required by execute() for protocol discovery queries. */
|
|
9
|
+
steerSubgraph?: string;
|
|
10
|
+
/** Required by execute() for pool discovery; unused by executeWithContext(). */
|
|
11
|
+
poolType?: {
|
|
12
12
|
/** Set true when the pool uses Algebra v1 semantics. */
|
|
13
13
|
isAlgebraPool: boolean;
|
|
14
14
|
/** Set true when the pool uses Algebra Integral semantics. */
|
|
@@ -20,11 +20,11 @@ export interface ExecutionAppConfig {
|
|
|
20
20
|
/** Set true when the pool uses Aerodrome semantics. */
|
|
21
21
|
isAerodromePool: boolean;
|
|
22
22
|
};
|
|
23
|
-
apiKeys
|
|
24
|
-
/**
|
|
25
|
-
subgraphStudioKey
|
|
23
|
+
apiKeys?: {
|
|
24
|
+
/** Host-only Graph credential; never added to WASM configuration. */
|
|
25
|
+
subgraphStudioKey?: string;
|
|
26
26
|
/** API key for Sentio endpoints, if applicable. */
|
|
27
|
-
sentioApiKey
|
|
27
|
+
sentioApiKey?: string;
|
|
28
28
|
};
|
|
29
29
|
/** Maximum number of retries for execution operations. */
|
|
30
30
|
maxRetries?: number;
|
|
@@ -38,22 +38,23 @@ export declare class ExecutionApp extends ExecutionBase {
|
|
|
38
38
|
isDirectionalPool: boolean;
|
|
39
39
|
isPoolSharkPool: boolean;
|
|
40
40
|
isAerodromePool: boolean;
|
|
41
|
-
subgraphStudioKey: string;
|
|
42
41
|
sentioApiKey: string;
|
|
43
42
|
config: ExecutionAppConfig;
|
|
44
43
|
constructor(config: ExecutionAppConfig);
|
|
45
|
-
execute<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>,
|
|
44
|
+
execute<T = unknown>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, rpc?: RpcAccess, forceDeposit?: boolean): Promise<T | "continue">;
|
|
46
45
|
/**
|
|
47
|
-
* Executes a strategy against
|
|
46
|
+
* Executes a strategy against a supplied execution context.
|
|
48
47
|
* This is the recommended API for new consumers. It intentionally bypasses
|
|
49
48
|
* all legacy vault, pool, subgraph, clock, and block-estimation reads.
|
|
50
49
|
*/
|
|
51
|
-
executeWithContext<T>(options: ExecuteWithContextOptions): Promise<
|
|
50
|
+
executeWithContext<T = unknown>(options: ExecuteWithContextOptions): Promise<T | "continue">;
|
|
51
|
+
/** T is the complete decoded JSON result. Only the exact sentinel skips JSON decoding. */
|
|
52
|
+
private parseStrategyResult;
|
|
52
53
|
private parseVaultConfig;
|
|
53
|
-
private
|
|
54
|
+
private validateExecutionContext;
|
|
54
55
|
private redactError;
|
|
55
|
-
executeStabilityVault<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>,
|
|
56
|
-
executeDynamicJobs<T>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails,
|
|
56
|
+
executeStabilityVault<T = unknown>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, rpc?: RpcAccess, forceDeposit?: boolean): Promise<T | "continue">;
|
|
57
|
+
executeDynamicJobs<T = unknown>(_wasmFile: string | ArrayBuffer, _vaultConfig: string, _data: Array<any>, _job: JobDetails, rpc?: RpcAccess, forceDeposit?: boolean): Promise<T | "continue">;
|
|
57
58
|
private getSmartPoolExecutionContext;
|
|
58
59
|
private getPoolCurrentTick;
|
|
59
60
|
private getTickSpacing;
|