@defillama/sdk 5.0.131 → 5.0.134

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.
@@ -9,6 +9,7 @@ const providers_json_1 = __importDefault(require("../providers.json"));
9
9
  const env_1 = require("./env");
10
10
  const debugLog_1 = require("./debugLog");
11
11
  const axios_1 = __importDefault(require("axios"));
12
+ const rpcRequestCounter = {};
12
13
  class LlamaProvider extends ethers_1.FallbackProvider {
13
14
  constructor({ providers, chainId, chainName, archivalRPCs, }, fallbackConfig) {
14
15
  const networkish = { name: chainName, chainId };
@@ -78,6 +79,9 @@ class LlamaProvider extends ethers_1.FallbackProvider {
78
79
  return this._performAction('getTransactionReceipt', [_hash]);
79
80
  }
80
81
  async _performAction(method, params, attempts = 7) {
82
+ if (!rpcRequestCounter[this.chainName])
83
+ rpcRequestCounter[this.chainName] = 0;
84
+ rpcRequestCounter[this.chainName]++;
81
85
  await this._isReady;
82
86
  let runners = [...this.rpcs];
83
87
  if (method === 'getLogs') {
@@ -305,3 +309,9 @@ function getMedianBlockValue(blocks) {
305
309
  const mid = Math.floor(blocks.length / 3);
306
310
  return blocks.length % 2 !== 0 ? blocks[mid] : (blocks[mid - 1] + blocks[mid]) / 2;
307
311
  }
312
+ process.on('exit', () => {
313
+ if (Object.keys(rpcRequestCounter).length > 7) {
314
+ (0, debugLog_1.debugLog)('RPC request count per chain');
315
+ console.table(rpcRequestCounter);
316
+ }
317
+ });
@@ -33,6 +33,8 @@ export type IndexerGetLogsOptions = {
33
33
  limit?: number;
34
34
  offset?: number;
35
35
  debugMode?: boolean;
36
+ noTarget?: boolean;
37
+ parseLog?: boolean;
36
38
  };
37
39
  export type IndexerGetTokenTransfersOptions = {
38
40
  target?: Address;
@@ -48,11 +50,11 @@ export type IndexerGetTokenTransfersOptions = {
48
50
  offset?: number;
49
51
  debugMode?: boolean;
50
52
  fromAddressFilter?: string | string[];
51
- transferType?: 'in' | 'out';
53
+ transferType?: 'in' | 'out' | 'all';
52
54
  tokens?: string | string[];
53
55
  token?: string;
54
56
  };
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[]>;
57
+ 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[]>;
56
58
  export declare function isIndexerEnabled(chain?: string): boolean;
57
59
  export declare function getTokenTransfers({ chain, fromAddressFilter, fromBlock, toBlock, all, limit, offset, target, targets, flatten, fromTimestamp, toTimestamp, debugMode, transferType, token, tokens, }: IndexerGetTokenTransfersOptions): Promise<any[]>;
58
60
  export {};
@@ -131,7 +131,7 @@ async function getTokens(address, { onlyWhitelisted = true, skipCacheRead = fals
131
131
  return tokens;
132
132
  }
133
133
  exports.getTokens = getTokens;
134
- 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 }) {
134
+ 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, }) {
135
135
  var _a, _b, _c;
136
136
  checkIndexerConfig();
137
137
  const chainId = chainToIDMapping[chain];
@@ -150,6 +150,8 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
150
150
  throw new Error('fromBlock or fromTimestamp is required');
151
151
  if (!toBlock && !toTimestamp)
152
152
  throw new Error('toBlock or toTimestamp is required');
153
+ if (!noTarget && !target && !(targets === null || targets === void 0 ? void 0 : targets.length))
154
+ throw new Error('target|targets is required or set the flag "noTarget" to true');
153
155
  if (!fromBlock)
154
156
  fromBlock = await (0, blocks_1.getBlockNumber)(chain, fromTimestamp);
155
157
  if (!toBlock)
@@ -185,6 +187,9 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
185
187
  }
186
188
  const addressSet = new Set(address === null || address === void 0 ? void 0 : address.split(','));
187
189
  const addressChunks = (0, _1.sliceIntoChunks)((_c = address === null || address === void 0 ? void 0 : address.split(',')) !== null && _c !== void 0 ? _c : [], 10);
190
+ // to ensure that we have at least one chunk to process if no target is provided
191
+ if (noTarget && addressChunks.length === 0)
192
+ addressChunks.push(undefined);
188
193
  for (const chunk of addressChunks) {
189
194
  let _logAgg = [];
190
195
  do {
@@ -232,12 +237,11 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
232
237
  log.topics = [log.topic0, log.topic1, log.topic2, log.topic3,].filter(t => t !== '').map(i => ethers_1.ethers.zeroPadValue(i, 32));
233
238
  const deleteKeys = ['chain', 'address', 'block_number', 'log_index', 'topic0', 'topic1', 'topic2', 'topic3', 'decodedArgs', 'transaction_hash',];
234
239
  deleteKeys.forEach(k => delete log[k]);
235
- const parsedLog = iface === null || iface === void 0 ? void 0 : iface.parseLog({
236
- data: log.data,
237
- topics: log.topics,
238
- });
240
+ const parsedLog = iface === null || iface === void 0 ? void 0 : iface.parseLog({ data: log.data, topics: log.topics, });
239
241
  log.args = parsedLog === null || parsedLog === void 0 ? void 0 : parsedLog.args;
240
242
  log = !entireLog ? log.args : log;
243
+ if (entireLog && parseLog)
244
+ log.parsedLog = parsedLog;
241
245
  if (splitByAddress) {
242
246
  const index = addressIndexMap[source];
243
247
  mappedLogs[index].push(log);
@@ -313,11 +317,23 @@ async function getTokenTransfers({ chain = 'ethereum', fromAddressFilter, fromBl
313
317
  limit,
314
318
  offset,
315
319
  tokens,
320
+ from_address: false,
321
+ to_address: false,
316
322
  };
317
- if (transferType === 'in')
318
- params.to_address = true;
319
- else
320
- params.from_address = true;
323
+ switch (transferType) {
324
+ case 'in':
325
+ params.to_address = true;
326
+ break;
327
+ case 'out':
328
+ params.from_address = true;
329
+ break;
330
+ case 'all':
331
+ params.from_address = true;
332
+ params.to_address = true;
333
+ break;
334
+ default:
335
+ throw new Error('Invalid transferType');
336
+ }
321
337
  const { data: { transfers: _logs, totalCount } } = await axiosIndexer(`/token-transfers`, { params, });
322
338
  logs.push(..._logs);
323
339
  offset += limit;
@@ -22,6 +22,8 @@ export type GetLogsOptions = {
22
22
  skipIndexer?: boolean;
23
23
  onlyIndexer?: boolean;
24
24
  debugMode?: boolean;
25
+ noTarget?: boolean;
26
+ parseLog?: boolean;
25
27
  };
26
28
  export declare function getLogs(options: GetLogsOptions): Promise<EventLog[] | EventLog[][] | any[]>;
27
29
  export declare function toFilterTopic(topic: string): string;
@@ -12,7 +12,8 @@ const currentVersion = 'v3';
12
12
  async function getLogs(options) {
13
13
  let { target, chain = 'ethereum', fromBlock, toBlock, fromTimestamp, toTimestamp, eventAbi, topic, topics, extraTopics, // can be passed as input as extra filter arguments
14
14
  skipCache = false, skipCacheRead = false, entireLog = false, cacheInCloud = false, onlyArgs = false, keys = [], // [Deprecated] This is just used to select only part of the logs
15
- targets, flatten = true, skipIndexer = false, onlyIndexer = false, debugMode = false, } = options;
15
+ targets, flatten = true, skipIndexer = false, onlyIndexer = false, debugMode = false, noTarget = false, // we sometimes want to query logs without a target, but it will an be expensive bug if target/targets were not passed by mistake, so this is a safety check
16
+ parseLog = false, } = options;
16
17
  if (!skipIndexer && (0, indexer_1.isIndexerEnabled)(chain)) {
17
18
  try {
18
19
  const response = await (0, indexer_1.getLogs)({
@@ -41,6 +42,9 @@ async function getLogs(options) {
41
42
  toBlock = await (0, blocks_1.getBlockNumber)(chain, toTimestamp);
42
43
  if (!fromBlock || !toBlock)
43
44
  throw new Error('fromBlock and toBlock must be > 0');
45
+ if (!noTarget && !target && !(targets === null || targets === void 0 ? void 0 : targets.length)) {
46
+ throw new Error('target|targets is required or set the flag "noTarget" to true');
47
+ }
44
48
  if (targets === null || targets === void 0 ? void 0 : targets.length) {
45
49
  const newOptions = { ...options, fromBlock, toBlock };
46
50
  delete newOptions.targets;
@@ -103,8 +107,12 @@ async function getLogs(options) {
103
107
  continue; // no intersection with cache
104
108
  logs.push(...cacheData.logs.filter((i) => i.blockNumber >= fromBlock && i.blockNumber <= toBlock));
105
109
  }
106
- if (!eventAbi || entireLog)
110
+ if (!eventAbi || entireLog) {
111
+ if (iface && parseLog) {
112
+ logs.forEach((i) => i.parsedLog = iface === null || iface === void 0 ? void 0 : iface.parseLog(i));
113
+ }
107
114
  return logs;
115
+ }
108
116
  return logs.map((i) => iface.parseLog(i)).map((i) => onlyArgs ? i.args : i);
109
117
  async function addLogsToCache(fromBlock, toBlock) {
110
118
  const debugTimeKey = `getLogs-${chain}-${topic}-${target}_${Math.random()}-${fromBlock}-${toBlock}`;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const providers_json_1 = __importDefault(require("../providers.json"));
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const providerList = providers_json_1.default;
10
+ async function getChainData() {
11
+ try {
12
+ const { data: chainData } = await (0, axios_1.default)('https://chainlist.org/rpcs.json');
13
+ return chainData;
14
+ }
15
+ catch (e) {
16
+ console.log('Failed to fetch chainlist.org, falling back to local copy');
17
+ // https://unpkg.com/@defillama/sdk@latest/build/providers.json
18
+ return require(__dirname + '/chainlistOrgCache.json');
19
+ }
20
+ }
21
+ async function main() {
22
+ let chainData = await getChainData();
23
+ const providerIDMap = {};
24
+ Object.values(chainData).forEach((i) => providerIDMap[i.chainId] = {
25
+ ...i,
26
+ rpc: new Set(i.rpc.map((j) => j.url))
27
+ });
28
+ Object.entries(providerList).forEach(([key, data]) => {
29
+ const chainListdata = providerIDMap[data.chainId];
30
+ if (!chainListdata)
31
+ return;
32
+ data.rpc = data.rpc.filter((i) => {
33
+ if (i.endsWith('/'))
34
+ i = i.slice(0, -1);
35
+ if (chainListdata.rpc.has(i)) {
36
+ console.log(`Removing rpc ${i} from ${key} as it is already in chainlist`);
37
+ return false;
38
+ }
39
+ return true;
40
+ });
41
+ if (!data.rpc.length && chainListdata.shortName === key) {
42
+ delete providerList[key];
43
+ console.log(`Removing ${key} as it has no rpcs left`);
44
+ return;
45
+ }
46
+ });
47
+ fs_1.default.writeFileSync(__dirname + '/../providers.json', JSON.stringify(providers_json_1.default, null, 2));
48
+ }
49
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defillama/sdk",
3
- "version": "5.0.131",
3
+ "version": "5.0.134",
4
4
  "description": "SDK for calculating TVL",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -9,6 +9,7 @@
9
9
  "watch": "tsc --watch",
10
10
  "test": "LLAMA_DEBUG_MODE='' SDK_DEBUG='' jest",
11
11
  "update-providers": "ts-node src/util/updateProviderList.ts",
12
+ "remove-rpcs": "ts-node src/util/removeRedundantRPCs.ts",
12
13
  "format": "prettier --write \"src/**/*.ts\"",
13
14
  "prepublishOnly": "npm run build"
14
15
  },