@defillama/sdk 5.0.133 → 5.0.136

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
+ (0, debugLog_1.debugTable)(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;
@@ -52,7 +54,7 @@ export type IndexerGetTokenTransfersOptions = {
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 {
@@ -198,6 +203,10 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
198
203
  offset,
199
204
  };
200
205
  const { data: { logs: _logs, totalCount } } = await axiosIndexer(`/logs`, { params, });
206
+ // getLogs uses 'address' field to return log source, so we add the field here to make it compatible
207
+ _logs.forEach((l) => {
208
+ l.address = l.source;
209
+ });
201
210
  _logAgg.push(..._logs.filter((l) => {
202
211
  if (!addressSet.size)
203
212
  return true;
@@ -232,12 +241,11 @@ async function getLogs({ chain = 'ethereum', topic, topics, fromBlock, toBlock,
232
241
  log.topics = [log.topic0, log.topic1, log.topic2, log.topic3,].filter(t => t !== '').map(i => ethers_1.ethers.zeroPadValue(i, 32));
233
242
  const deleteKeys = ['chain', 'address', 'block_number', 'log_index', 'topic0', 'topic1', 'topic2', 'topic3', 'decodedArgs', 'transaction_hash',];
234
243
  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
- });
244
+ const parsedLog = iface === null || iface === void 0 ? void 0 : iface.parseLog({ data: log.data, topics: log.topics, });
239
245
  log.args = parsedLog === null || parsedLog === void 0 ? void 0 : parsedLog.args;
240
246
  log = !entireLog ? log.args : log;
247
+ if (entireLog && parseLog)
248
+ log.parsedLog = parsedLog;
241
249
  if (splitByAddress) {
242
250
  const index = addressIndexMap[source];
243
251
  mappedLogs[index].push(log);
@@ -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}`;
@@ -79,9 +79,6 @@ async function main() {
79
79
  continue;
80
80
  providerList[key] = providerList[shorName];
81
81
  }
82
- if (providerList.hyperliquid) {
83
- providerList.hyperliquid.rpc.push('https://hyperliquid.cloud.blockscout.com/api/eth-rpc');
84
- }
85
82
  const droppedChains = Object.keys(oldProviders).filter(oldChain => providerList[oldChain] === undefined);
86
83
  if (droppedChains.length > 20) {
87
84
  throw new Error(`Following chains used to be included but is not anymore, can the devs fix please?\n${droppedChains.join('\n')}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defillama/sdk",
3
- "version": "5.0.133",
3
+ "version": "5.0.136",
4
4
  "description": "SDK for calculating TVL",
5
5
  "main": "build/index.js",
6
6
  "scripts": {