@ledgerhq/coin-tester-evm 1.6.0 → 1.6.1-nightly.1

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.
Files changed (56) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +21 -0
  3. package/lib/src/helpers.d.ts +6 -6
  4. package/lib/src/helpers.d.ts.map +1 -1
  5. package/lib/src/helpers.js +12 -11
  6. package/lib/src/helpers.js.map +1 -1
  7. package/lib/src/indexer.d.ts.map +1 -1
  8. package/lib/src/indexer.js +193 -184
  9. package/lib/src/indexer.js.map +1 -1
  10. package/lib/src/scenarii/blast.d.ts.map +1 -1
  11. package/lib/src/scenarii/blast.js +8 -8
  12. package/lib/src/scenarii/blast.js.map +1 -1
  13. package/lib/src/scenarii/ethereum.d.ts.map +1 -1
  14. package/lib/src/scenarii/ethereum.js +10 -10
  15. package/lib/src/scenarii/ethereum.js.map +1 -1
  16. package/lib/src/scenarii/polygon.d.ts.map +1 -1
  17. package/lib/src/scenarii/polygon.js +11 -11
  18. package/lib/src/scenarii/polygon.js.map +1 -1
  19. package/lib/src/scenarii/scroll.d.ts.map +1 -1
  20. package/lib/src/scenarii/scroll.js +8 -8
  21. package/lib/src/scenarii/scroll.js.map +1 -1
  22. package/lib/src/scenarii/sonic.d.ts.map +1 -1
  23. package/lib/src/scenarii/sonic.js +8 -8
  24. package/lib/src/scenarii/sonic.js.map +1 -1
  25. package/lib/tsconfig.tsbuildinfo +1 -1
  26. package/lib-es/src/helpers.d.ts +6 -6
  27. package/lib-es/src/helpers.d.ts.map +1 -1
  28. package/lib-es/src/helpers.js +12 -11
  29. package/lib-es/src/helpers.js.map +1 -1
  30. package/lib-es/src/indexer.d.ts.map +1 -1
  31. package/lib-es/src/indexer.js +194 -185
  32. package/lib-es/src/indexer.js.map +1 -1
  33. package/lib-es/src/scenarii/blast.d.ts.map +1 -1
  34. package/lib-es/src/scenarii/blast.js +9 -9
  35. package/lib-es/src/scenarii/blast.js.map +1 -1
  36. package/lib-es/src/scenarii/ethereum.d.ts.map +1 -1
  37. package/lib-es/src/scenarii/ethereum.js +11 -11
  38. package/lib-es/src/scenarii/ethereum.js.map +1 -1
  39. package/lib-es/src/scenarii/polygon.d.ts.map +1 -1
  40. package/lib-es/src/scenarii/polygon.js +12 -12
  41. package/lib-es/src/scenarii/polygon.js.map +1 -1
  42. package/lib-es/src/scenarii/scroll.d.ts.map +1 -1
  43. package/lib-es/src/scenarii/scroll.js +9 -9
  44. package/lib-es/src/scenarii/scroll.js.map +1 -1
  45. package/lib-es/src/scenarii/sonic.d.ts.map +1 -1
  46. package/lib-es/src/scenarii/sonic.js +9 -9
  47. package/lib-es/src/scenarii/sonic.js.map +1 -1
  48. package/lib-es/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +8 -8
  50. package/src/helpers.ts +15 -14
  51. package/src/indexer.ts +200 -205
  52. package/src/scenarii/blast.ts +9 -11
  53. package/src/scenarii/ethereum.ts +11 -13
  54. package/src/scenarii/polygon.ts +12 -14
  55. package/src/scenarii/scroll.ts +9 -11
  56. package/src/scenarii/sonic.ts +9 -11
@@ -12,14 +12,15 @@ const ethers_1 = require("ethers");
12
12
  const index_1 = require("@ledgerhq/coin-evm/abis/index");
13
13
  const utils_1 = require("@ledgerhq/coin-evm/utils");
14
14
  const MAX_BLOCK_RANGE = 1024;
15
- const ERC20Interface = new ethers_1.utils.Interface(index_1.ERC20_ABI);
16
- const ERC721Interface = new ethers_1.utils.Interface(index_1.ERC721_ABI);
17
- const ERC1155Interface = new ethers_1.utils.Interface(index_1.ERC1155_ABI);
15
+ const ERC20Interface = new ethers_1.ethers.Interface(index_1.ERC20_ABI);
16
+ const ERC721Interface = new ethers_1.ethers.Interface(index_1.ERC721_ABI);
17
+ const ERC1155Interface = new ethers_1.ethers.Interface(index_1.ERC1155_ABI);
18
18
  const TRANSFER_EVENTS_TOPICS = {
19
- ERC20: ERC20Interface.getEventTopic("Transfer"),
20
- ERC721: ERC721Interface.getEventTopic("Transfer"),
21
- ERC1155: ERC1155Interface.getEventTopic("TransferSingle"),
19
+ ERC20: ERC20Interface.getEvent("Transfer")?.topicHash || "",
20
+ ERC721: ERC721Interface.getEvent("Transfer")?.topicHash || "",
21
+ ERC1155: ERC1155Interface.getEvent("TransferSingle")?.topicHash || "",
22
22
  };
23
+ const abiCoder = new ethers_1.AbiCoder();
23
24
  const explorerEtherscanOperationByAddress = {};
24
25
  const explorerEtherscanERC20EventsByAddress = {};
25
26
  const explorerEtherscanERC721EventsByAddress = {};
@@ -50,11 +51,21 @@ const resetIndexer = () => {
50
51
  };
51
52
  exports.resetIndexer = resetIndexer;
52
53
  const handleLog = async (log, provider) => {
53
- const contractDecimals = await provider
54
- .call({ to: log.address, data: ERC20Interface.encodeFunctionData("decimals") })
55
- .then(res => (!res || res === "0x" ? false : true));
56
- const isERC20 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC20 && contractDecimals;
57
- const isERC721 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC721 && !contractDecimals;
54
+ let hasDecimals = false;
55
+ try {
56
+ const res = await provider.call({
57
+ to: log.address,
58
+ data: ERC20Interface.encodeFunctionData("decimals"),
59
+ });
60
+ // if call didn’t revert and returned something valid
61
+ hasDecimals = !!(res && res !== "0x");
62
+ }
63
+ catch {
64
+ // execution reverted → no decimals()
65
+ hasDecimals = false;
66
+ }
67
+ const isERC20 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC20 && hasDecimals;
68
+ const isERC721 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC721 && !hasDecimals;
58
69
  const isERC1155 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC1155;
59
70
  if (isERC20) {
60
71
  return handleERC20Log(log, provider);
@@ -70,10 +81,10 @@ const handleERC20Log = async (log, provider) => {
70
81
  const [name, ticker, decimals, block, tx, receipt] = await Promise.all([
71
82
  provider
72
83
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("name") })
73
- .then(res => ethers_1.ethers.utils.defaultAbiCoder.decode(["string"], res)[0]),
84
+ .then(res => abiCoder.decode(["string"], res)[0]),
74
85
  provider
75
86
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("symbol") })
76
- .then(res => ethers_1.ethers.utils.defaultAbiCoder.decode(["string"], res)[0]),
87
+ .then(res => abiCoder.decode(["string"], res)[0]),
77
88
  provider
78
89
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("decimals") })
79
90
  .then(res => new bignumber_js_1.default(res).toString()),
@@ -81,29 +92,29 @@ const handleERC20Log = async (log, provider) => {
81
92
  provider.getTransaction(log.transactionHash),
82
93
  provider.getTransactionReceipt(log.transactionHash),
83
94
  ]);
84
- const from = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0]);
85
- const to = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
86
- const amount = ethers_1.ethers.BigNumber.from(log.data === "0x" ? 0 : log.data).toString();
95
+ const from = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[1])[0]);
96
+ const to = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[2])[0]);
97
+ const amount = BigInt(log.data === "0x" ? 0 : log.data).toString();
87
98
  const etherscanErc20Event = {
88
- blockNumber: block.number.toString(),
89
- timeStamp: block.timestamp.toString(),
99
+ blockNumber: block?.number.toString() || "0",
100
+ timeStamp: block?.timestamp.toString() || "0",
90
101
  hash: log.transactionHash,
91
- nonce: tx.nonce.toString(),
92
- blockHash: block.hash,
102
+ nonce: tx?.nonce.toString() || "0",
103
+ blockHash: block?.hash || "",
93
104
  from,
94
105
  to,
95
106
  value: amount,
96
107
  tokenName: name,
97
108
  tokenSymbol: ticker,
98
109
  tokenDecimal: decimals,
99
- transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
100
- gas: tx.gasLimit.toString(),
101
- gasPrice: tx.gasPrice?.toString() || "",
102
- cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
110
+ transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
111
+ gas: tx?.gasLimit.toString() || "0",
112
+ gasPrice: tx?.gasPrice?.toString() || "",
113
+ cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
103
114
  gasUsed: receipt?.gasUsed?.toString() || "0",
104
- input: tx.data,
105
- confirmations: tx.confirmations.toString(),
106
- contractAddress: tx.to.toLowerCase(),
115
+ input: tx?.data || "0x",
116
+ confirmations: tx?.confirmations.toString() || "0",
117
+ contractAddress: tx?.to.toLowerCase() || "",
107
118
  };
108
119
  if (!explorerEtherscanERC20EventsByAddress[from]) {
109
120
  explorerEtherscanERC20EventsByAddress[from] = new Map();
@@ -119,8 +130,9 @@ const handleERC20Log = async (log, provider) => {
119
130
  if (!explorerLedgerOperationByAddress[to]) {
120
131
  explorerLedgerOperationByAddress[to] = new Map();
121
132
  }
122
- const alreadyExistingOperation = explorerLedgerOperationByAddress[from].get(tx.hash) ||
123
- explorerLedgerOperationByAddress[to].get(tx.hash);
133
+ const txHash = tx?.hash;
134
+ const alreadyExistingOperation = (txHash && explorerLedgerOperationByAddress[from].get(txHash)) ||
135
+ (txHash && explorerLedgerOperationByAddress[to].get(txHash));
124
136
  const ledgerOperation = alreadyExistingOperation
125
137
  ? {
126
138
  ...alreadyExistingOperation,
@@ -135,16 +147,16 @@ const handleERC20Log = async (log, provider) => {
135
147
  }
136
148
  : {
137
149
  hash: log.transactionHash,
138
- transaction_type: receipt.type,
150
+ transaction_type: receipt?.type ?? 0,
139
151
  nonce: "",
140
152
  nonce_value: -1,
141
- value: tx.value.toString(),
142
- gas: tx.gasLimit.toString(),
143
- gas_price: receipt.effectiveGasPrice.toString(),
144
- max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas.toString() : null,
145
- max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
146
- from: tx.from,
147
- to: tx.to,
153
+ value: tx?.value.toString() ?? "0",
154
+ gas: tx?.gasLimit.toString() ?? "0",
155
+ gas_price: receipt?.gasPrice.toString() ?? "0",
156
+ max_fee_per_gas: tx?.type === 2 ? tx.maxFeePerGas.toString() : null,
157
+ max_priority_fee_per_gas: tx?.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
158
+ from: tx?.from ?? "0x",
159
+ to: tx?.to ?? "0x0000000000000000000000000000000000000000",
148
160
  transfer_events: [
149
161
  {
150
162
  contract: log.address,
@@ -157,16 +169,16 @@ const handleERC20Log = async (log, provider) => {
157
169
  erc1155_transfer_events: [],
158
170
  approval_events: [],
159
171
  actions: [],
160
- confirmations: tx.confirmations,
172
+ confirmations: tx?.confirmations ? await tx.confirmations() : 0,
161
173
  input: null,
162
- gas_used: receipt.gasUsed.toString(),
163
- cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
164
- status: receipt.status,
165
- received_at: new Date(block.timestamp * 1000).toISOString(),
174
+ gas_used: receipt?.gasUsed.toString() ?? "0",
175
+ cumulative_gas_used: receipt?.cumulativeGasUsed.toString() ?? "0",
176
+ status: receipt?.status ?? 0,
177
+ received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
166
178
  block: {
167
179
  hash: log.blockHash,
168
180
  height: log.blockNumber,
169
- time: new Date(block.timestamp * 1000).toISOString(),
181
+ time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
170
182
  },
171
183
  };
172
184
  explorerLedgerOperationByAddress[from].set(ledgerOperation.hash, ledgerOperation);
@@ -178,25 +190,25 @@ const handleERC721Log = async (log, provider) => {
178
190
  provider.getTransaction(log.transactionHash),
179
191
  provider.getTransactionReceipt(log.transactionHash),
180
192
  ]);
181
- const from = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0]);
182
- const to = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
183
- const tokenID = ethers_1.ethers.utils.defaultAbiCoder.decode(["uint256"], log.topics[3])[0].toString();
193
+ const from = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[1])[0]);
194
+ const to = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[2])[0]);
195
+ const tokenID = abiCoder.decode(["uint256"], log.topics[3])[0].toString();
184
196
  const erc721Event = {
185
- blockNumber: block.number.toString(),
186
- timeStamp: block.timestamp.toString(),
187
- hash: tx.hash,
188
- nonce: tx.nonce.toString(),
189
- blockHash: block.hash,
197
+ blockNumber: block?.number.toString() || "0",
198
+ timeStamp: block?.timestamp.toString() || "0",
199
+ hash: tx?.hash || "",
200
+ nonce: tx?.nonce.toString() || "0",
201
+ blockHash: block?.hash || "",
190
202
  from,
191
203
  to,
192
- transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
193
- gas: tx.gasLimit.toString(),
194
- gasPrice: tx.gasPrice?.toString() || "",
195
- cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
204
+ transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
205
+ gas: tx?.gasLimit.toString() || "0",
206
+ gasPrice: tx?.gasPrice?.toString() || "",
207
+ cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
196
208
  gasUsed: receipt?.gasUsed?.toString() || "0",
197
- input: tx.data,
198
- confirmations: tx.confirmations.toString(),
199
- contractAddress: tx.to,
209
+ input: tx?.data || "0x",
210
+ confirmations: tx?.confirmations.toString() || "0",
211
+ contractAddress: tx?.to ?? "0x0000000000000000000000000000000000000000",
200
212
  tokenID,
201
213
  tokenName: "tokenName",
202
214
  tokenSymbol: "tokenSymbol",
@@ -216,8 +228,9 @@ const handleERC721Log = async (log, provider) => {
216
228
  if (!explorerLedgerOperationByAddress[to]) {
217
229
  explorerLedgerOperationByAddress[to] = new Map();
218
230
  }
219
- const alreadyExistingOperation = explorerLedgerOperationByAddress[from].get(tx.hash) ||
220
- explorerLedgerOperationByAddress[to].get(tx.hash);
231
+ const txHash = tx?.hash;
232
+ const alreadyExistingOperation = (txHash && explorerLedgerOperationByAddress[from].get(txHash)) ||
233
+ (txHash && explorerLedgerOperationByAddress[to].get(txHash));
221
234
  const ledgerOperation = alreadyExistingOperation
222
235
  ? {
223
236
  ...alreadyExistingOperation,
@@ -232,16 +245,16 @@ const handleERC721Log = async (log, provider) => {
232
245
  }
233
246
  : {
234
247
  hash: log.transactionHash,
235
- transaction_type: receipt.type,
248
+ transaction_type: receipt?.type ?? 0,
236
249
  nonce: "",
237
250
  nonce_value: -1,
238
- value: tx.value.toString(),
239
- gas: tx.gasLimit.toString(),
240
- gas_price: receipt.effectiveGasPrice.toString(),
241
- max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas.toString() : null,
242
- max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
243
- from: tx.from,
244
- to: tx.to,
251
+ value: tx?.value.toString() ?? "0",
252
+ gas: tx?.gasLimit.toString() ?? "0",
253
+ gas_price: receipt?.gasPrice.toString() ?? "0",
254
+ max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas.toString() : null,
255
+ max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas.toString() : null,
256
+ from: tx?.from ?? "0x",
257
+ to: tx?.to ?? "0x0000000000000000000000000000000000000000",
245
258
  transfer_events: [],
246
259
  erc721_transfer_events: [
247
260
  {
@@ -254,16 +267,16 @@ const handleERC721Log = async (log, provider) => {
254
267
  erc1155_transfer_events: [],
255
268
  approval_events: [],
256
269
  actions: [],
257
- confirmations: tx.confirmations,
270
+ confirmations: tx?.confirmations ? await tx.confirmations() : 0,
258
271
  input: null,
259
- gas_used: receipt.gasUsed.toString(),
260
- cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
261
- status: receipt.status,
262
- received_at: new Date(block.timestamp * 1000).toISOString(),
272
+ gas_used: receipt?.gasUsed.toString() ?? "0",
273
+ cumulative_gas_used: receipt?.cumulativeGasUsed.toString() ?? "0",
274
+ status: receipt?.status ?? 0,
275
+ received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
263
276
  block: {
264
277
  hash: log.blockHash,
265
278
  height: log.blockNumber,
266
- time: new Date(block.timestamp * 1000).toISOString(),
279
+ time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
267
280
  },
268
281
  };
269
282
  explorerLedgerOperationByAddress[from].set(ledgerOperation.hash, ledgerOperation);
@@ -275,28 +288,28 @@ const handleERC1155Log = async (log, provider) => {
275
288
  provider.getTransaction(log.transactionHash),
276
289
  provider.getTransactionReceipt(log.transactionHash),
277
290
  ]);
278
- const from = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
279
- const to = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[3])[0]);
280
- const operator = (0, utils_1.safeEncodeEIP55)(ethers_1.ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0]);
281
- const transfersMap = ethers_1.ethers.utils.defaultAbiCoder
291
+ const from = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[2])[0]);
292
+ const to = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[3])[0]);
293
+ const operator = (0, utils_1.safeEncodeEIP55)(abiCoder.decode(["address"], log.topics[1])[0]);
294
+ const transfersMap = abiCoder
282
295
  .decode(["uint256", "uint256"], log.data)
283
296
  .map((value, index) => [index === 0 ? "id" : "value", value.toString()]);
284
297
  const etherscanERC1155Events = transfersMap.map(([id, value]) => ({
285
- blockNumber: block.number.toString(),
286
- timeStamp: block.timestamp.toString(),
287
- hash: tx.hash,
288
- nonce: tx.nonce.toString(),
289
- blockHash: block.hash,
298
+ blockNumber: block?.number.toString() || "0",
299
+ timeStamp: block?.timestamp.toString() || "0",
300
+ hash: tx?.hash || "",
301
+ nonce: tx?.nonce.toString() || "0",
302
+ blockHash: block?.hash || "",
290
303
  from,
291
304
  to,
292
- transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
293
- gas: tx.gasLimit.toString(),
294
- gasPrice: tx.gasPrice?.toString() || "",
295
- cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
305
+ transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
306
+ gas: tx?.gasLimit.toString() || "0",
307
+ gasPrice: tx?.gasPrice?.toString() || "",
308
+ cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
296
309
  gasUsed: receipt?.gasUsed?.toString() || "0",
297
- input: tx.data,
298
- confirmations: tx.confirmations.toString(),
299
- contractAddress: tx.to,
310
+ input: tx?.data || "0x",
311
+ confirmations: tx?.confirmations.toString() || "0",
312
+ contractAddress: tx?.to ?? "0x0000000000000000000000000000000000000000",
300
313
  tokenID: id,
301
314
  tokenValue: value,
302
315
  tokenName: "tokenName",
@@ -318,8 +331,9 @@ const handleERC1155Log = async (log, provider) => {
318
331
  if (!explorerLedgerOperationByAddress[to]) {
319
332
  explorerLedgerOperationByAddress[to] = new Map();
320
333
  }
321
- const alreadyExistingOperation = explorerLedgerOperationByAddress[from].get(tx.hash) ||
322
- explorerLedgerOperationByAddress[to].get(tx.hash);
334
+ const txHash = tx?.hash;
335
+ const alreadyExistingOperation = (txHash && explorerLedgerOperationByAddress[from].get(txHash)) ||
336
+ (txHash && explorerLedgerOperationByAddress[to].get(txHash));
323
337
  const ledgerOperation = alreadyExistingOperation
324
338
  ? {
325
339
  ...alreadyExistingOperation,
@@ -334,17 +348,17 @@ const handleERC1155Log = async (log, provider) => {
334
348
  ],
335
349
  }
336
350
  : {
337
- hash: log.transactionHash,
338
- transaction_type: receipt.type,
351
+ hash: log.transactionHash || "",
352
+ transaction_type: receipt?.type ?? 0,
339
353
  nonce: "",
340
354
  nonce_value: -1,
341
- value: tx.value.toString(),
342
- gas: tx.gasLimit.toString(),
343
- gas_price: receipt.effectiveGasPrice.toString(),
344
- max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas.toString() : null,
345
- max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
346
- from: tx.from,
347
- to: tx.to,
355
+ value: tx?.value.toString() || "0",
356
+ gas: tx?.gasLimit.toString() || "0",
357
+ gas_price: receipt?.gasPrice.toString() || "0",
358
+ max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas.toString() : null,
359
+ max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas.toString() : null,
360
+ from: tx?.from ?? "0x",
361
+ to: tx?.to ?? "0x0000000000000000000000000000000000000000",
348
362
  transfer_events: [],
349
363
  erc721_transfer_events: [],
350
364
  erc1155_transfer_events: [
@@ -358,52 +372,52 @@ const handleERC1155Log = async (log, provider) => {
358
372
  ],
359
373
  approval_events: [],
360
374
  actions: [],
361
- confirmations: tx.confirmations,
375
+ confirmations: tx?.confirmations ? await tx.confirmations() : 0,
362
376
  input: null,
363
- gas_used: receipt.gasUsed.toString(),
364
- cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
365
- status: receipt.status,
366
- received_at: new Date(block.timestamp * 1000).toISOString(),
377
+ gas_used: receipt?.gasUsed.toString() || "0",
378
+ cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
379
+ status: receipt?.status ?? 0,
380
+ received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
367
381
  block: {
368
382
  hash: log.blockHash,
369
383
  height: log.blockNumber,
370
- time: new Date(block.timestamp * 1000).toISOString(),
384
+ time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
371
385
  },
372
386
  };
373
387
  explorerLedgerOperationByAddress[from].set(ledgerOperation.hash, ledgerOperation);
374
388
  explorerLedgerOperationByAddress[to].set(ledgerOperation.hash, ledgerOperation);
375
389
  };
376
390
  const handleBlock = async (blockNumber, provider) => {
377
- const block = await provider.getBlockWithTransactions(blockNumber);
391
+ const block = await provider.getBlock(blockNumber, true);
378
392
  for (const transaction of block?.transactions || []) {
379
393
  const [tx, receipt, traces] = await Promise.all([
380
- provider.getTransaction(transaction.hash),
381
- provider.getTransactionReceipt(transaction.hash),
382
- provider.send("trace_transaction", [transaction.hash]).catch(() => []),
394
+ provider.getTransaction(transaction),
395
+ provider.getTransactionReceipt(transaction),
396
+ provider.send("trace_transaction", [transaction]).catch(() => []),
383
397
  ]);
384
- const code = transaction.to ? await provider.getCode(transaction.to) : false;
385
- const from = (0, utils_1.safeEncodeEIP55)(transaction.from);
386
- const to = (0, utils_1.safeEncodeEIP55)(transaction.to || "");
398
+ const code = tx?.to ? await provider.getCode(tx?.to) : false;
399
+ const from = (0, utils_1.safeEncodeEIP55)(tx?.from || "");
400
+ const to = (0, utils_1.safeEncodeEIP55)(tx?.to || "");
387
401
  const etherscanOperation = {
388
- blockNumber: block.number.toString(),
389
- timeStamp: block.timestamp.toString(),
390
- hash: transaction.hash,
391
- nonce: transaction.nonce.toString(),
392
- blockHash: block.hash,
393
- transactionIndex: block.transactions.indexOf(transaction).toString(),
402
+ blockNumber: block?.number.toString() || "0",
403
+ timeStamp: block?.timestamp.toString() || "0",
404
+ hash: tx?.hash || "",
405
+ nonce: tx?.nonce.toString() || "0",
406
+ blockHash: block?.hash || "",
407
+ transactionIndex: block?.transactions.indexOf(transaction).toString() || "0",
394
408
  from,
395
409
  to,
396
- value: transaction.value.toBigInt().toString(),
397
- gas: transaction.gasLimit.toString(),
398
- gasPrice: transaction.gasPrice?.toString() || "",
399
- isError: receipt.status === 1 ? "0" : "1",
400
- txreceipt_status: receipt.status.toString(),
401
- input: transaction.data,
402
- contractAddress: code === "0x" ? "" : transaction.to,
403
- cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
410
+ value: tx?.value.toString() || "0",
411
+ gas: tx?.gasLimit.toString() || "0",
412
+ gasPrice: tx?.gasPrice?.toString() || "",
413
+ isError: receipt?.status === 1 ? "0" : "1",
414
+ txreceipt_status: receipt?.status.toString() || "0",
415
+ input: tx?.data,
416
+ contractAddress: code === "0x" ? "" : tx?.to ?? "0x0000000000000000000000000000000000000000",
417
+ cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
404
418
  gasUsed: receipt?.gasUsed?.toString() || "0",
405
- confirmations: transaction.confirmations.toString(),
406
- methodId: transaction.data?.length > 10 ? transaction.data.slice(0, 10) : "",
419
+ confirmations: tx?.confirmations.toString() || "0",
420
+ methodId: tx?.data && tx.data.length > 10 ? tx.data.slice(0, 10) : "",
407
421
  functionName: "",
408
422
  };
409
423
  if (!explorerEtherscanOperationByAddress[from]) {
@@ -421,32 +435,32 @@ const handleBlock = async (blockNumber, provider) => {
421
435
  explorerLedgerOperationByAddress[to] = new Map();
422
436
  }
423
437
  const ledgerOperation = {
424
- hash: receipt.transactionHash,
425
- transaction_type: receipt.type,
438
+ hash: receipt?.hash || "",
439
+ transaction_type: receipt?.type || 0,
426
440
  nonce: "",
427
441
  nonce_value: -1,
428
- value: tx.value.toString(),
429
- gas: tx.gasLimit.toString(),
430
- gas_price: receipt.effectiveGasPrice.toString(),
431
- max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas.toString() : null,
432
- max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
433
- from: tx.from,
434
- to: tx.to,
442
+ value: tx?.value.toString() || "0",
443
+ gas: tx?.gasLimit.toString() || "0",
444
+ gas_price: receipt?.gasPrice.toString() || "",
445
+ max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas.toString() : null,
446
+ max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas.toString() : null,
447
+ from: tx?.from || "",
448
+ to: tx?.to ?? "0x0000000000000000000000000000000000000000",
435
449
  transfer_events: [],
436
450
  erc721_transfer_events: [],
437
451
  erc1155_transfer_events: [],
438
452
  approval_events: [],
439
453
  actions: [],
440
- confirmations: tx.confirmations,
454
+ confirmations: tx?.confirmations ? await tx.confirmations() : 0,
441
455
  input: null,
442
- gas_used: receipt.gasUsed.toString(),
443
- cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
444
- status: receipt.status,
445
- received_at: new Date(block.timestamp * 1000).toISOString(),
456
+ gas_used: receipt?.gasUsed.toString() || "0",
457
+ cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
458
+ status: receipt?.status ?? 0,
459
+ received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
446
460
  block: {
447
- hash: receipt.blockHash,
448
- height: receipt.blockNumber,
449
- time: new Date(block.timestamp * 1000).toISOString(),
461
+ hash: receipt?.blockHash || "",
462
+ height: receipt?.blockNumber || 0,
463
+ time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
450
464
  },
451
465
  };
452
466
  explorerLedgerOperationByAddress[from].set(ledgerOperation.hash, ledgerOperation);
@@ -459,20 +473,18 @@ const handleBlock = async (blockNumber, provider) => {
459
473
  const to = (0, utils_1.safeEncodeEIP55)(action.to || "");
460
474
  const etherscanInternalTransaction = {
461
475
  blockNumber: blockNumber.toString(),
462
- timeStamp: block.timestamp.toString(),
476
+ timeStamp: block?.timestamp.toString() || "0",
463
477
  hash: transactionHash,
464
478
  from,
465
479
  to,
466
- value: ethers_1.ethers.BigNumber.from(action.value).toBigInt().toString(),
480
+ value: BigInt(action.value).toString() || "0",
467
481
  contractAddress: code === "0x" ? "" : action.to,
468
482
  input: action.input || "0x",
469
483
  type,
470
- gas: ethers_1.ethers.BigNumber.from(action.gas).toBigInt().toString(),
471
- gasUsed: ethers_1.ethers.BigNumber.from(result?.gasUsed || "0")
472
- .toBigInt()
473
- .toString(),
484
+ gas: BigInt(action.gas).toString(),
485
+ gasUsed: BigInt(result?.gasUsed || "0").toString(),
474
486
  traceId: transactionPosition.toString(),
475
- isError: receipt.status === 1 ? "0" : "1",
487
+ isError: receipt?.status === 1 ? "0" : "1",
476
488
  errCode: "",
477
489
  };
478
490
  if (!explorerEtherscanInternalByAddress[from]) {
@@ -489,8 +501,9 @@ const handleBlock = async (blockNumber, provider) => {
489
501
  if (!explorerLedgerOperationByAddress[to]) {
490
502
  explorerLedgerOperationByAddress[to] = new Map();
491
503
  }
492
- const alreadyExistingOperation = explorerLedgerOperationByAddress[from].get(tx.hash) ||
493
- explorerLedgerOperationByAddress[to].get(tx.hash);
504
+ const txHash = tx?.hash;
505
+ const alreadyExistingOperation = (txHash && explorerLedgerOperationByAddress[from].get(txHash)) ||
506
+ (txHash && explorerLedgerOperationByAddress[to].get(txHash));
494
507
  const ledgerOperation = alreadyExistingOperation
495
508
  ? {
496
509
  ...alreadyExistingOperation,
@@ -500,27 +513,25 @@ const handleBlock = async (blockNumber, provider) => {
500
513
  from,
501
514
  to,
502
515
  input: null,
503
- value: ethers_1.ethers.BigNumber.from(action.value).toBigInt().toString(),
504
- gas: ethers_1.ethers.BigNumber.from(action.gas).toBigInt().toString(),
505
- gas_used: ethers_1.ethers.BigNumber.from(result?.gasUsed || "0")
506
- .toBigInt()
507
- .toString(),
516
+ value: BigInt(action.value).toString(),
517
+ gas: BigInt(action.gas).toString(),
518
+ gas_used: BigInt(result?.gasUsed || "0").toString(),
508
519
  error: null,
509
520
  },
510
521
  ],
511
522
  }
512
523
  : {
513
- hash: receipt.transactionHash,
514
- transaction_type: receipt.type,
524
+ hash: receipt?.hash || "",
525
+ transaction_type: receipt?.type ?? 0,
515
526
  nonce: "",
516
527
  nonce_value: -1,
517
- value: tx.value.toString(),
518
- gas: tx.gasLimit.toString(),
519
- gas_price: receipt.effectiveGasPrice.toString(),
520
- max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas.toString() : null,
521
- max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas.toString() : null,
522
- from: tx.from,
523
- to: tx.to,
528
+ value: tx?.value.toString() || "0",
529
+ gas: tx?.gasLimit.toString() || "0",
530
+ gas_price: receipt?.gasPrice.toString() || "0",
531
+ max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas.toString() : null,
532
+ max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas.toString() : null,
533
+ from: tx?.from || "0x",
534
+ to: tx?.to ?? "0x0000000000000000000000000000000000000000",
524
535
  transfer_events: [],
525
536
  erc721_transfer_events: [],
526
537
  erc1155_transfer_events: [],
@@ -530,24 +541,22 @@ const handleBlock = async (blockNumber, provider) => {
530
541
  from,
531
542
  to,
532
543
  input: null,
533
- value: ethers_1.ethers.BigNumber.from(action.value).toBigInt().toString(),
534
- gas: ethers_1.ethers.BigNumber.from(action.gas).toBigInt().toString(),
535
- gas_used: ethers_1.ethers.BigNumber.from(result?.gasUsed || "0")
536
- .toBigInt()
537
- .toString(),
544
+ value: BigInt(action.value).toString(),
545
+ gas: BigInt(action.gas).toString(),
546
+ gas_used: BigInt(result?.gasUsed || "0").toString(),
538
547
  error: null,
539
548
  },
540
549
  ],
541
- confirmations: tx.confirmations,
550
+ confirmations: tx?.confirmations ? await tx.confirmations() : 0,
542
551
  input: null,
543
- gas_used: receipt.gasUsed.toString(),
544
- cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
545
- status: receipt.status,
546
- received_at: new Date(block.timestamp * 1000).toISOString(),
552
+ gas_used: receipt?.gasUsed.toString() || "0",
553
+ cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
554
+ status: receipt?.status ?? 0,
555
+ received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
547
556
  block: {
548
- hash: receipt.blockHash,
549
- height: receipt.blockNumber,
550
- time: new Date(block.timestamp * 1000).toISOString(),
557
+ hash: receipt?.blockHash || "",
558
+ height: receipt?.blockNumber || 0,
559
+ time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
551
560
  },
552
561
  };
553
562
  explorerLedgerOperationByAddress[from].set(ledgerOperation.hash, ledgerOperation);
@@ -563,7 +572,7 @@ const indexBlocks = async () => {
563
572
  if (!fromBlock) {
564
573
  throw new Error("fromBlock is not set");
565
574
  }
566
- const provider = new ethers_1.providers.StaticJsonRpcProvider(process.env.RPC);
575
+ const provider = new ethers_1.ethers.JsonRpcProvider(process.env.RPC);
567
576
  let latestBlockNumber = await provider.getBlockNumber();
568
577
  const toBlock = Math.min(fromBlock + MAX_BLOCK_RANGE, latestBlockNumber);
569
578
  const rangeSize = toBlock - fromBlock + 1;