@defillama/sdk 5.0.91 → 5.0.92

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.
@@ -34,6 +34,25 @@ export type IndexerGetLogsOptions = {
34
34
  offset?: number;
35
35
  debugMode?: boolean;
36
36
  };
37
+ export type IndexerGetTokenTransfersOptions = {
38
+ target?: Address;
39
+ targets?: Address[];
40
+ fromBlock?: number;
41
+ toBlock?: number;
42
+ chain?: string;
43
+ fromTimestamp?: number;
44
+ toTimestamp?: number;
45
+ flatten?: boolean;
46
+ all?: boolean;
47
+ limit?: number;
48
+ offset?: number;
49
+ debugMode?: boolean;
50
+ fromAddressFilter?: string | string[];
51
+ transferType?: 'in' | 'out';
52
+ tokens?: string | string[];
53
+ token?: string;
54
+ };
37
55
  export declare function getLogs({ chain, topic, topics, fromBlock, toBlock, all, limit, offset, target, targets, eventAbi, entireLog, flatten, extraTopics, fromTimestamp, toTimestamp, debugMode }: IndexerGetLogsOptions): Promise<any[]>;
38
56
  export declare function isIndexerEnabled(chain?: string): boolean;
57
+ export declare function getTokenTransfers({ chain, fromAddressFilter, fromBlock, toBlock, all, limit, offset, target, targets, flatten, fromTimestamp, toTimestamp, debugMode, transferType, token, tokens, }: IndexerGetTokenTransfersOptions): Promise<any[]>;
39
58
  export {};
@@ -3,7 +3,7 @@ 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.isIndexerEnabled = exports.getLogs = exports.getTokens = exports.supportedChainSet = void 0;
6
+ exports.getTokenTransfers = exports.isIndexerEnabled = exports.getLogs = exports.getTokens = exports.supportedChainSet = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const env_1 = require("./env");
9
9
  const cache_1 = require("./cache");
@@ -78,6 +78,9 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
78
78
  if (Array.isArray(address))
79
79
  address = address.join(',');
80
80
  address = address.toLowerCase();
81
+ let chainId;
82
+ if (chain)
83
+ chainId = chainToIDMapping[chain];
81
84
  const project = 'llama-indexer-cache';
82
85
  const key = onlyWhitelisted ? address : `${address}/all`;
83
86
  const file = `${project}/${key}`;
@@ -94,7 +97,7 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
94
97
  const { data: { balances } } = await axios_1.default.get(`${indexerURL}/balances`, {
95
98
  params: {
96
99
  addresses: address,
97
- chain: chain,
100
+ chainId,
98
101
  type: tokenType,
99
102
  }
100
103
  });
@@ -173,7 +176,7 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
173
176
  do {
174
177
  const params = {
175
178
  addresses: address,
176
- chain: chainId,
179
+ chainId,
177
180
  topic0: topic,
178
181
  from_block: fromBlock,
179
182
  to_block: toBlock,
@@ -238,3 +241,102 @@ function isIndexerEnabled(chain) {
238
241
  return true;
239
242
  }
240
243
  exports.isIndexerEnabled = isIndexerEnabled;
244
+ 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, }) {
245
+ var _a, _b;
246
+ if (!indexerURL)
247
+ throw new Error('Llama Indexer URL not set');
248
+ const chainId = chainToIDMapping[chain];
249
+ if (!chainId)
250
+ throw new Error('Chain not supported');
251
+ if (!debugMode)
252
+ debugMode = debugLog_1.DEBUG_LEVEL2;
253
+ const fromFilterEnabled = fromAddressFilter && fromAddressFilter.length;
254
+ if (fromAddressFilter && typeof fromAddressFilter === 'string')
255
+ fromAddressFilter = [fromAddressFilter];
256
+ const fromFilterSet = new Set((fromAddressFilter !== null && fromAddressFilter !== void 0 ? fromAddressFilter : []).map((a) => a.toLowerCase()));
257
+ // if (!target && !targets?.length) throw new Error('target|targets is required')
258
+ if (!fromBlock && !fromTimestamp)
259
+ throw new Error('fromBlock or fromTimestamp is required');
260
+ if (!toBlock && !toTimestamp)
261
+ throw new Error('toBlock or toTimestamp is required');
262
+ if (!fromBlock)
263
+ fromBlock = await (0, blocks_1.getBlockNumber)(chain, fromTimestamp);
264
+ if (!toBlock)
265
+ toBlock = await (0, blocks_1.getBlockNumber)(chain, toTimestamp);
266
+ if (!fromBlock || !toBlock)
267
+ throw new Error('fromBlock and toBlock must be > 0');
268
+ if (token)
269
+ tokens = [token];
270
+ if (tokens) {
271
+ if (typeof tokens === 'string')
272
+ tokens = [tokens];
273
+ tokens = tokens.join(',').toLowerCase();
274
+ }
275
+ if (target)
276
+ targets = [target];
277
+ if (!targets.length)
278
+ throw new Error('target|targets is required');
279
+ targets = targets.map(t => t.toLowerCase());
280
+ let addresses = targets.join(',');
281
+ const chainIndexStatus = await getChainIndexStatus();
282
+ const lastIndexedBlock = (_b = (_a = chainIndexStatus[chain]) === null || _a === void 0 ? void 0 : _a.block) !== null && _b !== void 0 ? _b : 0;
283
+ if (lastIndexedBlock < toBlock)
284
+ throw new Error(`Indexer not up to date for ${chain}. Last indexed block: ${lastIndexedBlock}, requested block: ${toBlock}`);
285
+ let hasMore = true;
286
+ let logs = [];
287
+ const debugTimeKey = `Indexer-tokenTransfers-${chain}-${addresses}_${Math.random()}`;
288
+ if (debugMode) {
289
+ (0, debugLog_1.debugLog)('[Indexer] Pulling token transfers ' + debugTimeKey);
290
+ console.time(debugTimeKey);
291
+ }
292
+ do {
293
+ const params = {
294
+ addresses,
295
+ chainId,
296
+ from_block: fromBlock,
297
+ to_block: toBlock,
298
+ limit,
299
+ offset,
300
+ tokens,
301
+ };
302
+ if (transferType === 'in')
303
+ params.to_address = true;
304
+ else
305
+ params.from_address = true;
306
+ const { data: { transfers: _logs, totalCount } } = await axios_1.default.get(`${indexerURL}/token-transfers`, { params });
307
+ logs.push(..._logs);
308
+ offset += limit;
309
+ // If we have all the logs, or we have reached the limit, or there are no logs, we stop
310
+ if (_logs.length < limit || totalCount <= logs.length || _logs.length === 0)
311
+ hasMore = false;
312
+ } while (all && hasMore);
313
+ logs = logs.filter((l) => {
314
+ if (!fromFilterEnabled)
315
+ return true;
316
+ return fromFilterSet.has(l === null || l === void 0 ? void 0 : l.from_address.toLowerCase());
317
+ });
318
+ if (debugMode) {
319
+ console.timeEnd(debugTimeKey);
320
+ (0, debugLog_1.debugLog)('Token Transfers pulled ' + chain, addresses, logs.length);
321
+ }
322
+ const mappedLogs = [];
323
+ let addressIndexMap = {};
324
+ const splitByAddress = (targets === null || targets === void 0 ? void 0 : targets.length) && !flatten;
325
+ if (splitByAddress) {
326
+ for (let i = 0; i < targets.length; i++) {
327
+ addressIndexMap[targets[i]] = i;
328
+ mappedLogs.push([]);
329
+ }
330
+ }
331
+ if (splitByAddress) {
332
+ logs.forEach((log) => {
333
+ const sourceField = transferType === 'in' ? 'to_address' : 'from_address';
334
+ const source = log[sourceField].toLowerCase();
335
+ const index = addressIndexMap[source];
336
+ mappedLogs[index].push(log);
337
+ });
338
+ return mappedLogs;
339
+ }
340
+ return logs;
341
+ }
342
+ exports.getTokenTransfers = getTokenTransfers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defillama/sdk",
3
- "version": "5.0.91",
3
+ "version": "5.0.92",
4
4
  "description": "SDK for calculating TVL",
5
5
  "main": "build/index.js",
6
6
  "scripts": {