@defillama/sdk 5.0.187 → 5.0.192

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.
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.padTopic32 = padTopic32;
4
+ exports.normalizeLog = normalizeLog;
5
+ exports.normalizeValueByType = normalizeValueByType;
6
+ exports.convertTopicsToViemFormat = convertTopicsToViemFormat;
7
+ exports.enrichEthersArgsWithNamedProperties = enrichEthersArgsWithNamedProperties;
8
+ exports.buildEthersCompatibleArgs = buildEthersCompatibleArgs;
9
+ exports.createViemFastPathBatchDecoder = createViemFastPathBatchDecoder;
10
+ const ethers_1 = require("ethers");
11
+ const viem_1 = require("viem");
12
+ function padTopic32(t) {
13
+ if (!t)
14
+ return '0x';
15
+ // Early return if already 32 bytes (0x + 64 hex chars)
16
+ if (t.startsWith('0x') && t.length === 66)
17
+ return t;
18
+ const hex = t.startsWith('0x') ? t.slice(2) : t;
19
+ return ('0x' + hex.padStart(64, '0'));
20
+ }
21
+ function normalizeLog(log, isIndexerCall = false) {
22
+ if (isIndexerCall || log.source) {
23
+ log.address = log.source;
24
+ log.logIndex = log.log_index;
25
+ log.index = log.log_index;
26
+ log.transactionHash = log.transaction_hash;
27
+ log.blockNumber = parseInt(log.block_number || log.blockNumber || 0);
28
+ const topics = [log.topic0, log.topic1, log.topic2, log.topic3]
29
+ .filter(Boolean)
30
+ .map(padTopic32);
31
+ if (!topics[0])
32
+ return false;
33
+ log.topics = topics;
34
+ log._originalTopics = {
35
+ topic0: log.topic0,
36
+ topic1: log.topic1,
37
+ topic2: log.topic2,
38
+ topic3: log.topic3
39
+ };
40
+ log._originalTransactionHash = log.transaction_hash;
41
+ // Only delete fields that are not needed for parsing
42
+ [
43
+ "chain",
44
+ "log_index",
45
+ ].forEach((k) => delete log[k]);
46
+ }
47
+ if (log.blockNumber === undefined && log.block_number !== undefined)
48
+ log.blockNumber = parseInt(log.block_number);
49
+ // Restore topics if they were lost
50
+ if (!log.topics && log._originalTopics) {
51
+ log.topics = [log._originalTopics.topic0, log._originalTopics.topic1, log._originalTopics.topic2, log._originalTopics.topic3]
52
+ .filter(Boolean)
53
+ .map(padTopic32);
54
+ }
55
+ // Restore transaction hash if it was lost
56
+ if (!log.transactionHash && log._originalTransactionHash) {
57
+ log.transactionHash = log._originalTransactionHash;
58
+ }
59
+ return true;
60
+ }
61
+ /**
62
+ * Normalize value type according to Solidity type to match Ethers format
63
+ * Ethers returns small int types (int24, uint24, uint16, etc.) as strings to avoid JS precision issues
64
+ */
65
+ const smallIntPattern = /^u?int(8|16|24)$/;
66
+ function normalizeValueByType(value, type) {
67
+ if (value === null || value === undefined)
68
+ return value;
69
+ // Ethers formats small integer types as strings
70
+ if (smallIntPattern.test(type)) {
71
+ if (typeof value === 'number') {
72
+ return value.toString();
73
+ }
74
+ else if (typeof value === 'bigint') {
75
+ return value.toString();
76
+ }
77
+ return value;
78
+ }
79
+ return value;
80
+ }
81
+ function convertTopicsToViemFormat(topics) {
82
+ if (!topics || topics.length === 0 || topics[0] === null) {
83
+ return [];
84
+ }
85
+ const filteredTopics = [];
86
+ for (let t = 0; t < topics.length; t++) {
87
+ if (topics[t] !== null) {
88
+ filteredTopics.push(topics[t]);
89
+ }
90
+ }
91
+ // Create tuple type for Viem (required format)
92
+ return filteredTopics.length > 0
93
+ ? [filteredTopics[0], ...filteredTopics.slice(1)]
94
+ : [];
95
+ }
96
+ // Enrich Ethers args with named properties to match Viem output structure
97
+ function enrichEthersArgsWithNamedProperties(ethersArgs, event, iface) {
98
+ if (!ethersArgs || !event || !event.inputs) {
99
+ return ethersArgs;
100
+ }
101
+ const inputs = event.inputs;
102
+ const length = typeof ethersArgs.length === 'number' ? ethersArgs.length : inputs.length;
103
+ const enrichedArgs = new Array(length);
104
+ for (let i = 0; i < length; i++) {
105
+ if (i in ethersArgs) {
106
+ enrichedArgs[i] = ethersArgs[i];
107
+ }
108
+ }
109
+ for (const key in ethersArgs) {
110
+ if (!Object.prototype.hasOwnProperty.call(ethersArgs, key))
111
+ continue;
112
+ if (!/^\d+$/.test(key)) {
113
+ enrichedArgs[key] = ethersArgs[key];
114
+ }
115
+ }
116
+ for (let i = 0; i < inputs.length; i++) {
117
+ const input = inputs[i];
118
+ const value = ethersArgs[i];
119
+ if (value !== undefined && value !== null) {
120
+ if (input.name && !(input.name in enrichedArgs)) {
121
+ enrichedArgs[input.name] = value;
122
+ }
123
+ if (!(i in enrichedArgs)) {
124
+ enrichedArgs[i] = value;
125
+ }
126
+ }
127
+ }
128
+ return enrichedArgs;
129
+ }
130
+ function buildEthersCompatibleArgs(decodedArgs, eventInputs, normalizeFn = normalizeValueByType) {
131
+ var _a, _b;
132
+ if (!decodedArgs) {
133
+ const args = new Array(eventInputs.length);
134
+ return args;
135
+ }
136
+ const args = new Array(eventInputs.length);
137
+ try {
138
+ if (Array.isArray(decodedArgs)) {
139
+ const len = Math.min(decodedArgs.length, eventInputs.length);
140
+ for (let i = 0; i < len; i++) {
141
+ const input = eventInputs[i];
142
+ const value = decodedArgs[i];
143
+ if (value !== undefined && value !== null) {
144
+ const normalizedValue = normalizeFn(value, input.type);
145
+ if (input.name)
146
+ args[input.name] = normalizedValue;
147
+ args[i] = normalizedValue;
148
+ }
149
+ }
150
+ return args;
151
+ }
152
+ if (typeof decodedArgs === 'object') {
153
+ const inputCount = eventInputs.length;
154
+ for (let i = 0; i < inputCount; i++) {
155
+ const input = eventInputs[i];
156
+ const value = (_b = (_a = decodedArgs[input.name]) !== null && _a !== void 0 ? _a : decodedArgs[i]) !== null && _b !== void 0 ? _b : null;
157
+ if (value !== undefined && value !== null) {
158
+ const normalizedValue = normalizeFn(value, input.type);
159
+ if (input.name)
160
+ args[input.name] = normalizedValue;
161
+ args[i] = normalizedValue;
162
+ }
163
+ }
164
+ return args;
165
+ }
166
+ }
167
+ catch (e) {
168
+ // Fallback: minimal object creation
169
+ if (Array.isArray(decodedArgs)) {
170
+ const len = decodedArgs.length;
171
+ for (let i = 0; i < len; i++) {
172
+ args[i] = decodedArgs[i];
173
+ }
174
+ args.length = len;
175
+ }
176
+ else if (typeof decodedArgs === 'object') {
177
+ Object.assign(args, decodedArgs);
178
+ }
179
+ }
180
+ return args;
181
+ }
182
+ function createViemFastPathBatchDecoder(eventAbi) {
183
+ try {
184
+ // Parse ABI once
185
+ const ev = (0, viem_1.parseAbiItem)(eventAbi);
186
+ if (!ev || ev.type !== 'event')
187
+ return null;
188
+ const inputs = ev.inputs || [];
189
+ const indexed = [];
190
+ const nonIndexed = [];
191
+ for (const inp of inputs) {
192
+ if (inp.indexed) {
193
+ indexed.push(inp);
194
+ }
195
+ else {
196
+ nonIndexed.push(inp);
197
+ }
198
+ }
199
+ const nonIndexedTypes = nonIndexed.map(i => ({ type: i.type }));
200
+ return async function decodeBatchViemFast(logs) {
201
+ var _a, _b;
202
+ const out = new Array(logs.length);
203
+ for (let i = 0; i < logs.length; i++) {
204
+ const l = logs[i];
205
+ try {
206
+ const logData = l.data || l.data_field || '0x';
207
+ const decodedNon = nonIndexed.length && logData && logData !== '0x'
208
+ ? (0, viem_1.decodeAbiParameters)(nonIndexedTypes, logData)
209
+ : [];
210
+ const args = new Array(inputs.length);
211
+ let topicIdx = 1; // topics[0] = event signature
212
+ let nonIndexedIdx = 0;
213
+ for (let j = 0; j < inputs.length; j++) {
214
+ const inp = inputs[j];
215
+ let value;
216
+ if (inp.indexed) {
217
+ if (topicIdx < (((_a = l.topics) === null || _a === void 0 ? void 0 : _a.length) || 0)) {
218
+ value = l.topics[topicIdx];
219
+ topicIdx++;
220
+ }
221
+ else {
222
+ value = null;
223
+ }
224
+ }
225
+ else {
226
+ value = (_b = decodedNon[nonIndexedIdx]) !== null && _b !== void 0 ? _b : null;
227
+ nonIndexedIdx++;
228
+ }
229
+ let normalizedValue = null;
230
+ if (value !== null && value !== undefined) {
231
+ // For indexed addresses, Ethers extracts the address from the padded topic
232
+ // Topics are 32 bytes padded, but Ethers returns addresses as normal 20-byte addresses
233
+ // Ethers uses getAddress() which converts to checksum format
234
+ if (inp.type === 'address' && inp.indexed && typeof value === 'string') {
235
+ let addressStr;
236
+ if (value.startsWith('0x') && value.length === 66) {
237
+ // Topic is 32 bytes padded, extract the address (last 20 bytes = 40 hex chars)
238
+ addressStr = '0x' + value.slice(-40);
239
+ }
240
+ else if (value.startsWith('0x') && value.length === 42) {
241
+ addressStr = value;
242
+ }
243
+ else {
244
+ // Fallback: try to extract address from topic
245
+ const hex = value.startsWith('0x') ? value.slice(2) : value;
246
+ if (hex.length >= 40) {
247
+ addressStr = '0x' + hex.slice(-40);
248
+ }
249
+ else {
250
+ addressStr = value;
251
+ }
252
+ }
253
+ // Use ethers.getAddress to convert to checksum format (like Ethers does)
254
+ try {
255
+ normalizedValue = ethers_1.ethers.getAddress(addressStr);
256
+ }
257
+ catch {
258
+ // Fallback if getAddress fails
259
+ normalizedValue = addressStr.toLowerCase();
260
+ }
261
+ }
262
+ else {
263
+ // For other types, use normal normalization
264
+ normalizedValue = normalizeValueByType(value, inp.type);
265
+ }
266
+ }
267
+ // Always assign both numeric index and named property (even if value is null/undefined)
268
+ // This matches Ethers behavior where all args are present in the args object
269
+ args[j] = normalizedValue;
270
+ if (inp.name) {
271
+ args[inp.name] = normalizedValue;
272
+ }
273
+ }
274
+ out[i] = args;
275
+ }
276
+ catch (e) {
277
+ // Fallback: return empty args on decode error
278
+ const args = new Array(inputs.length);
279
+ out[i] = args;
280
+ }
281
+ }
282
+ return out;
283
+ };
284
+ }
285
+ catch (e) {
286
+ return null;
287
+ }
288
+ }
@@ -15,6 +15,7 @@ const indexer_1 = require("./indexer");
15
15
  const promisePool_1 = __importDefault(require("./promisePool"));
16
16
  const env_1 = require("./env");
17
17
  const common_1 = require("./common");
18
+ const logs_decode_shared_1 = require("./logs.decode.shared");
18
19
  const currentVersion = "v3";
19
20
  /* -------------------------------------------------------------------------- */
20
21
  /* getLogs */
@@ -277,8 +278,14 @@ async function getLogParams(options, isIndexerCall = false) {
277
278
  if (!noTarget && !target && !targets.length)
278
279
  throw new Error('target|targets is required or set the flag "noTarget" to true');
279
280
  let iface;
280
- if (eventAbi)
281
+ let event = null;
282
+ if (eventAbi) {
281
283
  iface = new ethers_1.Interface([eventAbi]);
284
+ const fragments = iface.fragments.filter(f => f.type === 'event');
285
+ if (fragments.length > 0) {
286
+ event = fragments[0];
287
+ }
288
+ }
282
289
  if (!(topics === null || topics === void 0 ? void 0 : topics.length)) {
283
290
  if (topic)
284
291
  topic = toFilterTopic(topic);
@@ -296,19 +303,17 @@ async function getLogParams(options, isIndexerCall = false) {
296
303
  // normalize indexer payload
297
304
  if (isIndexerCall) {
298
305
  log.address = log.source;
299
- log.logIndex = log.log_index;
300
- log.index = log.log_index;
306
+ // Preserve logIndex/index if already set by normalizeLog, otherwise set from log_index
307
+ if (log.logIndex === undefined && log.index === undefined) {
308
+ log.logIndex = log.log_index;
309
+ log.index = log.log_index;
310
+ }
301
311
  log.transactionHash = log.transaction_hash;
302
312
  log.blockNumber = parseInt(log.block_number);
303
313
  // Ensure topics are properly formatted
304
314
  const topics = [log.topic0, log.topic1, log.topic2, log.topic3]
305
315
  .filter(Boolean)
306
- .map((t) => {
307
- if (!t)
308
- return null;
309
- const topic = t.startsWith("0x") ? t : `0x${t}`;
310
- return ethers_1.ethers.zeroPadValue(topic, 32);
311
- });
316
+ .map(logs_decode_shared_1.padTopic32);
312
317
  // Ensure first topic (event signature) is present
313
318
  if (!topics[0]) {
314
319
  return log;
@@ -338,21 +343,28 @@ async function getLogParams(options, isIndexerCall = false) {
338
343
  if (!log.topics && log._originalTopics) {
339
344
  log.topics = [log._originalTopics.topic0, log._originalTopics.topic1, log._originalTopics.topic2, log._originalTopics.topic3]
340
345
  .filter(Boolean)
341
- .map((t) => {
342
- if (!t)
343
- return null;
344
- const topic = t.startsWith("0x") ? t : `0x${t}`;
345
- return ethers_1.ethers.zeroPadValue(topic, 32);
346
- });
346
+ .map(logs_decode_shared_1.padTopic32);
347
347
  }
348
348
  // Restore transaction hash if it was lost
349
349
  if (!log.transactionHash && log._originalTransactionHash) {
350
350
  log.transactionHash = log._originalTransactionHash;
351
351
  }
352
- const parsed = iface.parseLog(log);
353
- if (!parsed && !allowParseFailure)
354
- throw new Error(`Failed to parse log: ${JSON.stringify(log.transactionHash)}`);
355
- log.args = parsed === null || parsed === void 0 ? void 0 : parsed.args;
352
+ let parsed = null;
353
+ if (!iface) {
354
+ log.args = undefined;
355
+ }
356
+ else {
357
+ parsed = iface.parseLog(log);
358
+ if (!parsed && !allowParseFailure)
359
+ throw new Error(`Failed to parse log: ${JSON.stringify(log.transactionHash)}`);
360
+ // Enrich args with named properties to match Viem output structure
361
+ if ((parsed === null || parsed === void 0 ? void 0 : parsed.args) && event && iface) {
362
+ log.args = (0, logs_decode_shared_1.enrichEthersArgsWithNamedProperties)(parsed.args, event, iface);
363
+ }
364
+ else {
365
+ log.args = parsed === null || parsed === void 0 ? void 0 : parsed.args;
366
+ }
367
+ }
356
368
  if (entireLog)
357
369
  log.parsedLog = parsed;
358
370
  return onlyArgs ? log.args : log;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defillama/sdk",
3
- "version": "5.0.187",
3
+ "version": "5.0.192",
4
4
  "description": "SDK for calculating TVL",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -34,10 +34,13 @@
34
34
  "axios": "^1.6.5",
35
35
  "ethers": "^6.0.0",
36
36
  "p-limit": "^3.0.0",
37
- "tron-format-address": "^0.1.11"
37
+ "stream-json": "^1.9.1",
38
+ "tron-format-address": "^0.1.11",
39
+ "viem": "^2.38.6"
38
40
  },
39
41
  "devDependencies": {
40
42
  "@types/jest": "^29.2.3",
43
+ "@types/stream-json": "^1.7.8",
41
44
  "jest": "^29.3.1",
42
45
  "ts-jest": "^29.1.1",
43
46
  "ts-node": "^10.9.1",