@defillama/sdk 5.0.146 → 5.0.147
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/build/generalUtil.d.ts +1 -1
- package/build/generalUtil.js +2 -1
- package/build/providers.json +1 -1
- package/build/util/cache.d.ts +4 -2
- package/build/util/cache.js +30 -16
- package/build/util/index.d.ts +1 -0
- package/build/util/index.js +32 -1
- package/build/util/indexer.d.ts +16 -13
- package/build/util/indexer.js +295 -352
- package/build/util/logs.d.ts +19 -1
- package/build/util/logs.js +258 -122
- package/package.json +1 -1
package/build/util/indexer.js
CHANGED
|
@@ -3,9 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.isIndexer2Enabled = exports.isIndexerEnabled = exports.getTransactions = exports.getTokenTransfers = exports.getLogs = exports.getTokens = exports.supportedChainSet2 = exports.supportedChainSet = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
const ethers_1 = require("ethers");
|
|
9
8
|
const _1 = require(".");
|
|
10
9
|
const general_1 = require("../general");
|
|
11
10
|
const generalUtil_1 = require("../generalUtil");
|
|
@@ -14,74 +13,51 @@ const cache_1 = require("./cache");
|
|
|
14
13
|
const debugLog_1 = require("./debugLog");
|
|
15
14
|
const env_1 = require("./env");
|
|
16
15
|
const logs_1 = require("./logs");
|
|
17
|
-
const indexerURL = (0, env_1.getEnvValue)(
|
|
18
|
-
const LLAMA_INDEXER_API_KEY = (0, env_1.getEnvValue)(
|
|
19
|
-
const LLAMA_INDEXER_V2_ENDPOINT = (0, env_1.getEnvValue)(
|
|
20
|
-
const LLAMA_INDEXER_V2_API_KEY = (0, env_1.getEnvValue)(
|
|
21
|
-
const addressChunkSize = +(0, env_1.getEnvValue)(
|
|
16
|
+
const indexerURL = (0, env_1.getEnvValue)("LLAMA_INDEXER_ENDPOINT");
|
|
17
|
+
const LLAMA_INDEXER_API_KEY = (0, env_1.getEnvValue)("LLAMA_INDEXER_API_KEY");
|
|
18
|
+
const LLAMA_INDEXER_V2_ENDPOINT = (0, env_1.getEnvValue)("LLAMA_INDEXER_V2_ENDPOINT");
|
|
19
|
+
const LLAMA_INDEXER_V2_API_KEY = (0, env_1.getEnvValue)("LLAMA_INDEXER_V2_API_KEY");
|
|
20
|
+
const addressChunkSize = +(0, env_1.getEnvValue)("LLAMA_INDEXER_ADDRESS_CHUNK_SIZE") || 100;
|
|
21
|
+
// v1 chains (still used for balances endpoint) -------------------------------------------------
|
|
22
22
|
const indexerChainIdChainMapping = {
|
|
23
|
-
1:
|
|
24
|
-
10:
|
|
25
|
-
56:
|
|
26
|
-
100:
|
|
27
|
-
137:
|
|
28
|
-
204:
|
|
29
|
-
250:
|
|
30
|
-
324:
|
|
31
|
-
1101:
|
|
32
|
-
8453:
|
|
33
|
-
34443:
|
|
34
|
-
42170:
|
|
35
|
-
42161:
|
|
36
|
-
43114:
|
|
37
|
-
59144:
|
|
38
|
-
81457:
|
|
39
|
-
534352:
|
|
40
|
-
146:
|
|
23
|
+
1: "ethereum",
|
|
24
|
+
10: "optimism",
|
|
25
|
+
56: "bsc",
|
|
26
|
+
100: "xdai",
|
|
27
|
+
137: "polygon",
|
|
28
|
+
204: "op_bnb",
|
|
29
|
+
250: "fantom",
|
|
30
|
+
324: "era",
|
|
31
|
+
1101: "polygon_zkevm",
|
|
32
|
+
8453: "base",
|
|
33
|
+
34443: "mode",
|
|
34
|
+
42170: "arbitrum_nova",
|
|
35
|
+
42161: "arbitrum",
|
|
36
|
+
43114: "avax",
|
|
37
|
+
59144: "linea",
|
|
38
|
+
81457: "blast",
|
|
39
|
+
534352: "scroll",
|
|
40
|
+
146: "sonic",
|
|
41
41
|
};
|
|
42
|
+
// v2 chains (superset of v1)
|
|
42
43
|
const indexer2ChainIdChainMapping = {
|
|
43
44
|
...indexerChainIdChainMapping,
|
|
44
|
-
130:
|
|
45
|
-
1868:
|
|
46
|
-
80094:
|
|
47
|
-
999:
|
|
45
|
+
130: "unichain",
|
|
46
|
+
1868: "soneium",
|
|
47
|
+
80094: "berachain",
|
|
48
|
+
999: "hyperliquid",
|
|
48
49
|
};
|
|
49
|
-
const state = { chainIndexStatus: {} };
|
|
50
|
-
const cacheTime = 1 * 60 * 1000; // 1 minutes - we cache sync status for 1 minute
|
|
51
|
-
async function getChainIndexStatus(version = 'v1') {
|
|
52
|
-
checkIndexerConfig(version);
|
|
53
|
-
if (state.timestamp && (Date.now() - state.timestamp) < cacheTime)
|
|
54
|
-
return state.chainIndexStatus;
|
|
55
|
-
state.timestamp = Date.now();
|
|
56
|
-
state.chainIndexStatus = _getState();
|
|
57
|
-
return state.chainIndexStatus;
|
|
58
|
-
async function _getState() {
|
|
59
|
-
const { data: { syncStatus } } = await axiosInstances[version].get(`/sync`);
|
|
60
|
-
const syncInfo = {};
|
|
61
|
-
syncStatus.forEach((d) => {
|
|
62
|
-
const chain = indexerConfigs[version].chainMapping[d.chain];
|
|
63
|
-
if (chain) {
|
|
64
|
-
syncInfo[chain] = {
|
|
65
|
-
block: d.lastIndexedBlock,
|
|
66
|
-
timestamp: +new Date(d.lastIndexedDate)
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
state.chainIndexStatus = syncInfo;
|
|
71
|
-
return syncInfo;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
50
|
const indexerConfigs = {
|
|
75
51
|
v1: {
|
|
76
52
|
endpoint: indexerURL,
|
|
77
53
|
apiKey: LLAMA_INDEXER_API_KEY,
|
|
78
|
-
chainMapping: indexerChainIdChainMapping
|
|
54
|
+
chainMapping: indexerChainIdChainMapping,
|
|
79
55
|
},
|
|
80
56
|
v2: {
|
|
81
57
|
endpoint: LLAMA_INDEXER_V2_ENDPOINT,
|
|
82
58
|
apiKey: LLAMA_INDEXER_V2_API_KEY,
|
|
83
|
-
chainMapping: indexer2ChainIdChainMapping
|
|
84
|
-
}
|
|
59
|
+
chainMapping: indexer2ChainIdChainMapping,
|
|
60
|
+
},
|
|
85
61
|
};
|
|
86
62
|
const axiosInstances = {
|
|
87
63
|
v1: axios_1.default.create({
|
|
@@ -91,53 +67,83 @@ const axiosInstances = {
|
|
|
91
67
|
v2: axios_1.default.create({
|
|
92
68
|
headers: { "x-api-key": indexerConfigs.v2.apiKey },
|
|
93
69
|
baseURL: indexerConfigs.v2.endpoint,
|
|
94
|
-
})
|
|
70
|
+
}),
|
|
95
71
|
};
|
|
96
72
|
function checkIndexerConfig(version) {
|
|
97
73
|
const config = indexerConfigs[version];
|
|
98
74
|
if (!config.endpoint || !config.apiKey)
|
|
99
75
|
throw new Error(`Llama Indexer ${version} URL/api key is not set`);
|
|
100
76
|
}
|
|
101
|
-
function getChainId(chain, version =
|
|
77
|
+
function getChainId(chain, version = "v2") {
|
|
102
78
|
var _a;
|
|
103
|
-
const chainId = (_a = Object.entries(indexerConfigs[version].chainMapping)
|
|
104
|
-
.find(([_, chainName]) => chainName === chain)) === null || _a === void 0 ? void 0 : _a[0];
|
|
79
|
+
const chainId = (_a = Object.entries(indexerConfigs[version].chainMapping).find(([, chainName]) => chainName === chain)) === null || _a === void 0 ? void 0 : _a[0];
|
|
105
80
|
if (!chainId)
|
|
106
|
-
throw new Error(
|
|
81
|
+
throw new Error("Chain not supported");
|
|
107
82
|
return +chainId;
|
|
108
83
|
}
|
|
109
|
-
function getSupportedChains(version =
|
|
84
|
+
function getSupportedChains(version = "v2") {
|
|
110
85
|
return new Set(Object.values(indexerConfigs[version].chainMapping));
|
|
111
86
|
}
|
|
112
|
-
exports.supportedChainSet = getSupportedChains(
|
|
113
|
-
exports.supportedChainSet2 = getSupportedChains(
|
|
87
|
+
exports.supportedChainSet = getSupportedChains("v1"); // legacy
|
|
88
|
+
exports.supportedChainSet2 = getSupportedChains("v2");
|
|
114
89
|
const chainToIDMapping = {};
|
|
115
90
|
Object.entries(indexerConfigs.v1.chainMapping).forEach(([id, chain]) => {
|
|
116
|
-
chainToIDMapping[chain] = id;
|
|
91
|
+
chainToIDMapping[chain] = +id;
|
|
117
92
|
});
|
|
118
93
|
const chainToIDMapping2 = {};
|
|
119
94
|
Object.entries(indexerConfigs.v2.chainMapping).forEach(([id, chain]) => {
|
|
120
|
-
chainToIDMapping2[chain] = id;
|
|
95
|
+
chainToIDMapping2[chain] = +id;
|
|
121
96
|
});
|
|
97
|
+
const state = {
|
|
98
|
+
chainIndexStatus: {},
|
|
99
|
+
};
|
|
100
|
+
const cacheTime = 1 * 60 * 1000; // 1 min
|
|
101
|
+
async function getChainIndexStatus(version = "v2") {
|
|
102
|
+
checkIndexerConfig(version);
|
|
103
|
+
if (state.timestamp && Date.now() - state.timestamp < cacheTime)
|
|
104
|
+
return state.chainIndexStatus;
|
|
105
|
+
state.timestamp = Date.now();
|
|
106
|
+
state.chainIndexStatus = (async () => {
|
|
107
|
+
const { data: { syncStatus }, } = await axiosInstances[version].get(`/sync`);
|
|
108
|
+
const info = {};
|
|
109
|
+
syncStatus.forEach((d) => {
|
|
110
|
+
const chain = indexerConfigs[version].chainMapping[d.chain];
|
|
111
|
+
if (chain) {
|
|
112
|
+
info[chain] = {
|
|
113
|
+
block: d.lastIndexedBlock,
|
|
114
|
+
timestamp: +new Date(d.lastIndexedDate),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return (state.chainIndexStatus = info);
|
|
119
|
+
})();
|
|
120
|
+
return state.chainIndexStatus;
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Utilities / Enums / Types
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
122
125
|
var TokenTypes;
|
|
123
126
|
(function (TokenTypes) {
|
|
124
127
|
TokenTypes["ERC20"] = "erc20";
|
|
125
128
|
TokenTypes["ERC721"] = "erc721";
|
|
126
129
|
})(TokenTypes || (TokenTypes = {}));
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Token helpers (still via v1 endpoint)
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
127
133
|
async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = false, skipCache = false, chain, tokenType, } = {}) {
|
|
128
134
|
var _a, _b;
|
|
129
|
-
checkIndexerConfig(
|
|
135
|
+
checkIndexerConfig("v1");
|
|
130
136
|
if (!address)
|
|
131
|
-
throw new Error(
|
|
137
|
+
throw new Error("Address is required either as a string or an array of strings");
|
|
132
138
|
if (Array.isArray(address) && !address.length)
|
|
133
|
-
throw new Error(
|
|
139
|
+
throw new Error("Address array cannot be empty");
|
|
134
140
|
if (Array.isArray(address))
|
|
135
|
-
address = address.join(
|
|
141
|
+
address = address.join(",");
|
|
136
142
|
address = address.toLowerCase();
|
|
137
143
|
let chainId;
|
|
138
144
|
if (chain)
|
|
139
145
|
chainId = chainToIDMapping[chain];
|
|
140
|
-
const project =
|
|
146
|
+
const project = "llama-indexer-cache";
|
|
141
147
|
const key = onlyWhitelisted ? address : `${address}/all`;
|
|
142
148
|
const file = `${project}/${key}`;
|
|
143
149
|
const timeNow = Math.floor(Date.now() / 1e3);
|
|
@@ -145,28 +151,29 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
|
|
|
145
151
|
let cache = {};
|
|
146
152
|
if (!skipCacheRead && !skipCache) {
|
|
147
153
|
cache = (_a = (await (0, cache_1.readCache)(file))) !== null && _a !== void 0 ? _a : {};
|
|
148
|
-
if (cache.timestamp &&
|
|
154
|
+
if (cache.timestamp && timeNow - cache.timestamp < THREE_DAYS)
|
|
149
155
|
return cache.tokens;
|
|
150
156
|
}
|
|
151
|
-
(0, debugLog_1.debugLog)(
|
|
157
|
+
(0, debugLog_1.debugLog)("[Indexer] Pulling tokens for " + address);
|
|
152
158
|
const tokens = (_b = cache.tokens) !== null && _b !== void 0 ? _b : {};
|
|
153
|
-
const { data: { balances } } = await axiosInstances.v1(`/balances`, {
|
|
159
|
+
const { data: { balances }, } = await axiosInstances.v1(`/balances`, {
|
|
154
160
|
params: {
|
|
155
161
|
addresses: address,
|
|
156
162
|
chainId,
|
|
157
163
|
type: tokenType,
|
|
158
164
|
},
|
|
159
165
|
});
|
|
160
|
-
balances
|
|
166
|
+
balances
|
|
167
|
+
.filter((b) => +b.total_amount > 0)
|
|
168
|
+
.forEach((b) => {
|
|
161
169
|
const chain = indexerConfigs.v1.chainMapping[b.chain];
|
|
162
|
-
if (!chain)
|
|
170
|
+
if (!chain)
|
|
163
171
|
return;
|
|
164
|
-
}
|
|
165
172
|
if (!tokens[chain])
|
|
166
173
|
tokens[chain] = [];
|
|
167
174
|
tokens[chain].push(b.address);
|
|
168
175
|
});
|
|
169
|
-
const tokenCache = { timestamp: timeNow, tokens
|
|
176
|
+
const tokenCache = { timestamp: timeNow, tokens };
|
|
170
177
|
Object.entries(tokens).forEach(([chain, values]) => {
|
|
171
178
|
values.push(general_1.ETHER_ADDRESS);
|
|
172
179
|
tokens[chain] = (0, generalUtil_1.getUniqueAddresses)(values);
|
|
@@ -176,239 +183,187 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
|
|
|
176
183
|
return tokens;
|
|
177
184
|
}
|
|
178
185
|
exports.getTokens = getTokens;
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
throw new Error(`Indexer not enabled for chain ${chain}`);
|
|
184
|
-
}
|
|
185
|
-
return 'v1';
|
|
186
|
-
}
|
|
187
|
-
const syncStatus = await getChainIndexStatus('v2');
|
|
188
|
-
const lastIndexedBlock = (_b = (_a = syncStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
189
|
-
if (lastIndexedBlock >= blockNumber) {
|
|
190
|
-
return 'v2';
|
|
191
|
-
}
|
|
192
|
-
return 'v1';
|
|
193
|
-
}
|
|
194
|
-
async function executeWithFallback(chain, blockNumber, v2Fn, v1Fn) {
|
|
195
|
-
const version = await getIndexerVersionForBlock(chain, blockNumber);
|
|
196
|
-
try {
|
|
197
|
-
return version === 'v2' ? await v2Fn() : await v1Fn();
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
if (version === 'v2') {
|
|
201
|
-
console.log(`Fallback to v1 for chain ${chain} due to error:`, error);
|
|
202
|
-
return v1Fn();
|
|
203
|
-
}
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock, all = true, limit = 1000, offset = 0, target, targets, eventAbi, entireLog = false, flatten = true, extraTopics, fromTimestamp, toTimestamp, debugMode = false, noTarget = false, parseLog = true, }) {
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// LOGS (v2 only)
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
async function getLogs(options) {
|
|
208
190
|
var _a, _b, _c;
|
|
191
|
+
let { all = true, limit = 1000, offset: initialOffset = 0, target, targets = [], flatten = true, debugMode = false, noTarget = false, maxBlockRange, processor, } = options;
|
|
192
|
+
const { chain, fromBlock, toBlock, topic, topic1, topic2, topic3, transformLog, } = await (0, logs_1.getLogParams)(options, true);
|
|
209
193
|
if (!debugMode)
|
|
210
194
|
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
let topic2;
|
|
216
|
-
let topic3;
|
|
217
|
-
if (((topics === null || topics === void 0 ? void 0 : topics.length) && topics.length > 1)) {
|
|
218
|
-
if (topics === null || topics === void 0 ? void 0 : topics.length) {
|
|
219
|
-
topic1 = topics[1];
|
|
220
|
-
topic2 = topics[2];
|
|
221
|
-
topic3 = topics[3];
|
|
222
|
-
}
|
|
195
|
+
const blockRange = toBlock - fromBlock;
|
|
196
|
+
const effectiveMaxBlockRange = maxBlockRange !== null && maxBlockRange !== void 0 ? maxBlockRange : (noTarget ? 10000 : Infinity);
|
|
197
|
+
if (noTarget && blockRange > 500000) {
|
|
198
|
+
throw new Error("When noTarget is true, block range must be less than 500k blocks. Please narrow down your block range.");
|
|
223
199
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
200
|
+
// We now only support v2 for logs ---------------------------------------------------------
|
|
201
|
+
checkIndexerConfig("v2");
|
|
202
|
+
const chainId = getChainId(chain, "v2");
|
|
203
|
+
// Ensure the indexer is synced far enough
|
|
204
|
+
const chainIndexStatus = await getChainIndexStatus("v2");
|
|
205
|
+
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
206
|
+
if (lastIndexedBlock < toBlock) {
|
|
207
|
+
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
|
|
228
208
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
fromBlock = await (0, blocks_1.getBlockNumber)(chain, fromTimestamp);
|
|
241
|
-
if (!toBlock)
|
|
242
|
-
toBlock = await (0, blocks_1.getBlockNumber)(chain, toTimestamp);
|
|
243
|
-
if (!fromBlock || !toBlock)
|
|
244
|
-
throw new Error('fromBlock and toBlock must be > 0');
|
|
245
|
-
if (version === 'v1') {
|
|
246
|
-
const chainIndexStatus = await getChainIndexStatus('v1');
|
|
247
|
-
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
248
|
-
if (lastIndexedBlock < toBlock)
|
|
249
|
-
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
|
|
209
|
+
// Re‑curse if the requested range is too large ------------------------------------------------
|
|
210
|
+
if (blockRange > effectiveMaxBlockRange) {
|
|
211
|
+
const results = [];
|
|
212
|
+
for (let currentFromBlock = fromBlock; currentFromBlock < toBlock; currentFromBlock += effectiveMaxBlockRange) {
|
|
213
|
+
const currentToBlock = Math.min(currentFromBlock + effectiveMaxBlockRange - 1, toBlock);
|
|
214
|
+
const chunk = await getLogs({ ...options, fromBlock: currentFromBlock, toBlock: currentToBlock });
|
|
215
|
+
results.push(chunk);
|
|
216
|
+
}
|
|
217
|
+
if (flatten || !(targets === null || targets === void 0 ? void 0 : targets.length))
|
|
218
|
+
return results.flat();
|
|
219
|
+
return targets.map((_, i) => results.map((r) => r[i]).flat());
|
|
250
220
|
}
|
|
221
|
+
// -------------------------------------------------------------------------
|
|
222
|
+
// Prepare address filters
|
|
223
|
+
// -------------------------------------------------------------------------
|
|
251
224
|
let address = target;
|
|
252
|
-
if (typeof target ===
|
|
225
|
+
if (typeof target === "string")
|
|
253
226
|
targets = [target];
|
|
254
|
-
if (Array.isArray(targets))
|
|
255
|
-
address = targets.join(
|
|
256
|
-
const hasAddressFilter = address
|
|
227
|
+
if (Array.isArray(targets) && targets.length)
|
|
228
|
+
address = targets.join(",");
|
|
229
|
+
const hasAddressFilter = !!(address === null || address === void 0 ? void 0 : address.length);
|
|
257
230
|
if (address)
|
|
258
231
|
address = address.toLowerCase();
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
let hasMore = true;
|
|
268
|
-
let logs = [];
|
|
232
|
+
const addressSet = new Set((address !== null && address !== void 0 ? address : "").split(",").filter(Boolean));
|
|
233
|
+
const addressChunks = (0, _1.sliceIntoChunks)((_c = address === null || address === void 0 ? void 0 : address.split(",")) !== null && _c !== void 0 ? _c : [], addressChunkSize);
|
|
234
|
+
if (noTarget && addressChunks.length === 0)
|
|
235
|
+
addressChunks.push(undefined);
|
|
236
|
+
// -------------------------------------------------------------------------
|
|
237
|
+
// Pull logs
|
|
238
|
+
// -------------------------------------------------------------------------
|
|
239
|
+
const rawLogs = [];
|
|
269
240
|
const debugTimeKey = `Indexer-getLogs-${chain}-${topic}-${address}_${Math.random()}`;
|
|
270
241
|
if (debugMode) {
|
|
271
|
-
(0, debugLog_1.debugLog)(
|
|
242
|
+
(0, debugLog_1.debugLog)("[Indexer] Pulling logs " + debugTimeKey);
|
|
272
243
|
console.time(debugTimeKey);
|
|
273
244
|
}
|
|
274
|
-
const addressSet = new Set(address === null || address === void 0 ? void 0 : address.split(','));
|
|
275
|
-
const addressChunks = (0, _1.sliceIntoChunks)((_c = address === null || address === void 0 ? void 0 : address.split(',')) !== null && _c !== void 0 ? _c : [], addressChunkSize);
|
|
276
|
-
// to ensure that we have at least one chunk to process if no target is provided
|
|
277
|
-
if (noTarget && addressChunks.length === 0)
|
|
278
|
-
addressChunks.push(undefined);
|
|
279
245
|
for (const chunk of addressChunks) {
|
|
280
|
-
if (Array.isArray(chunk) && chunk.length === 0)
|
|
281
|
-
throw new Error(
|
|
282
|
-
|
|
246
|
+
if (Array.isArray(chunk) && chunk.length === 0)
|
|
247
|
+
throw new Error("Address chunk cannot be empty");
|
|
248
|
+
let chunkOffset = initialOffset;
|
|
283
249
|
let logCount = 0;
|
|
250
|
+
let hasMore = true;
|
|
284
251
|
do {
|
|
285
252
|
const params = {
|
|
286
|
-
addresses: hasAddressFilter ? chunk.join(
|
|
253
|
+
addresses: hasAddressFilter ? chunk === null || chunk === void 0 ? void 0 : chunk.join(",") : undefined,
|
|
287
254
|
chainId,
|
|
288
255
|
topic0: topic,
|
|
289
256
|
from_block: fromBlock,
|
|
290
257
|
to_block: toBlock,
|
|
291
|
-
topic1,
|
|
292
|
-
|
|
258
|
+
topic1,
|
|
259
|
+
topic2,
|
|
260
|
+
topic3,
|
|
261
|
+
limit,
|
|
262
|
+
offset: chunkOffset,
|
|
293
263
|
noTarget,
|
|
264
|
+
eventAbi: options.eventAbi,
|
|
265
|
+
parseLog: options.parseLog,
|
|
266
|
+
onlyArgs: options.onlyArgs,
|
|
294
267
|
};
|
|
295
|
-
const { data: { logs: _logs, totalCount } } = await
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (
|
|
301
|
-
|
|
268
|
+
const { data: { logs: _logs, totalCount }, } = await axiosInstances.v2(`/logs`, { params });
|
|
269
|
+
const filtered = _logs.filter((l) => {
|
|
270
|
+
const isWhitelisted = !addressSet.size || addressSet.has(l.source.toLowerCase());
|
|
271
|
+
if (!isWhitelisted)
|
|
272
|
+
return false;
|
|
273
|
+
if (l.block_number) {
|
|
274
|
+
l.blockNumber = parseInt(l.block_number);
|
|
302
275
|
}
|
|
276
|
+
return true;
|
|
303
277
|
});
|
|
278
|
+
const transformed = filtered.map(transformLog);
|
|
279
|
+
if (processor)
|
|
280
|
+
await processor(transformed);
|
|
281
|
+
rawLogs.push(...transformed);
|
|
304
282
|
logCount += _logs.length;
|
|
305
|
-
|
|
306
|
-
// If we have all the logs, or we have reached the limit, or there are no logs, we stop
|
|
283
|
+
chunkOffset += limit;
|
|
307
284
|
if (_logs.length < limit || totalCount <= logCount || _logs.length === 0)
|
|
308
285
|
hasMore = false;
|
|
309
286
|
} while (all && hasMore);
|
|
310
287
|
}
|
|
311
288
|
if (debugMode) {
|
|
312
289
|
console.timeEnd(debugTimeKey);
|
|
313
|
-
(0, debugLog_1.debugLog)(
|
|
290
|
+
(0, debugLog_1.debugLog)("Logs pulled " + chain, address, rawLogs.length);
|
|
314
291
|
}
|
|
315
|
-
|
|
316
|
-
|
|
292
|
+
// -------------------------------------------------------------------------
|
|
293
|
+
// Map / transform result
|
|
294
|
+
// -------------------------------------------------------------------------
|
|
317
295
|
const splitByAddress = (targets === null || targets === void 0 ? void 0 : targets.length) && !flatten;
|
|
318
296
|
if (splitByAddress) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
297
|
+
const mapped = targets.map(() => []);
|
|
298
|
+
const indexMap = {};
|
|
299
|
+
targets.forEach((t, i) => (indexMap[t.toLowerCase()] = i));
|
|
300
|
+
rawLogs.forEach((log) => {
|
|
301
|
+
const idx = indexMap[log.source.toLowerCase()];
|
|
302
|
+
if (idx === undefined)
|
|
303
|
+
return; // ignore unknown sources
|
|
304
|
+
mapped[idx].push(log);
|
|
305
|
+
});
|
|
306
|
+
return mapped;
|
|
323
307
|
}
|
|
324
|
-
|
|
325
|
-
const source = log.source.toLowerCase();
|
|
326
|
-
log.logIndex = log.log_index;
|
|
327
|
-
log.index = log.log_index;
|
|
328
|
-
log.transactionHash = log.transaction_hash;
|
|
329
|
-
log.blockNumber = log.block_number;
|
|
330
|
-
log.topics = [log.topic0, log.topic1, log.topic2, log.topic3,].filter(t => t !== '').map(i => ethers_1.ethers.zeroPadValue(i, 32));
|
|
331
|
-
const deleteKeys = ['chain', 'block_number', 'log_index', 'topic0', 'topic1', 'topic2', 'topic3', 'decodedArgs', 'transaction_hash',];
|
|
332
|
-
deleteKeys.forEach(k => delete log[k]);
|
|
333
|
-
const parsedLog = iface === null || iface === void 0 ? void 0 : iface.parseLog({ data: log.data, topics: log.topics, });
|
|
334
|
-
log.args = parsedLog === null || parsedLog === void 0 ? void 0 : parsedLog.args;
|
|
335
|
-
log = !entireLog ? log.args : log;
|
|
336
|
-
if (entireLog && parseLog)
|
|
337
|
-
log.parsedLog = parsedLog;
|
|
338
|
-
if (splitByAddress) {
|
|
339
|
-
const index = addressIndexMap[source];
|
|
340
|
-
mappedLogs[index].push(log);
|
|
341
|
-
}
|
|
342
|
-
return log;
|
|
343
|
-
});
|
|
344
|
-
if (splitByAddress)
|
|
345
|
-
return mappedLogs;
|
|
346
|
-
return logs;
|
|
308
|
+
return rawLogs;
|
|
347
309
|
}
|
|
348
310
|
exports.getLogs = getLogs;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return false;
|
|
354
|
-
return true;
|
|
355
|
-
}
|
|
356
|
-
exports.isIndexerEnabled = isIndexerEnabled;
|
|
357
|
-
function isIndexer2Enabled(chain) {
|
|
358
|
-
if (!indexerConfigs.v2.endpoint)
|
|
359
|
-
return false;
|
|
360
|
-
if (chain && !exports.supportedChainSet2.has(chain))
|
|
361
|
-
return false;
|
|
362
|
-
return true;
|
|
363
|
-
}
|
|
364
|
-
exports.isIndexer2Enabled = isIndexer2Enabled;
|
|
365
|
-
async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBlock, toBlock, all = true, limit = 1000, offset = 0, target, targets = [], flatten = true, fromTimestamp, toTimestamp, debugMode = false, transferType = 'in', token, tokens, }) {
|
|
311
|
+
// ---------------------------------------------------------------------------
|
|
312
|
+
// TOKEN TRANSFERS (v2 only)
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
async function getTokenTransfers({ chain = "ethereum", fromAddressFilter, fromBlock, toBlock, all = true, limit = 1000, offset = 0, target, targets = [], flatten = true, fromTimestamp, toTimestamp, debugMode = false, transferType = "in", token, tokens, }) {
|
|
366
315
|
var _a, _b;
|
|
367
316
|
if (!debugMode)
|
|
368
317
|
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
318
|
+
checkIndexerConfig("v2");
|
|
319
|
+
const chainId = getChainId(chain, "v2");
|
|
320
|
+
// -----------------------------------------------------------------------
|
|
321
|
+
// Input validation & pre‑processing
|
|
322
|
+
// -----------------------------------------------------------------------
|
|
323
|
+
const fromFilterEnabled = !!(fromAddressFilter === null || fromAddressFilter === void 0 ? void 0 : fromAddressFilter.length);
|
|
324
|
+
if (typeof fromAddressFilter === "string")
|
|
374
325
|
fromAddressFilter = [fromAddressFilter];
|
|
375
326
|
const fromFilterSet = new Set((fromAddressFilter !== null && fromAddressFilter !== void 0 ? fromAddressFilter : []).map((a) => a.toLowerCase()));
|
|
376
327
|
if (!fromBlock && !fromTimestamp)
|
|
377
|
-
throw new Error(
|
|
328
|
+
throw new Error("fromBlock or fromTimestamp is required");
|
|
378
329
|
if (!toBlock && !toTimestamp)
|
|
379
|
-
throw new Error(
|
|
330
|
+
throw new Error("toBlock or toTimestamp is required");
|
|
380
331
|
if (!fromBlock)
|
|
381
332
|
fromBlock = await (0, blocks_1.getBlockNumber)(chain, fromTimestamp);
|
|
382
333
|
if (!toBlock)
|
|
383
334
|
toBlock = await (0, blocks_1.getBlockNumber)(chain, toTimestamp);
|
|
384
335
|
if (!fromBlock || !toBlock)
|
|
385
|
-
throw new Error(
|
|
336
|
+
throw new Error("fromBlock and toBlock must be > 0");
|
|
386
337
|
if (token)
|
|
387
338
|
tokens = [token];
|
|
388
339
|
if (tokens) {
|
|
389
|
-
if (typeof tokens ===
|
|
340
|
+
if (typeof tokens === "string")
|
|
390
341
|
tokens = [tokens];
|
|
391
|
-
tokens = tokens.join(
|
|
342
|
+
tokens = tokens.join(",").toLowerCase();
|
|
392
343
|
}
|
|
393
344
|
if (target)
|
|
394
345
|
targets = [target];
|
|
395
346
|
if (!targets.length)
|
|
396
|
-
throw new Error(
|
|
397
|
-
targets = targets.map(t => t.toLowerCase());
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
347
|
+
throw new Error("target|targets is required");
|
|
348
|
+
targets = targets.map((t) => t.toLowerCase());
|
|
349
|
+
const addresses = targets.join(",");
|
|
350
|
+
// Ensure v2 indexer is up‑to‑date
|
|
351
|
+
const chainIndexStatus = await getChainIndexStatus("v2");
|
|
352
|
+
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
353
|
+
if (lastIndexedBlock < toBlock) {
|
|
354
|
+
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
|
|
404
355
|
}
|
|
405
|
-
|
|
406
|
-
|
|
356
|
+
// -----------------------------------------------------------------------
|
|
357
|
+
// Fetch transfers
|
|
358
|
+
// -----------------------------------------------------------------------
|
|
359
|
+
const rawTransfers = [];
|
|
407
360
|
const debugTimeKey = `Indexer-tokenTransfers-${chain}-${addresses}_${Math.random()}`;
|
|
408
361
|
if (debugMode) {
|
|
409
|
-
(0, debugLog_1.debugLog)(
|
|
362
|
+
(0, debugLog_1.debugLog)("[Indexer] Pulling token transfers " + debugTimeKey);
|
|
410
363
|
console.time(debugTimeKey);
|
|
411
364
|
}
|
|
365
|
+
let currentOffset = offset;
|
|
366
|
+
let hasMore = true;
|
|
412
367
|
do {
|
|
413
368
|
const params = {
|
|
414
369
|
addresses,
|
|
@@ -416,161 +371,149 @@ async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBl
|
|
|
416
371
|
from_block: fromBlock,
|
|
417
372
|
to_block: toBlock,
|
|
418
373
|
limit,
|
|
419
|
-
offset,
|
|
374
|
+
offset: currentOffset,
|
|
420
375
|
tokens,
|
|
421
376
|
from_address: false,
|
|
422
377
|
to_address: false,
|
|
423
378
|
};
|
|
424
379
|
switch (transferType) {
|
|
425
|
-
case
|
|
380
|
+
case "in":
|
|
426
381
|
params.to_address = true;
|
|
427
382
|
break;
|
|
428
|
-
case
|
|
383
|
+
case "out":
|
|
429
384
|
params.from_address = true;
|
|
430
385
|
break;
|
|
431
|
-
case
|
|
386
|
+
case "all":
|
|
432
387
|
params.from_address = true;
|
|
433
388
|
params.to_address = true;
|
|
434
389
|
break;
|
|
435
390
|
default:
|
|
436
|
-
throw new Error(
|
|
391
|
+
throw new Error("Invalid transferType");
|
|
437
392
|
}
|
|
438
|
-
const { data: { transfers: _logs, totalCount } } = await
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
if (_logs.length < limit || totalCount <= logs.length || _logs.length === 0)
|
|
393
|
+
const { data: { transfers: _logs, totalCount }, } = await axiosInstances.v2(`/token-transfers`, { params });
|
|
394
|
+
rawTransfers.push(..._logs);
|
|
395
|
+
currentOffset += limit;
|
|
396
|
+
if (_logs.length < limit || totalCount <= rawTransfers.length || _logs.length === 0)
|
|
443
397
|
hasMore = false;
|
|
444
398
|
} while (all && hasMore);
|
|
445
|
-
|
|
399
|
+
const filteredTransfers = rawTransfers.filter((l) => {
|
|
446
400
|
if (!fromFilterEnabled)
|
|
447
401
|
return true;
|
|
448
|
-
return fromFilterSet.has(l
|
|
402
|
+
return fromFilterSet.has(l.from_address.toLowerCase());
|
|
449
403
|
});
|
|
450
404
|
if (debugMode) {
|
|
451
405
|
console.timeEnd(debugTimeKey);
|
|
452
|
-
(0, debugLog_1.debugLog)(
|
|
406
|
+
(0, debugLog_1.debugLog)("Token Transfers pulled " + chain, addresses, filteredTransfers.length);
|
|
453
407
|
}
|
|
454
|
-
|
|
455
|
-
|
|
408
|
+
// -----------------------------------------------------------------------
|
|
409
|
+
// Split result if requested
|
|
410
|
+
// -----------------------------------------------------------------------
|
|
456
411
|
const splitByAddress = (targets === null || targets === void 0 ? void 0 : targets.length) && !flatten;
|
|
457
412
|
if (splitByAddress) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const source = log[sourceField].toLowerCase();
|
|
467
|
-
const index = addressIndexMap[source];
|
|
468
|
-
mappedLogs[index].push(log);
|
|
413
|
+
const mapped = targets.map(() => []);
|
|
414
|
+
const indexMap = {};
|
|
415
|
+
targets.forEach((t, i) => (indexMap[t] = i));
|
|
416
|
+
filteredTransfers.forEach((log) => {
|
|
417
|
+
const sourceField = transferType === "in" ? "to_address" : "from_address";
|
|
418
|
+
const idx = indexMap[log[sourceField].toLowerCase()];
|
|
419
|
+
if (idx !== undefined)
|
|
420
|
+
mapped[idx].push(log);
|
|
469
421
|
});
|
|
470
|
-
return
|
|
422
|
+
return mapped;
|
|
471
423
|
}
|
|
472
|
-
return
|
|
424
|
+
return filteredTransfers;
|
|
473
425
|
}
|
|
474
426
|
exports.getTokenTransfers = getTokenTransfers;
|
|
475
|
-
|
|
427
|
+
// ---------------------------------------------------------------------------
|
|
428
|
+
// TRANSACTIONS (v2 only)
|
|
429
|
+
// ---------------------------------------------------------------------------
|
|
430
|
+
async function getTransactions({ chain = "ethereum", addresses, transaction_hashes, from_block, to_block, all = true, limit = 1000, offset = 0, debugMode = false, transactionType = "from", }) {
|
|
476
431
|
var _a, _b;
|
|
477
432
|
if (!debugMode)
|
|
478
433
|
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
479
|
-
checkIndexerConfig(
|
|
480
|
-
const chainId = getChainId(chain,
|
|
481
|
-
if ((!addresses || addresses.length === 0) && (!transaction_hashes || transaction_hashes.length === 0))
|
|
434
|
+
checkIndexerConfig("v2");
|
|
435
|
+
const chainId = getChainId(chain, "v2");
|
|
436
|
+
if ((!addresses || addresses.length === 0) && (!transaction_hashes || transaction_hashes.length === 0))
|
|
482
437
|
throw new Error("You must provide at least 'addresses' or 'transaction_hashes'");
|
|
483
|
-
|
|
484
|
-
if (!from_block || !to_block) {
|
|
438
|
+
if (!from_block || !to_block)
|
|
485
439
|
throw new Error("'from_block' and 'to_block' are required to search for transactions");
|
|
486
|
-
|
|
487
|
-
const chainIndexStatus = await getChainIndexStatus('v2');
|
|
440
|
+
const chainIndexStatus = await getChainIndexStatus("v2");
|
|
488
441
|
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
489
442
|
if (to_block > lastIndexedBlock) {
|
|
490
443
|
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${to_block}`);
|
|
491
444
|
}
|
|
492
|
-
const
|
|
445
|
+
const params = { chainId };
|
|
493
446
|
if (addresses) {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
else {
|
|
498
|
-
apiParams.addresses = addresses.toLowerCase();
|
|
499
|
-
}
|
|
447
|
+
params.addresses = Array.isArray(addresses)
|
|
448
|
+
? addresses.map((a) => a.toLowerCase()).join(",")
|
|
449
|
+
: addresses.toLowerCase();
|
|
500
450
|
}
|
|
501
451
|
if (transaction_hashes) {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
else {
|
|
506
|
-
apiParams.transaction_hashes = transaction_hashes.toLowerCase();
|
|
507
|
-
}
|
|
452
|
+
params.transaction_hashes = Array.isArray(transaction_hashes)
|
|
453
|
+
? transaction_hashes.map((h) => h.toLowerCase()).join(",")
|
|
454
|
+
: transaction_hashes.toLowerCase();
|
|
508
455
|
}
|
|
509
|
-
|
|
510
|
-
|
|
456
|
+
params.from_block = from_block;
|
|
457
|
+
params.to_block = to_block;
|
|
511
458
|
if (offset)
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
case 'to':
|
|
520
|
-
to_address = true;
|
|
521
|
-
break;
|
|
522
|
-
case 'all':
|
|
523
|
-
default:
|
|
524
|
-
from_address = true;
|
|
525
|
-
to_address = true;
|
|
526
|
-
break;
|
|
527
|
-
}
|
|
528
|
-
apiParams.from_address = from_address;
|
|
529
|
-
apiParams.to_address = to_address;
|
|
530
|
-
if (all) {
|
|
531
|
-
apiParams.limit = 'all';
|
|
532
|
-
}
|
|
533
|
-
else {
|
|
534
|
-
if (limit !== 'all' && limit !== 0) {
|
|
535
|
-
apiParams.limit = limit;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
459
|
+
params.offset = offset;
|
|
460
|
+
params.from_address = transactionType !== "to";
|
|
461
|
+
params.to_address = transactionType !== "from";
|
|
462
|
+
if (all)
|
|
463
|
+
params.limit = "all";
|
|
464
|
+
else if (limit !== "all" && limit !== 0)
|
|
465
|
+
params.limit = limit;
|
|
538
466
|
const debugTimeKey = `Indexer-getTransactions-${chain}-${addresses || transaction_hashes}-${from_block}-${to_block}_${Math.random()}`;
|
|
539
467
|
if (debugMode) {
|
|
540
|
-
(0, debugLog_1.debugLog)(
|
|
468
|
+
(0, debugLog_1.debugLog)("[Indexer] Pulling transactions " + debugTimeKey);
|
|
541
469
|
console.time(debugTimeKey);
|
|
542
470
|
}
|
|
543
|
-
const { data: { transactions } } = await axiosInstances.v2(`/transactions`, {
|
|
544
|
-
params: apiParams,
|
|
545
|
-
});
|
|
471
|
+
const { data: { transactions } } = await axiosInstances.v2(`/transactions`, { params });
|
|
546
472
|
if (debugMode) {
|
|
547
473
|
console.timeEnd(debugTimeKey);
|
|
548
|
-
(0, debugLog_1.debugLog)(
|
|
474
|
+
(0, debugLog_1.debugLog)("Transactions pulled " + chain, addresses || transaction_hashes, (transactions === null || transactions === void 0 ? void 0 : transactions.length) || 0);
|
|
549
475
|
}
|
|
550
476
|
if (!(transactions === null || transactions === void 0 ? void 0 : transactions.length))
|
|
551
477
|
return null;
|
|
552
|
-
return transactions.map((
|
|
553
|
-
hash:
|
|
554
|
-
blockNumber:
|
|
555
|
-
transactionIndex:
|
|
556
|
-
from:
|
|
557
|
-
to:
|
|
558
|
-
value:
|
|
559
|
-
gasPrice:
|
|
560
|
-
gas:
|
|
561
|
-
input:
|
|
562
|
-
nonce:
|
|
563
|
-
data:
|
|
564
|
-
type:
|
|
565
|
-
maxFeePerGas:
|
|
566
|
-
maxPriorityFeePerGas:
|
|
567
|
-
baseFeePerGas:
|
|
568
|
-
effectiveGasPrice:
|
|
569
|
-
gasUsed:
|
|
570
|
-
cumulativeGasUsed:
|
|
571
|
-
status:
|
|
572
|
-
contractCreated:
|
|
573
|
-
timestamp:
|
|
478
|
+
return transactions.map((t) => ({
|
|
479
|
+
hash: t.hash,
|
|
480
|
+
blockNumber: +t.block_number,
|
|
481
|
+
transactionIndex: +t.transaction_index,
|
|
482
|
+
from: t.from_address,
|
|
483
|
+
to: t.to_address,
|
|
484
|
+
value: t.value,
|
|
485
|
+
gasPrice: t.gas_price,
|
|
486
|
+
gas: t.gas,
|
|
487
|
+
input: t.input,
|
|
488
|
+
nonce: +t.nonce,
|
|
489
|
+
data: t.input,
|
|
490
|
+
type: t.transaction_type,
|
|
491
|
+
maxFeePerGas: t.max_fee_per_gas,
|
|
492
|
+
maxPriorityFeePerGas: t.max_priority_fee_per_gas,
|
|
493
|
+
baseFeePerGas: t.base_fee_per_gas,
|
|
494
|
+
effectiveGasPrice: t.effective_gas_price,
|
|
495
|
+
gasUsed: t.gas_used,
|
|
496
|
+
cumulativeGasUsed: t.cumulative_gas_used,
|
|
497
|
+
status: t.status === "success" ? 1 : 0,
|
|
498
|
+
contractCreated: t.contract_created || undefined,
|
|
499
|
+
timestamp: t.timestamp,
|
|
574
500
|
}));
|
|
575
501
|
}
|
|
576
502
|
exports.getTransactions = getTransactions;
|
|
503
|
+
// ---------------------------------------------------------------------------
|
|
504
|
+
// Public helpers
|
|
505
|
+
// ---------------------------------------------------------------------------
|
|
506
|
+
function isIndexerEnabled(chain) {
|
|
507
|
+
// Legacy function kept for backward‑compat: return true if v2 is enabled
|
|
508
|
+
if (!indexerConfigs.v2.endpoint)
|
|
509
|
+
return false;
|
|
510
|
+
if (chain && !exports.supportedChainSet2.has(chain))
|
|
511
|
+
return false;
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
exports.isIndexerEnabled = isIndexerEnabled;
|
|
515
|
+
function isIndexer2Enabled(chain) {
|
|
516
|
+
// Alias – retained so external calls do not break
|
|
517
|
+
return isIndexerEnabled(chain);
|
|
518
|
+
}
|
|
519
|
+
exports.isIndexer2Enabled = isIndexer2Enabled;
|