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