@ledgerhq/coin-tester-evm 1.6.0-nightly.7 → 1.6.0

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 +41 -47
  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 +11 -12
  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 +184 -193
  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 +11 -12
  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 +185 -194
  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 +11 -11
  50. package/src/helpers.ts +14 -15
  51. package/src/indexer.ts +205 -200
  52. package/src/scenarii/blast.ts +11 -9
  53. package/src/scenarii/ethereum.ts +13 -11
  54. package/src/scenarii/polygon.ts +14 -12
  55. package/src/scenarii/scroll.ts +11 -9
  56. package/src/scenarii/sonic.ts +11 -9
package/src/indexer.ts CHANGED
@@ -2,7 +2,7 @@ import BigNumber from "bignumber.js";
2
2
  import { SetupServerApi, setupServer } from "msw/node";
3
3
  import BlueBirdPromise from "bluebird";
4
4
  import { http, HttpResponse, bypass } from "msw";
5
- import { AbiCoder, ethers } from "ethers";
5
+ import { utils, providers, ethers } from "ethers";
6
6
  import { ERC20_ABI, ERC721_ABI, ERC1155_ABI } from "@ledgerhq/coin-evm/abis/index";
7
7
  import { safeEncodeEIP55 } from "@ledgerhq/coin-evm/utils";
8
8
  import { EvmConfigInfo } from "@ledgerhq/coin-evm/config";
@@ -41,18 +41,16 @@ type TraceTransaction = {
41
41
 
42
42
  const MAX_BLOCK_RANGE = 1024;
43
43
 
44
- const ERC20Interface = new ethers.Interface(ERC20_ABI);
45
- const ERC721Interface = new ethers.Interface(ERC721_ABI);
46
- const ERC1155Interface = new ethers.Interface(ERC1155_ABI);
44
+ const ERC20Interface = new utils.Interface(ERC20_ABI);
45
+ const ERC721Interface = new utils.Interface(ERC721_ABI);
46
+ const ERC1155Interface = new utils.Interface(ERC1155_ABI);
47
47
 
48
48
  const TRANSFER_EVENTS_TOPICS = {
49
- ERC20: ERC20Interface.getEvent("Transfer")?.topicHash || "",
50
- ERC721: ERC721Interface.getEvent("Transfer")?.topicHash || "",
51
- ERC1155: ERC1155Interface.getEvent("TransferSingle")?.topicHash || "",
49
+ ERC20: ERC20Interface.getEventTopic("Transfer"),
50
+ ERC721: ERC721Interface.getEventTopic("Transfer"),
51
+ ERC1155: ERC1155Interface.getEventTopic("TransferSingle"),
52
52
  };
53
53
 
54
- const abiCoder = new AbiCoder();
55
-
56
54
  const explorerEtherscanOperationByAddress: Record<string, Map<string, EtherscanOperation> | null> =
57
55
  {};
58
56
  const explorerEtherscanERC20EventsByAddress: Record<
@@ -100,23 +98,13 @@ export const resetIndexer = () => {
100
98
  }
101
99
  };
102
100
 
103
- const handleLog = async (log: ethers.Log, provider: ethers.JsonRpcProvider) => {
104
- let hasDecimals = false;
105
-
106
- try {
107
- const res = await provider.call({
108
- to: log.address,
109
- data: ERC20Interface.encodeFunctionData("decimals"),
110
- });
111
- // if call didn’t revert and returned something valid
112
- hasDecimals = !!(res && res !== "0x");
113
- } catch {
114
- // execution reverted → no decimals()
115
- hasDecimals = false;
116
- }
101
+ const handleLog = async (log: providers.Log, provider: ethers.providers.StaticJsonRpcProvider) => {
102
+ const contractDecimals = await provider
103
+ .call({ to: log.address, data: ERC20Interface.encodeFunctionData("decimals") })
104
+ .then(res => (!res || res === "0x" ? false : true));
117
105
 
118
- const isERC20 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC20 && hasDecimals;
119
- const isERC721 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC721 && !hasDecimals;
106
+ const isERC20 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC20 && contractDecimals;
107
+ const isERC721 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC721 && !contractDecimals;
120
108
  const isERC1155 = log.topics[0] === TRANSFER_EVENTS_TOPICS.ERC1155;
121
109
 
122
110
  if (isERC20) {
@@ -128,14 +116,17 @@ const handleLog = async (log: ethers.Log, provider: ethers.JsonRpcProvider) => {
128
116
  }
129
117
  };
130
118
 
131
- const handleERC20Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider) => {
119
+ const handleERC20Log = async (
120
+ log: providers.Log,
121
+ provider: ethers.providers.StaticJsonRpcProvider,
122
+ ) => {
132
123
  const [name, ticker, decimals, block, tx, receipt] = await Promise.all([
133
124
  provider
134
125
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("name") })
135
- .then(res => abiCoder.decode(["string"], res)[0]),
126
+ .then(res => ethers.utils.defaultAbiCoder.decode(["string"], res)[0]),
136
127
  provider
137
128
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("symbol") })
138
- .then(res => abiCoder.decode(["string"], res)[0]),
129
+ .then(res => ethers.utils.defaultAbiCoder.decode(["string"], res)[0]),
139
130
  provider
140
131
  .call({ to: log.address, data: ERC20Interface.encodeFunctionData("decimals") })
141
132
  .then(res => new BigNumber(res).toString()),
@@ -144,30 +135,30 @@ const handleERC20Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider)
144
135
  provider.getTransactionReceipt(log.transactionHash),
145
136
  ]);
146
137
 
147
- const from = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[1])[0]);
148
- const to = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[2])[0]);
149
- const amount = BigInt(log.data === "0x" ? 0 : log.data).toString();
138
+ const from = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0]);
139
+ const to = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
140
+ const amount = ethers.BigNumber.from(log.data === "0x" ? 0 : log.data).toString();
150
141
 
151
142
  const etherscanErc20Event: EtherscanERC20Event = {
152
- blockNumber: block?.number.toString() || "0",
153
- timeStamp: block?.timestamp.toString() || "0",
143
+ blockNumber: block.number.toString(),
144
+ timeStamp: block.timestamp.toString(),
154
145
  hash: log.transactionHash,
155
- nonce: tx?.nonce.toString() || "0",
156
- blockHash: block?.hash || "",
146
+ nonce: tx.nonce.toString(),
147
+ blockHash: block.hash,
157
148
  from,
158
149
  to,
159
150
  value: amount,
160
151
  tokenName: name,
161
152
  tokenSymbol: ticker,
162
153
  tokenDecimal: decimals,
163
- transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
164
- gas: tx?.gasLimit.toString() || "0",
165
- gasPrice: tx?.gasPrice?.toString() || "",
166
- cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
154
+ transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
155
+ gas: tx.gasLimit.toString(),
156
+ gasPrice: tx.gasPrice?.toString() || "",
157
+ cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
167
158
  gasUsed: receipt?.gasUsed?.toString() || "0",
168
- input: tx?.data || "0x",
169
- confirmations: tx?.confirmations.toString() || "0",
170
- contractAddress: tx?.to!.toLowerCase() || "",
159
+ input: tx.data,
160
+ confirmations: tx.confirmations.toString(),
161
+ contractAddress: tx.to!.toLowerCase(),
171
162
  };
172
163
 
173
164
  if (!explorerEtherscanERC20EventsByAddress[from]) {
@@ -185,10 +176,9 @@ const handleERC20Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider)
185
176
  if (!explorerLedgerOperationByAddress[to]) {
186
177
  explorerLedgerOperationByAddress[to] = new Map<string, LedgerExplorerOperation>();
187
178
  }
188
- const txHash = tx?.hash;
189
179
  const alreadyExistingOperation =
190
- (txHash && explorerLedgerOperationByAddress[from]!.get(txHash)) ||
191
- (txHash && explorerLedgerOperationByAddress[to]!.get(txHash));
180
+ explorerLedgerOperationByAddress[from]!.get(tx.hash) ||
181
+ explorerLedgerOperationByAddress[to]!.get(tx.hash);
192
182
  const ledgerOperation: LedgerExplorerOperation = alreadyExistingOperation
193
183
  ? {
194
184
  ...alreadyExistingOperation,
@@ -203,16 +193,16 @@ const handleERC20Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider)
203
193
  }
204
194
  : {
205
195
  hash: log.transactionHash,
206
- transaction_type: receipt?.type ?? 0,
196
+ transaction_type: receipt.type,
207
197
  nonce: "",
208
198
  nonce_value: -1,
209
- value: tx?.value.toString() ?? "0",
210
- gas: tx?.gasLimit.toString() ?? "0",
211
- gas_price: receipt?.gasPrice.toString() ?? "0",
212
- max_fee_per_gas: tx?.type === 2 ? tx.maxFeePerGas!.toString() : null,
213
- max_priority_fee_per_gas: tx?.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
214
- from: tx?.from ?? "0x",
215
- to: tx?.to ?? "0x0000000000000000000000000000000000000000",
199
+ value: tx.value.toString(),
200
+ gas: tx.gasLimit.toString(),
201
+ gas_price: receipt.effectiveGasPrice.toString(),
202
+ max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas!.toString() : null,
203
+ max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
204
+ from: tx.from,
205
+ to: tx.to!,
216
206
  transfer_events: [
217
207
  {
218
208
  contract: log.address,
@@ -225,49 +215,52 @@ const handleERC20Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider)
225
215
  erc1155_transfer_events: [],
226
216
  approval_events: [],
227
217
  actions: [],
228
- confirmations: tx?.confirmations ? await tx.confirmations() : 0,
218
+ confirmations: tx.confirmations,
229
219
  input: null,
230
- gas_used: receipt?.gasUsed.toString() ?? "0",
231
- cumulative_gas_used: receipt?.cumulativeGasUsed.toString() ?? "0",
232
- status: receipt?.status ?? 0,
233
- received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
220
+ gas_used: receipt.gasUsed.toString(),
221
+ cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
222
+ status: receipt.status!,
223
+ received_at: new Date(block.timestamp * 1000).toISOString(),
234
224
  block: {
235
225
  hash: log.blockHash,
236
226
  height: log.blockNumber,
237
- time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
227
+ time: new Date(block.timestamp * 1000).toISOString(),
238
228
  },
239
229
  };
240
230
  explorerLedgerOperationByAddress[from]!.set(ledgerOperation.hash, ledgerOperation);
241
231
  explorerLedgerOperationByAddress[to]!.set(ledgerOperation.hash, ledgerOperation);
242
232
  };
243
233
 
244
- const handleERC721Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider) => {
234
+ const handleERC721Log = async (
235
+ log: providers.Log,
236
+ provider: ethers.providers.StaticJsonRpcProvider,
237
+ ) => {
245
238
  const [block, tx, receipt] = await Promise.all([
246
239
  provider.getBlock(log.blockHash),
247
240
  provider.getTransaction(log.transactionHash),
248
241
  provider.getTransactionReceipt(log.transactionHash),
249
242
  ]);
250
243
 
251
- const from = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[1])[0]);
252
- const to = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[2])[0]);
253
- const tokenID = abiCoder.decode(["uint256"], log.topics[3])[0].toString();
244
+ const from = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0]);
245
+ const to = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
246
+ const tokenID = ethers.utils.defaultAbiCoder.decode(["uint256"], log.topics[3])[0].toString();
254
247
 
255
248
  const erc721Event: EtherscanERC721Event = {
256
- blockNumber: block?.number.toString() || "0",
257
- timeStamp: block?.timestamp.toString() || "0",
258
- hash: tx?.hash || "",
259
- nonce: tx?.nonce.toString() || "0",
260
- blockHash: block?.hash || "",
249
+ blockNumber: block.number.toString(),
250
+ timeStamp: block.timestamp.toString(),
251
+ hash: tx.hash,
252
+ nonce: tx.nonce.toString(),
253
+ blockHash: block.hash,
261
254
  from,
262
255
  to,
263
- transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
264
- gas: tx?.gasLimit.toString() || "0",
265
- gasPrice: tx?.gasPrice?.toString() || "",
266
- cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
256
+ transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
257
+ gas: tx.gasLimit.toString(),
258
+ gasPrice: tx.gasPrice?.toString() || "",
259
+ cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
267
260
  gasUsed: receipt?.gasUsed?.toString() || "0",
268
- input: tx?.data || "0x",
269
- confirmations: tx?.confirmations.toString() || "0",
270
- contractAddress: tx?.to ?? "0x0000000000000000000000000000000000000000",
261
+ input: tx.data,
262
+ confirmations: tx.confirmations.toString(),
263
+ contractAddress: tx.to!,
271
264
  tokenID,
272
265
  tokenName: "tokenName",
273
266
  tokenSymbol: "tokenSymbol",
@@ -289,10 +282,9 @@ const handleERC721Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider
289
282
  if (!explorerLedgerOperationByAddress[to]) {
290
283
  explorerLedgerOperationByAddress[to] = new Map<string, LedgerExplorerOperation>();
291
284
  }
292
- const txHash = tx?.hash;
293
285
  const alreadyExistingOperation =
294
- (txHash && explorerLedgerOperationByAddress[from]!.get(txHash)) ||
295
- (txHash && explorerLedgerOperationByAddress[to]!.get(txHash));
286
+ explorerLedgerOperationByAddress[from]!.get(tx.hash) ||
287
+ explorerLedgerOperationByAddress[to]!.get(tx.hash);
296
288
  const ledgerOperation: LedgerExplorerOperation = alreadyExistingOperation
297
289
  ? {
298
290
  ...alreadyExistingOperation,
@@ -307,16 +299,16 @@ const handleERC721Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider
307
299
  }
308
300
  : {
309
301
  hash: log.transactionHash,
310
- transaction_type: receipt?.type ?? 0,
302
+ transaction_type: receipt.type,
311
303
  nonce: "",
312
304
  nonce_value: -1,
313
- value: tx?.value.toString() ?? "0",
314
- gas: tx?.gasLimit.toString() ?? "0",
315
- gas_price: receipt?.gasPrice.toString() ?? "0",
316
- max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas!.toString() : null,
317
- max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas!.toString() : null,
318
- from: tx?.from ?? "0x",
319
- to: tx?.to ?? "0x0000000000000000000000000000000000000000",
305
+ value: tx.value.toString(),
306
+ gas: tx.gasLimit.toString(),
307
+ gas_price: receipt.effectiveGasPrice.toString(),
308
+ max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas!.toString() : null,
309
+ max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
310
+ from: tx.from,
311
+ to: tx.to!,
320
312
  transfer_events: [],
321
313
  erc721_transfer_events: [
322
314
  {
@@ -329,16 +321,16 @@ const handleERC721Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider
329
321
  erc1155_transfer_events: [],
330
322
  approval_events: [],
331
323
  actions: [],
332
- confirmations: tx?.confirmations ? await tx.confirmations() : 0,
324
+ confirmations: tx.confirmations,
333
325
  input: null,
334
- gas_used: receipt?.gasUsed.toString() ?? "0",
335
- cumulative_gas_used: receipt?.cumulativeGasUsed.toString() ?? "0",
336
- status: receipt?.status ?? 0,
337
- received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
326
+ gas_used: receipt.gasUsed.toString(),
327
+ cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
328
+ status: receipt.status!,
329
+ received_at: new Date(block.timestamp * 1000).toISOString(),
338
330
  block: {
339
331
  hash: log.blockHash,
340
332
  height: log.blockNumber,
341
- time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
333
+ time: new Date(block.timestamp * 1000).toISOString(),
342
334
  },
343
335
  };
344
336
 
@@ -346,37 +338,42 @@ const handleERC721Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider
346
338
  explorerLedgerOperationByAddress[to]!.set(ledgerOperation.hash, ledgerOperation);
347
339
  };
348
340
 
349
- const handleERC1155Log = async (log: ethers.Log, provider: ethers.JsonRpcProvider) => {
341
+ const handleERC1155Log = async (
342
+ log: providers.Log,
343
+ provider: ethers.providers.StaticJsonRpcProvider,
344
+ ) => {
350
345
  const [block, tx, receipt] = await Promise.all([
351
346
  provider.getBlock(log.blockHash),
352
347
  provider.getTransaction(log.transactionHash),
353
348
  provider.getTransactionReceipt(log.transactionHash),
354
349
  ]);
355
350
 
356
- const from = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[2])[0]);
357
- const to = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[3])[0]);
358
- const operator = safeEncodeEIP55(abiCoder.decode(["address"], log.topics[1])[0]);
351
+ const from = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[2])[0]);
352
+ const to = safeEncodeEIP55(ethers.utils.defaultAbiCoder.decode(["address"], log.topics[3])[0]);
353
+ const operator = safeEncodeEIP55(
354
+ ethers.utils.defaultAbiCoder.decode(["address"], log.topics[1])[0],
355
+ );
359
356
 
360
- const transfersMap: [string, string][] = abiCoder
357
+ const transfersMap: [string, string][] = ethers.utils.defaultAbiCoder
361
358
  .decode(["uint256", "uint256"], log.data)
362
359
  .map((value, index) => [index === 0 ? "id" : "value", value.toString()]);
363
360
 
364
361
  const etherscanERC1155Events: EtherscanERC1155Event[] = transfersMap.map(([id, value]) => ({
365
- blockNumber: block?.number.toString() || "0",
366
- timeStamp: block?.timestamp.toString() || "0",
367
- hash: tx?.hash || "",
368
- nonce: tx?.nonce.toString() || "0",
369
- blockHash: block?.hash || "",
362
+ blockNumber: block.number.toString(),
363
+ timeStamp: block.timestamp.toString(),
364
+ hash: tx.hash,
365
+ nonce: tx.nonce.toString(),
366
+ blockHash: block.hash,
370
367
  from,
371
368
  to,
372
- transactionIndex: block?.transactions.indexOf(log.transactionHash).toString() || "0",
373
- gas: tx?.gasLimit.toString() || "0",
374
- gasPrice: tx?.gasPrice?.toString() || "",
375
- cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
369
+ transactionIndex: block.transactions.indexOf(log.transactionHash).toString(),
370
+ gas: tx.gasLimit.toString(),
371
+ gasPrice: tx.gasPrice?.toString() || "",
372
+ cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
376
373
  gasUsed: receipt?.gasUsed?.toString() || "0",
377
- input: tx?.data || "0x",
378
- confirmations: tx?.confirmations.toString() || "0",
379
- contractAddress: tx?.to ?? "0x0000000000000000000000000000000000000000",
374
+ input: tx.data,
375
+ confirmations: tx.confirmations.toString(),
376
+ contractAddress: tx.to!,
380
377
  tokenID: id,
381
378
  tokenValue: value,
382
379
  tokenName: "tokenName",
@@ -401,10 +398,9 @@ const handleERC1155Log = async (log: ethers.Log, provider: ethers.JsonRpcProvide
401
398
  if (!explorerLedgerOperationByAddress[to]) {
402
399
  explorerLedgerOperationByAddress[to] = new Map<string, LedgerExplorerOperation>();
403
400
  }
404
- const txHash = tx?.hash;
405
401
  const alreadyExistingOperation =
406
- (txHash && explorerLedgerOperationByAddress[from]!.get(txHash)) ||
407
- (txHash && explorerLedgerOperationByAddress[to]!.get(txHash));
402
+ explorerLedgerOperationByAddress[from]!.get(tx.hash) ||
403
+ explorerLedgerOperationByAddress[to]!.get(tx.hash);
408
404
  const ledgerOperation: LedgerExplorerOperation = alreadyExistingOperation
409
405
  ? {
410
406
  ...alreadyExistingOperation,
@@ -419,17 +415,17 @@ const handleERC1155Log = async (log: ethers.Log, provider: ethers.JsonRpcProvide
419
415
  ],
420
416
  }
421
417
  : {
422
- hash: log.transactionHash || "",
423
- transaction_type: receipt?.type ?? 0,
418
+ hash: log.transactionHash,
419
+ transaction_type: receipt.type,
424
420
  nonce: "",
425
421
  nonce_value: -1,
426
- value: tx?.value.toString() || "0",
427
- gas: tx?.gasLimit.toString() || "0",
428
- gas_price: receipt?.gasPrice.toString() || "0",
429
- max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas!.toString() : null,
430
- max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas!.toString() : null,
431
- from: tx?.from ?? "0x",
432
- to: tx?.to ?? "0x0000000000000000000000000000000000000000",
422
+ value: tx.value.toString(),
423
+ gas: tx.gasLimit.toString(),
424
+ gas_price: receipt.effectiveGasPrice.toString(),
425
+ max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas!.toString() : null,
426
+ max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
427
+ from: tx.from,
428
+ to: tx.to!,
433
429
  transfer_events: [],
434
430
  erc721_transfer_events: [],
435
431
  erc1155_transfer_events: [
@@ -443,16 +439,16 @@ const handleERC1155Log = async (log: ethers.Log, provider: ethers.JsonRpcProvide
443
439
  ],
444
440
  approval_events: [],
445
441
  actions: [],
446
- confirmations: tx?.confirmations ? await tx.confirmations() : 0,
442
+ confirmations: tx.confirmations,
447
443
  input: null,
448
- gas_used: receipt?.gasUsed.toString() || "0",
449
- cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
450
- status: receipt?.status ?? 0,
451
- received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
444
+ gas_used: receipt.gasUsed.toString(),
445
+ cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
446
+ status: receipt.status!,
447
+ received_at: new Date(block.timestamp * 1000).toISOString(),
452
448
  block: {
453
449
  hash: log.blockHash,
454
450
  height: log.blockNumber,
455
- time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
451
+ time: new Date(block.timestamp * 1000).toISOString(),
456
452
  },
457
453
  };
458
454
 
@@ -460,41 +456,44 @@ const handleERC1155Log = async (log: ethers.Log, provider: ethers.JsonRpcProvide
460
456
  explorerLedgerOperationByAddress[to]!.set(ledgerOperation.hash, ledgerOperation);
461
457
  };
462
458
 
463
- const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider) => {
464
- const block = await provider.getBlock(blockNumber, true);
459
+ const handleBlock = async (
460
+ blockNumber: number,
461
+ provider: ethers.providers.StaticJsonRpcProvider,
462
+ ) => {
463
+ const block = await provider.getBlockWithTransactions(blockNumber);
465
464
 
466
465
  for (const transaction of block?.transactions || []) {
467
466
  const [tx, receipt, traces] = await Promise.all([
468
- provider.getTransaction(transaction),
469
- provider.getTransactionReceipt(transaction),
470
- provider.send("trace_transaction", [transaction]).catch(() => []) as Promise<
467
+ provider.getTransaction(transaction.hash),
468
+ provider.getTransactionReceipt(transaction.hash),
469
+ provider.send("trace_transaction", [transaction.hash]).catch(() => []) as Promise<
471
470
  TraceTransaction[]
472
471
  >,
473
472
  ]);
474
473
 
475
- const code = tx?.to ? await provider.getCode(tx?.to) : false;
476
- const from = safeEncodeEIP55(tx?.from || "");
477
- const to = safeEncodeEIP55(tx?.to || "");
474
+ const code = transaction.to ? await provider.getCode(transaction.to) : false;
475
+ const from = safeEncodeEIP55(transaction.from);
476
+ const to = safeEncodeEIP55(transaction.to || "");
478
477
  const etherscanOperation: EtherscanOperation = {
479
- blockNumber: block?.number.toString() || "0",
480
- timeStamp: block?.timestamp.toString() || "0",
481
- hash: tx?.hash || "",
482
- nonce: tx?.nonce.toString() || "0",
483
- blockHash: block?.hash || "",
484
- transactionIndex: block?.transactions.indexOf(transaction).toString() || "0",
478
+ blockNumber: block.number.toString(),
479
+ timeStamp: block.timestamp.toString(),
480
+ hash: transaction.hash,
481
+ nonce: transaction.nonce.toString(),
482
+ blockHash: block.hash,
483
+ transactionIndex: block.transactions.indexOf(transaction).toString(),
485
484
  from,
486
485
  to,
487
- value: tx?.value.toString() || "0",
488
- gas: tx?.gasLimit.toString() || "0",
489
- gasPrice: tx?.gasPrice?.toString() || "",
490
- isError: receipt?.status === 1 ? "0" : "1",
491
- txreceipt_status: receipt?.status!.toString() || "0",
492
- input: tx?.data,
493
- contractAddress: code === "0x" ? "" : tx?.to ?? "0x0000000000000000000000000000000000000000",
494
- cumulativeGasUsed: receipt?.cumulativeGasUsed.toString() || "0",
486
+ value: transaction.value.toBigInt().toString(),
487
+ gas: transaction.gasLimit.toString(),
488
+ gasPrice: transaction.gasPrice?.toString() || "",
489
+ isError: receipt.status === 1 ? "0" : "1",
490
+ txreceipt_status: receipt.status!.toString(),
491
+ input: transaction.data,
492
+ contractAddress: code === "0x" ? "" : transaction.to!,
493
+ cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
495
494
  gasUsed: receipt?.gasUsed?.toString() || "0",
496
- confirmations: tx?.confirmations.toString() || "0",
497
- methodId: tx?.data && tx.data.length > 10 ? tx.data.slice(0, 10) : "",
495
+ confirmations: transaction.confirmations.toString(),
496
+ methodId: transaction.data?.length > 10 ? transaction.data.slice(0, 10) : "",
498
497
  functionName: "",
499
498
  };
500
499
 
@@ -514,32 +513,32 @@ const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider
514
513
  explorerLedgerOperationByAddress[to] = new Map<string, LedgerExplorerOperation>();
515
514
  }
516
515
  const ledgerOperation: LedgerExplorerOperation = {
517
- hash: receipt?.hash || "",
518
- transaction_type: receipt?.type || 0,
516
+ hash: receipt.transactionHash,
517
+ transaction_type: receipt.type,
519
518
  nonce: "",
520
519
  nonce_value: -1,
521
- value: tx?.value.toString() || "0",
522
- gas: tx?.gasLimit.toString() || "0",
523
- gas_price: receipt?.gasPrice.toString() || "",
524
- max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas!.toString() : null,
525
- max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas!.toString() : null,
526
- from: tx?.from || "",
527
- to: tx?.to ?? "0x0000000000000000000000000000000000000000",
520
+ value: tx.value.toString(),
521
+ gas: tx.gasLimit.toString(),
522
+ gas_price: receipt.effectiveGasPrice.toString(),
523
+ max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas!.toString() : null,
524
+ max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
525
+ from: tx.from,
526
+ to: tx.to!,
528
527
  transfer_events: [],
529
528
  erc721_transfer_events: [],
530
529
  erc1155_transfer_events: [],
531
530
  approval_events: [],
532
531
  actions: [],
533
- confirmations: tx?.confirmations ? await tx.confirmations() : 0,
532
+ confirmations: tx.confirmations,
534
533
  input: null,
535
- gas_used: receipt?.gasUsed.toString() || "0",
536
- cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
537
- status: receipt?.status ?? 0,
538
- received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
534
+ gas_used: receipt.gasUsed.toString(),
535
+ cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
536
+ status: receipt.status!,
537
+ received_at: new Date(block.timestamp * 1000).toISOString(),
539
538
  block: {
540
- hash: receipt?.blockHash || "",
541
- height: receipt?.blockNumber || 0,
542
- time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
539
+ hash: receipt.blockHash,
540
+ height: receipt.blockNumber,
541
+ time: new Date(block.timestamp * 1000).toISOString(),
543
542
  },
544
543
  };
545
544
  explorerLedgerOperationByAddress[from]!.set(ledgerOperation.hash, ledgerOperation);
@@ -554,18 +553,20 @@ const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider
554
553
  const to = safeEncodeEIP55(action.to || "");
555
554
  const etherscanInternalTransaction: EtherscanInternalTransaction = {
556
555
  blockNumber: blockNumber.toString(),
557
- timeStamp: block?.timestamp.toString() || "0",
556
+ timeStamp: block.timestamp.toString(),
558
557
  hash: transactionHash,
559
558
  from,
560
559
  to,
561
- value: BigInt(action.value).toString() || "0",
560
+ value: ethers.BigNumber.from(action.value).toBigInt().toString(),
562
561
  contractAddress: code === "0x" ? "" : action.to!,
563
562
  input: action.input || "0x",
564
563
  type,
565
- gas: BigInt(action.gas).toString(),
566
- gasUsed: BigInt(result?.gasUsed || "0").toString(),
564
+ gas: ethers.BigNumber.from(action.gas).toBigInt().toString(),
565
+ gasUsed: ethers.BigNumber.from(result?.gasUsed || "0")
566
+ .toBigInt()
567
+ .toString(),
567
568
  traceId: transactionPosition.toString(),
568
- isError: receipt?.status === 1 ? "0" : "1",
569
+ isError: receipt.status === 1 ? "0" : "1",
569
570
  errCode: "",
570
571
  };
571
572
 
@@ -590,10 +591,9 @@ const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider
590
591
  if (!explorerLedgerOperationByAddress[to]) {
591
592
  explorerLedgerOperationByAddress[to] = new Map();
592
593
  }
593
- const txHash = tx?.hash;
594
594
  const alreadyExistingOperation =
595
- (txHash && explorerLedgerOperationByAddress[from]!.get(txHash)) ||
596
- (txHash && explorerLedgerOperationByAddress[to]!.get(txHash));
595
+ explorerLedgerOperationByAddress[from]!.get(tx.hash) ||
596
+ explorerLedgerOperationByAddress[to]!.get(tx.hash);
597
597
  const ledgerOperation: LedgerExplorerOperation = alreadyExistingOperation
598
598
  ? {
599
599
  ...alreadyExistingOperation,
@@ -603,25 +603,27 @@ const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider
603
603
  from,
604
604
  to,
605
605
  input: null,
606
- value: BigInt(action.value).toString(),
607
- gas: BigInt(action.gas).toString(),
608
- gas_used: BigInt(result?.gasUsed || "0").toString(),
606
+ value: ethers.BigNumber.from(action.value).toBigInt().toString(),
607
+ gas: ethers.BigNumber.from(action.gas).toBigInt().toString(),
608
+ gas_used: ethers.BigNumber.from(result?.gasUsed || "0")
609
+ .toBigInt()
610
+ .toString(),
609
611
  error: null,
610
612
  },
611
613
  ],
612
614
  }
613
615
  : {
614
- hash: receipt?.hash || "",
615
- transaction_type: receipt?.type ?? 0,
616
+ hash: receipt.transactionHash,
617
+ transaction_type: receipt.type,
616
618
  nonce: "",
617
619
  nonce_value: -1,
618
- value: tx?.value.toString() || "0",
619
- gas: tx?.gasLimit.toString() || "0",
620
- gas_price: receipt?.gasPrice.toString() || "0",
621
- max_fee_per_gas: tx?.type === 2 ? tx?.maxFeePerGas!.toString() : null,
622
- max_priority_fee_per_gas: tx?.type === 2 ? tx?.maxPriorityFeePerGas!.toString() : null,
623
- from: tx?.from || "0x",
624
- to: tx?.to ?? "0x0000000000000000000000000000000000000000",
620
+ value: tx.value.toString(),
621
+ gas: tx.gasLimit.toString(),
622
+ gas_price: receipt.effectiveGasPrice.toString(),
623
+ max_fee_per_gas: tx.type === 2 ? tx.maxFeePerGas!.toString() : null,
624
+ max_priority_fee_per_gas: tx.type === 2 ? tx.maxPriorityFeePerGas!.toString() : null,
625
+ from: tx.from,
626
+ to: tx.to!,
625
627
  transfer_events: [],
626
628
  erc721_transfer_events: [],
627
629
  erc1155_transfer_events: [],
@@ -631,22 +633,24 @@ const handleBlock = async (blockNumber: number, provider: ethers.JsonRpcProvider
631
633
  from,
632
634
  to,
633
635
  input: null,
634
- value: BigInt(action.value).toString(),
635
- gas: BigInt(action.gas).toString(),
636
- gas_used: BigInt(result?.gasUsed || "0").toString(),
636
+ value: ethers.BigNumber.from(action.value).toBigInt().toString(),
637
+ gas: ethers.BigNumber.from(action.gas).toBigInt().toString(),
638
+ gas_used: ethers.BigNumber.from(result?.gasUsed || "0")
639
+ .toBigInt()
640
+ .toString(),
637
641
  error: null,
638
642
  },
639
643
  ],
640
- confirmations: tx?.confirmations ? await tx.confirmations() : 0,
644
+ confirmations: tx.confirmations,
641
645
  input: null,
642
- gas_used: receipt?.gasUsed.toString() || "0",
643
- cumulative_gas_used: receipt?.cumulativeGasUsed.toString() || "0",
644
- status: receipt?.status ?? 0,
645
- received_at: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
646
+ gas_used: receipt.gasUsed.toString(),
647
+ cumulative_gas_used: receipt.cumulativeGasUsed.toString(),
648
+ status: receipt.status!,
649
+ received_at: new Date(block.timestamp * 1000).toISOString(),
646
650
  block: {
647
- hash: receipt?.blockHash || "",
648
- height: receipt?.blockNumber || 0,
649
- time: new Date((block?.timestamp ?? 0) * 1000).toISOString(),
651
+ hash: receipt.blockHash,
652
+ height: receipt.blockNumber,
653
+ time: new Date(block.timestamp * 1000).toISOString(),
650
654
  },
651
655
  };
652
656
  explorerLedgerOperationByAddress[from]!.set(ledgerOperation.hash, ledgerOperation);
@@ -664,7 +668,7 @@ export const indexBlocks = async () => {
664
668
  throw new Error("fromBlock is not set");
665
669
  }
666
670
 
667
- const provider = new ethers.JsonRpcProvider(process.env.RPC);
671
+ const provider = new providers.StaticJsonRpcProvider(process.env.RPC);
668
672
  let latestBlockNumber = await provider.getBlockNumber();
669
673
  const toBlock = Math.min(fromBlock + MAX_BLOCK_RANGE, latestBlockNumber);
670
674
  const rangeSize = toBlock - fromBlock + 1;
@@ -683,6 +687,7 @@ export const indexBlocks = async () => {
683
687
  [TRANSFER_EVENTS_TOPICS.ERC20, TRANSFER_EVENTS_TOPICS.ERC721, TRANSFER_EVENTS_TOPICS.ERC1155],
684
688
  ],
685
689
  });
690
+
686
691
  await BlueBirdPromise.map(
687
692
  blocks,
688
693
  async blockNumber =>