@defillama/sdk 5.0.139 → 5.0.142
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/ChainApi.d.ts +3 -2
- package/build/ChainApi.js +7 -6
- package/build/abi/multicall3.js +1 -0
- package/build/providers.json +1 -1
- package/build/util/blocks.js +3 -1
- package/build/util/env.js +1 -1
- package/build/util/indexer.d.ts +5 -1
- package/build/util/indexer.js +246 -64
- package/build/util/transactions.d.ts +13 -0
- package/build/util/transactions.js +23 -0
- package/package.json +1 -1
package/build/util/blocks.js
CHANGED
|
@@ -126,7 +126,7 @@ function getExtraProvider(chain = "ethereum") {
|
|
|
126
126
|
}
|
|
127
127
|
exports.getLatestBlock = getCurrentChainBlock;
|
|
128
128
|
const intialBlocks = {
|
|
129
|
-
planq:
|
|
129
|
+
planq: 14000000,
|
|
130
130
|
sei: 78353999,
|
|
131
131
|
terra: 4724001,
|
|
132
132
|
crab: 4969901
|
|
@@ -173,6 +173,8 @@ async function _lookupBlock(timestamp, extraParams) {
|
|
|
173
173
|
low = parseInt(envLowValue);
|
|
174
174
|
let lowBlock = getLowBlock();
|
|
175
175
|
let highBlock = getHighBlock();
|
|
176
|
+
if ((lowBlock === null || lowBlock === void 0 ? void 0 : lowBlock.number) < low)
|
|
177
|
+
lowBlock = undefined;
|
|
176
178
|
let block;
|
|
177
179
|
let i = 0;
|
|
178
180
|
let time = Date.now();
|
package/build/util/env.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getChainRPCs = exports.getArchivalRPCs = exports.getBatchMaxCount = exports.getDefaultChunkSize = exports.getEnvMulticallAddress = exports.getEnvCacheFolder = exports.getEnvValue = exports.getEnvRPC = exports.getParallelGetBlocksLimit = exports.getParallelGetLogsLimit = exports.getMaxParallelRequests = exports.getChainId = exports.ENV_CONSTANTS = void 0;
|
|
4
4
|
const whitelistedEnvConstants = [
|
|
5
5
|
'R2_ENDPOINT', 'R2_ACCESS_KEY_ID', 'R2_SECRET_ACCESS_KEY', 'TRON_PRO_API_KEY', 'COINS_API_KEY',
|
|
6
|
-
'ELASTICSEARCH_CONFIG', 'GRAPH_API_KEY', 'LLAMA_INDEXER_ENDPOINT', 'LLAMA_INDEXER_API_KEY',
|
|
6
|
+
'ELASTICSEARCH_CONFIG', 'GRAPH_API_KEY', 'LLAMA_INDEXER_ENDPOINT', 'LLAMA_INDEXER_API_KEY', 'LLAMA_INDEXER_V2_ENDPOINT', 'LLAMA_INDEXER_V2_API_KEY',
|
|
7
7
|
];
|
|
8
8
|
const defaultEnvValues = {
|
|
9
9
|
INTERNAL_SDK_CACHE_FILE: './cache.json',
|
package/build/util/indexer.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Address } from "../types";
|
|
2
|
-
|
|
2
|
+
import { GetTransactionOptions } from "./transactions";
|
|
3
|
+
export declare const supportedChainSet: Set<string>;
|
|
4
|
+
export declare const supportedChainSet2: Set<string>;
|
|
3
5
|
declare enum TokenTypes {
|
|
4
6
|
ERC20 = "erc20",
|
|
5
7
|
ERC721 = "erc721"
|
|
@@ -56,5 +58,7 @@ export type IndexerGetTokenTransfersOptions = {
|
|
|
56
58
|
};
|
|
57
59
|
export declare function getLogs({ chain, topic, topics, fromBlock, toBlock, all, limit, offset, target, targets, eventAbi, entireLog, flatten, extraTopics, fromTimestamp, toTimestamp, debugMode, noTarget, parseLog, }: IndexerGetLogsOptions): Promise<any[]>;
|
|
58
60
|
export declare function isIndexerEnabled(chain?: string): boolean;
|
|
61
|
+
export declare function isIndexer2Enabled(chain?: string): boolean;
|
|
59
62
|
export declare function getTokenTransfers({ chain, fromAddressFilter, fromBlock, toBlock, all, limit, offset, target, targets, flatten, fromTimestamp, toTimestamp, debugMode, transferType, token, tokens, }: IndexerGetTokenTransfersOptions): Promise<any[]>;
|
|
63
|
+
export declare function getTransactions({ chain, addresses, transaction_hashes, from_block, to_block, all, limit, offset, debugMode, transactionType }: GetTransactionOptions): Promise<any>;
|
|
60
64
|
export {};
|
package/build/util/indexer.js
CHANGED
|
@@ -3,9 +3,10 @@ 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.getTokenTransfers = exports.isIndexerEnabled = exports.getLogs = exports.getTokens = exports.supportedChainSet = void 0;
|
|
6
|
+
exports.getTransactions = exports.getTokenTransfers = exports.isIndexer2Enabled = exports.isIndexerEnabled = exports.getLogs = exports.getTokens = exports.supportedChainSet2 = exports.supportedChainSet = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const ethers_1 = require("ethers");
|
|
9
|
+
const _1 = require(".");
|
|
9
10
|
const general_1 = require("../general");
|
|
10
11
|
const generalUtil_1 = require("../generalUtil");
|
|
11
12
|
const blocks_1 = require("./blocks");
|
|
@@ -13,43 +14,11 @@ const cache_1 = require("./cache");
|
|
|
13
14
|
const debugLog_1 = require("./debugLog");
|
|
14
15
|
const env_1 = require("./env");
|
|
15
16
|
const logs_1 = require("./logs");
|
|
16
|
-
const _1 = require(".");
|
|
17
17
|
const indexerURL = (0, env_1.getEnvValue)('LLAMA_INDEXER_ENDPOINT');
|
|
18
18
|
const LLAMA_INDEXER_API_KEY = (0, env_1.getEnvValue)('LLAMA_INDEXER_API_KEY');
|
|
19
|
+
const LLAMA_INDEXER_V2_ENDPOINT = (0, env_1.getEnvValue)('LLAMA_INDEXER_V2_ENDPOINT');
|
|
20
|
+
const LLAMA_INDEXER_V2_API_KEY = (0, env_1.getEnvValue)('LLAMA_INDEXER_V2_API_KEY');
|
|
19
21
|
const addressChunkSize = +(0, env_1.getEnvValue)('LLAMA_INDEXER_ADDRESS_CHUNK_SIZE');
|
|
20
|
-
const axiosIndexer = axios_1.default.create({
|
|
21
|
-
headers: {
|
|
22
|
-
"x-api-key": LLAMA_INDEXER_API_KEY,
|
|
23
|
-
},
|
|
24
|
-
baseURL: indexerURL,
|
|
25
|
-
});
|
|
26
|
-
function checkIndexerConfig() {
|
|
27
|
-
if (!indexerURL || !LLAMA_INDEXER_API_KEY)
|
|
28
|
-
throw new Error('Llama Indexer URL/api key is not set');
|
|
29
|
-
}
|
|
30
|
-
const state = { chainIndexStatus: {} };
|
|
31
|
-
const cacheTime = 1 * 60 * 1000; // 1 minutes - we cache sync status for 1 minute
|
|
32
|
-
async function getChainIndexStatus() {
|
|
33
|
-
checkIndexerConfig();
|
|
34
|
-
if (state.timestamp && (Date.now() - state.timestamp) < cacheTime)
|
|
35
|
-
return state.chainIndexStatus;
|
|
36
|
-
state.timestamp = Date.now();
|
|
37
|
-
state.chainIndexStatus = _getState();
|
|
38
|
-
return state.chainIndexStatus;
|
|
39
|
-
async function _getState() {
|
|
40
|
-
const { data: { syncStatus } } = await axiosIndexer.get(`/sync`);
|
|
41
|
-
const syncInfo = {};
|
|
42
|
-
syncStatus.forEach((d) => {
|
|
43
|
-
const chain = indexerChainIdChainMapping[d.chain];
|
|
44
|
-
syncInfo[chain] = {
|
|
45
|
-
block: d.lastIndexedBlock,
|
|
46
|
-
timestamp: +new Date(d.lastIndexedDate)
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
state.chainIndexStatus = syncInfo;
|
|
50
|
-
return syncInfo;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
22
|
const indexerChainIdChainMapping = {
|
|
54
23
|
1: 'ethereum',
|
|
55
24
|
10: 'optimism',
|
|
@@ -68,13 +37,88 @@ const indexerChainIdChainMapping = {
|
|
|
68
37
|
59144: 'linea',
|
|
69
38
|
81457: 'blast',
|
|
70
39
|
534352: 'scroll',
|
|
71
|
-
146: 'sonic'
|
|
40
|
+
146: 'sonic',
|
|
41
|
+
};
|
|
42
|
+
const indexer2ChainIdChainMapping = {
|
|
43
|
+
...indexerChainIdChainMapping,
|
|
44
|
+
130: 'unichain',
|
|
45
|
+
1868: 'soneium',
|
|
46
|
+
80094: 'berachain',
|
|
47
|
+
999: 'hyperliquid'
|
|
72
48
|
};
|
|
73
|
-
|
|
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
|
+
const indexerConfigs = {
|
|
75
|
+
v1: {
|
|
76
|
+
endpoint: indexerURL,
|
|
77
|
+
apiKey: LLAMA_INDEXER_API_KEY,
|
|
78
|
+
chainMapping: indexerChainIdChainMapping
|
|
79
|
+
},
|
|
80
|
+
v2: {
|
|
81
|
+
endpoint: LLAMA_INDEXER_V2_ENDPOINT,
|
|
82
|
+
apiKey: LLAMA_INDEXER_V2_API_KEY,
|
|
83
|
+
chainMapping: indexer2ChainIdChainMapping
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const axiosInstances = {
|
|
87
|
+
v1: axios_1.default.create({
|
|
88
|
+
headers: { "x-api-key": indexerConfigs.v1.apiKey },
|
|
89
|
+
baseURL: indexerConfigs.v1.endpoint,
|
|
90
|
+
}),
|
|
91
|
+
v2: axios_1.default.create({
|
|
92
|
+
headers: { "x-api-key": indexerConfigs.v2.apiKey },
|
|
93
|
+
baseURL: indexerConfigs.v2.endpoint,
|
|
94
|
+
})
|
|
95
|
+
};
|
|
96
|
+
function checkIndexerConfig(version) {
|
|
97
|
+
const config = indexerConfigs[version];
|
|
98
|
+
if (!config.endpoint || !config.apiKey)
|
|
99
|
+
throw new Error(`Llama Indexer ${version} URL/api key is not set`);
|
|
100
|
+
}
|
|
101
|
+
function getChainId(chain, version = 'v1') {
|
|
102
|
+
var _a;
|
|
103
|
+
const chainId = (_a = Object.entries(indexerConfigs[version].chainMapping)
|
|
104
|
+
.find(([_, chainName]) => chainName === chain)) === null || _a === void 0 ? void 0 : _a[0];
|
|
105
|
+
if (!chainId)
|
|
106
|
+
throw new Error('Chain not supported');
|
|
107
|
+
return +chainId;
|
|
108
|
+
}
|
|
109
|
+
function getSupportedChains(version = 'v1') {
|
|
110
|
+
return new Set(Object.values(indexerConfigs[version].chainMapping));
|
|
111
|
+
}
|
|
112
|
+
exports.supportedChainSet = getSupportedChains('v1');
|
|
113
|
+
exports.supportedChainSet2 = getSupportedChains('v2');
|
|
74
114
|
const chainToIDMapping = {};
|
|
75
|
-
Object.entries(
|
|
115
|
+
Object.entries(indexerConfigs.v1.chainMapping).forEach(([id, chain]) => {
|
|
76
116
|
chainToIDMapping[chain] = id;
|
|
77
117
|
});
|
|
118
|
+
const chainToIDMapping2 = {};
|
|
119
|
+
Object.entries(indexerConfigs.v2.chainMapping).forEach(([id, chain]) => {
|
|
120
|
+
chainToIDMapping2[chain] = id;
|
|
121
|
+
});
|
|
78
122
|
var TokenTypes;
|
|
79
123
|
(function (TokenTypes) {
|
|
80
124
|
TokenTypes["ERC20"] = "erc20";
|
|
@@ -82,7 +126,7 @@ var TokenTypes;
|
|
|
82
126
|
})(TokenTypes || (TokenTypes = {}));
|
|
83
127
|
async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = false, skipCache = false, chain, tokenType, } = {}) {
|
|
84
128
|
var _a, _b;
|
|
85
|
-
checkIndexerConfig();
|
|
129
|
+
checkIndexerConfig('v1');
|
|
86
130
|
if (!address)
|
|
87
131
|
throw new Error('Address is required either as a string or an array of strings');
|
|
88
132
|
if (Array.isArray(address) && !address.length)
|
|
@@ -106,7 +150,7 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
|
|
|
106
150
|
}
|
|
107
151
|
(0, debugLog_1.debugLog)('[Indexer] Pulling tokens for ' + address);
|
|
108
152
|
const tokens = (_b = cache.tokens) !== null && _b !== void 0 ? _b : {};
|
|
109
|
-
const { data: { balances } } = await
|
|
153
|
+
const { data: { balances } } = await axiosInstances.v1(`/balances`, {
|
|
110
154
|
params: {
|
|
111
155
|
addresses: address,
|
|
112
156
|
chainId,
|
|
@@ -114,7 +158,7 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
|
|
|
114
158
|
},
|
|
115
159
|
});
|
|
116
160
|
balances.filter((b) => +b.total_amount > 0).forEach((b) => {
|
|
117
|
-
const chain =
|
|
161
|
+
const chain = indexerConfigs.v1.chainMapping[b.chain];
|
|
118
162
|
if (!chain) {
|
|
119
163
|
return;
|
|
120
164
|
}
|
|
@@ -132,14 +176,41 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
|
|
|
132
176
|
return tokens;
|
|
133
177
|
}
|
|
134
178
|
exports.getTokens = getTokens;
|
|
179
|
+
async function getIndexerVersionForBlock(chain, blockNumber) {
|
|
180
|
+
var _a, _b;
|
|
181
|
+
if (!isIndexer2Enabled(chain)) {
|
|
182
|
+
if (!isIndexerEnabled(chain)) {
|
|
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
|
+
}
|
|
135
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, }) {
|
|
136
208
|
var _a, _b, _c;
|
|
137
|
-
checkIndexerConfig();
|
|
138
|
-
const chainId = chainToIDMapping[chain];
|
|
139
|
-
if (!chainId)
|
|
140
|
-
throw new Error('Chain not supported');
|
|
141
209
|
if (!debugMode)
|
|
142
210
|
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
211
|
+
const version = await getIndexerVersionForBlock(chain, toBlock !== null && toBlock !== void 0 ? toBlock : 0);
|
|
212
|
+
checkIndexerConfig(version);
|
|
213
|
+
const chainId = getChainId(chain, version);
|
|
143
214
|
let topic1;
|
|
144
215
|
let topic2;
|
|
145
216
|
let topic3;
|
|
@@ -159,19 +230,24 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
|
|
|
159
230
|
topic = topics[0];
|
|
160
231
|
if (!eventAbi)
|
|
161
232
|
entireLog = true;
|
|
162
|
-
|
|
233
|
+
if (!noTarget && !target && !(targets === null || targets === void 0 ? void 0 : targets.length))
|
|
234
|
+
throw new Error('target|targets is required or set the flag "noTarget" to true');
|
|
163
235
|
if (!fromBlock && !fromTimestamp)
|
|
164
236
|
throw new Error('fromBlock or fromTimestamp is required');
|
|
165
237
|
if (!toBlock && !toTimestamp)
|
|
166
238
|
throw new Error('toBlock or toTimestamp is required');
|
|
167
|
-
if (!noTarget && !target && !(targets === null || targets === void 0 ? void 0 : targets.length))
|
|
168
|
-
throw new Error('target|targets is required or set the flag "noTarget" to true');
|
|
169
239
|
if (!fromBlock)
|
|
170
240
|
fromBlock = await (0, blocks_1.getBlockNumber)(chain, fromTimestamp);
|
|
171
241
|
if (!toBlock)
|
|
172
242
|
toBlock = await (0, blocks_1.getBlockNumber)(chain, toTimestamp);
|
|
173
243
|
if (!fromBlock || !toBlock)
|
|
174
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}`);
|
|
250
|
+
}
|
|
175
251
|
let address = target;
|
|
176
252
|
if (typeof target === 'string')
|
|
177
253
|
targets = [target];
|
|
@@ -180,10 +256,6 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
|
|
|
180
256
|
const hasAddressFilter = address && address.length;
|
|
181
257
|
if (address)
|
|
182
258
|
address = address.toLowerCase();
|
|
183
|
-
const chainIndexStatus = await getChainIndexStatus();
|
|
184
|
-
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
185
|
-
if (lastIndexedBlock < toBlock)
|
|
186
|
-
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
|
|
187
259
|
// Create an Interface object
|
|
188
260
|
let iface;
|
|
189
261
|
if (eventAbi)
|
|
@@ -220,7 +292,7 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
|
|
|
220
292
|
limit, offset,
|
|
221
293
|
noTarget,
|
|
222
294
|
};
|
|
223
|
-
const { data: { logs: _logs, totalCount } } = await
|
|
295
|
+
const { data: { logs: _logs, totalCount } } = await executeWithFallback(chain, toBlock, () => axiosInstances.v2(`/logs`, { params }), () => axiosInstances.v1(`/logs`, { params }));
|
|
224
296
|
// getLogs uses 'address' field to return log source, so we add the field here to make it compatible
|
|
225
297
|
_logs.forEach((l) => {
|
|
226
298
|
l.address = l.source;
|
|
@@ -275,26 +347,32 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
|
|
|
275
347
|
}
|
|
276
348
|
exports.getLogs = getLogs;
|
|
277
349
|
function isIndexerEnabled(chain) {
|
|
278
|
-
if (!
|
|
350
|
+
if (!indexerConfigs.v1.endpoint)
|
|
279
351
|
return false;
|
|
280
352
|
if (chain && !exports.supportedChainSet.has(chain))
|
|
281
353
|
return false;
|
|
282
354
|
return true;
|
|
283
355
|
}
|
|
284
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;
|
|
285
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, }) {
|
|
286
366
|
var _a, _b;
|
|
287
|
-
checkIndexerConfig();
|
|
288
|
-
const chainId = chainToIDMapping[chain];
|
|
289
|
-
if (!chainId)
|
|
290
|
-
throw new Error('Chain not supported');
|
|
291
367
|
if (!debugMode)
|
|
292
368
|
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
369
|
+
const version = await getIndexerVersionForBlock(chain, toBlock !== null && toBlock !== void 0 ? toBlock : 0);
|
|
370
|
+
checkIndexerConfig(version);
|
|
371
|
+
const chainId = getChainId(chain, version);
|
|
293
372
|
const fromFilterEnabled = fromAddressFilter && fromAddressFilter.length;
|
|
294
373
|
if (fromAddressFilter && typeof fromAddressFilter === 'string')
|
|
295
374
|
fromAddressFilter = [fromAddressFilter];
|
|
296
375
|
const fromFilterSet = new Set((fromAddressFilter !== null && fromAddressFilter !== void 0 ? fromAddressFilter : []).map((a) => a.toLowerCase()));
|
|
297
|
-
// if (!target && !targets?.length) throw new Error('target|targets is required')
|
|
298
376
|
if (!fromBlock && !fromTimestamp)
|
|
299
377
|
throw new Error('fromBlock or fromTimestamp is required');
|
|
300
378
|
if (!toBlock && !toTimestamp)
|
|
@@ -318,10 +396,12 @@ async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBl
|
|
|
318
396
|
throw new Error('target|targets is required');
|
|
319
397
|
targets = targets.map(t => t.toLowerCase());
|
|
320
398
|
let addresses = targets.join(',');
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
399
|
+
if (version === 'v1') {
|
|
400
|
+
const chainIndexStatus = await getChainIndexStatus('v1');
|
|
401
|
+
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
402
|
+
if (lastIndexedBlock < toBlock)
|
|
403
|
+
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
|
|
404
|
+
}
|
|
325
405
|
let hasMore = true;
|
|
326
406
|
let logs = [];
|
|
327
407
|
const debugTimeKey = `Indexer-tokenTransfers-${chain}-${addresses}_${Math.random()}`;
|
|
@@ -355,7 +435,7 @@ async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBl
|
|
|
355
435
|
default:
|
|
356
436
|
throw new Error('Invalid transferType');
|
|
357
437
|
}
|
|
358
|
-
const { data: { transfers: _logs, totalCount } } = await
|
|
438
|
+
const { data: { transfers: _logs, totalCount } } = await executeWithFallback(chain, toBlock, () => axiosInstances.v2(`/token-transfers`, { params }), () => axiosInstances.v1(`/token-transfers`, { params }));
|
|
359
439
|
logs.push(..._logs);
|
|
360
440
|
offset += limit;
|
|
361
441
|
// If we have all the logs, or we have reached the limit, or there are no logs, we stop
|
|
@@ -392,3 +472,105 @@ async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBl
|
|
|
392
472
|
return logs;
|
|
393
473
|
}
|
|
394
474
|
exports.getTokenTransfers = getTokenTransfers;
|
|
475
|
+
async function getTransactions({ chain = 'ethereum', addresses, transaction_hashes, from_block, to_block, all = true, limit = 1000, offset = 0, debugMode = false, transactionType = 'from' }) {
|
|
476
|
+
var _a, _b;
|
|
477
|
+
if (!debugMode)
|
|
478
|
+
debugMode = debugLog_1.DEBUG_LEVEL2;
|
|
479
|
+
checkIndexerConfig('v2');
|
|
480
|
+
const chainId = getChainId(chain, 'v2');
|
|
481
|
+
if ((!addresses || addresses.length === 0) && (!transaction_hashes || transaction_hashes.length === 0)) {
|
|
482
|
+
throw new Error("You must provide at least 'addresses' or 'transaction_hashes'");
|
|
483
|
+
}
|
|
484
|
+
if (!from_block || !to_block) {
|
|
485
|
+
throw new Error("'from_block' and 'to_block' are required to search for transactions");
|
|
486
|
+
}
|
|
487
|
+
const chainIndexStatus = await getChainIndexStatus('v2');
|
|
488
|
+
const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
|
|
489
|
+
if (to_block > lastIndexedBlock) {
|
|
490
|
+
throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${to_block}`);
|
|
491
|
+
}
|
|
492
|
+
const apiParams = { chainId };
|
|
493
|
+
if (addresses) {
|
|
494
|
+
if (Array.isArray(addresses)) {
|
|
495
|
+
apiParams.addresses = addresses.map((a) => a.toLowerCase()).join(',');
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
apiParams.addresses = addresses.toLowerCase();
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (transaction_hashes) {
|
|
502
|
+
if (Array.isArray(transaction_hashes)) {
|
|
503
|
+
apiParams.transaction_hashes = transaction_hashes.map((h) => h.toLowerCase()).join(',');
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
apiParams.transaction_hashes = transaction_hashes.toLowerCase();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
apiParams.from_block = from_block;
|
|
510
|
+
apiParams.to_block = to_block;
|
|
511
|
+
if (offset)
|
|
512
|
+
apiParams.offset = offset;
|
|
513
|
+
let from_address = false;
|
|
514
|
+
let to_address = false;
|
|
515
|
+
switch (transactionType) {
|
|
516
|
+
case 'from':
|
|
517
|
+
from_address = true;
|
|
518
|
+
break;
|
|
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
|
+
}
|
|
538
|
+
const debugTimeKey = `Indexer-getTransactions-${chain}-${addresses || transaction_hashes}-${from_block}-${to_block}_${Math.random()}`;
|
|
539
|
+
if (debugMode) {
|
|
540
|
+
(0, debugLog_1.debugLog)('[Indexer] Pulling transactions ' + debugTimeKey);
|
|
541
|
+
console.time(debugTimeKey);
|
|
542
|
+
}
|
|
543
|
+
const { data: { transactions } } = await axiosInstances.v2(`/transactions`, {
|
|
544
|
+
params: apiParams,
|
|
545
|
+
});
|
|
546
|
+
if (debugMode) {
|
|
547
|
+
console.timeEnd(debugTimeKey);
|
|
548
|
+
(0, debugLog_1.debugLog)('Transactions pulled ' + chain, addresses || transaction_hashes, (transactions === null || transactions === void 0 ? void 0 : transactions.length) || 0);
|
|
549
|
+
}
|
|
550
|
+
if (!(transactions === null || transactions === void 0 ? void 0 : transactions.length))
|
|
551
|
+
return null;
|
|
552
|
+
return transactions.map((transaction) => ({
|
|
553
|
+
hash: transaction.hash,
|
|
554
|
+
blockNumber: parseInt(transaction.block_number),
|
|
555
|
+
transactionIndex: parseInt(transaction.transaction_index),
|
|
556
|
+
from: transaction.from_address,
|
|
557
|
+
to: transaction.to_address,
|
|
558
|
+
value: transaction.value,
|
|
559
|
+
gasPrice: transaction.gas_price,
|
|
560
|
+
gas: transaction.gas,
|
|
561
|
+
input: transaction.input,
|
|
562
|
+
nonce: parseInt(transaction.nonce),
|
|
563
|
+
data: transaction.input,
|
|
564
|
+
type: transaction.transaction_type,
|
|
565
|
+
maxFeePerGas: transaction.max_fee_per_gas,
|
|
566
|
+
maxPriorityFeePerGas: transaction.max_priority_fee_per_gas,
|
|
567
|
+
baseFeePerGas: transaction.base_fee_per_gas,
|
|
568
|
+
effectiveGasPrice: transaction.effective_gas_price,
|
|
569
|
+
gasUsed: transaction.gas_used,
|
|
570
|
+
cumulativeGasUsed: transaction.cumulative_gas_used,
|
|
571
|
+
status: transaction.status === 'success' ? 1 : 0,
|
|
572
|
+
contractCreated: transaction.contract_created || undefined,
|
|
573
|
+
timestamp: transaction.timestamp,
|
|
574
|
+
}));
|
|
575
|
+
}
|
|
576
|
+
exports.getTransactions = getTransactions;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface GetTransactionOptions {
|
|
2
|
+
addresses?: string[];
|
|
3
|
+
from_block?: number;
|
|
4
|
+
to_block?: number;
|
|
5
|
+
transaction_hashes?: string[];
|
|
6
|
+
limit?: number | 'all';
|
|
7
|
+
offset?: number;
|
|
8
|
+
chain: string;
|
|
9
|
+
all?: boolean;
|
|
10
|
+
debugMode?: boolean;
|
|
11
|
+
transactionType?: 'from' | 'to' | 'all';
|
|
12
|
+
}
|
|
13
|
+
export declare function getTransactions(params: GetTransactionOptions): Promise<any>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTransactions = void 0;
|
|
4
|
+
const debugLog_1 = require("./debugLog");
|
|
5
|
+
const indexer_1 = require("./indexer");
|
|
6
|
+
async function getTransactions(params) {
|
|
7
|
+
const { chain } = params;
|
|
8
|
+
if (!(0, indexer_1.isIndexer2Enabled)(chain)) {
|
|
9
|
+
throw new Error(`Indexer v2 not available for chain ${chain}`);
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const response = await (0, indexer_1.getTransactions)(params);
|
|
13
|
+
if (response)
|
|
14
|
+
return response;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
let message = e === null || e === void 0 ? void 0 : e.message;
|
|
18
|
+
(0, debugLog_1.debugLog)('Error in indexer getTransactions', message);
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
exports.getTransactions = getTransactions;
|