@0xtorch/evm 0.0.8 → 0.0.9
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/_cjs/decoder/tests.js +9 -0
- package/_cjs/decoder/tests.js.map +1 -1
- package/_cjs/explorers/definitions/blockscout.js +97 -0
- package/_cjs/explorers/definitions/blockscout.js.map +1 -1
- package/_cjs/explorers/definitions/etherscan.js +152 -0
- package/_cjs/explorers/definitions/etherscan.js.map +1 -1
- package/_cjs/explorers/definitions/roninExplorer.js +70 -0
- package/_cjs/explorers/definitions/roninExplorer.js.map +1 -1
- package/_cjs/explorers/definitions/routescan.js +12 -0
- package/_cjs/explorers/definitions/routescan.js.map +1 -1
- package/_esm/decoder/tests.js +9 -0
- package/_esm/decoder/tests.js.map +1 -1
- package/_esm/explorers/definitions/blockscout.js +99 -1
- package/_esm/explorers/definitions/blockscout.js.map +1 -1
- package/_esm/explorers/definitions/etherscan.js +155 -0
- package/_esm/explorers/definitions/etherscan.js.map +1 -1
- package/_esm/explorers/definitions/roninExplorer.js +70 -0
- package/_esm/explorers/definitions/roninExplorer.js.map +1 -1
- package/_esm/explorers/definitions/routescan.js +15 -0
- package/_esm/explorers/definitions/routescan.js.map +1 -1
- package/_types/decoder/tests.d.ts.map +1 -1
- package/_types/explorers/definitions/blockscout.d.ts +28 -1
- package/_types/explorers/definitions/blockscout.d.ts.map +1 -1
- package/_types/explorers/definitions/etherscan.d.ts +28 -1
- package/_types/explorers/definitions/etherscan.d.ts.map +1 -1
- package/_types/explorers/definitions/roninExplorer.d.ts +26 -0
- package/_types/explorers/definitions/roninExplorer.d.ts.map +1 -1
- package/_types/explorers/definitions/routescan.d.ts +3 -0
- package/_types/explorers/definitions/routescan.d.ts.map +1 -1
- package/_types/explorers/types.d.ts +30 -0
- package/_types/explorers/types.d.ts.map +1 -1
- package/decoder/tests.ts +9 -0
- package/explorers/definitions/blockscout.ts +141 -1
- package/explorers/definitions/etherscan.ts +211 -0
- package/explorers/definitions/roninExplorer.ts +99 -0
- package/explorers/definitions/routescan.ts +15 -0
- package/explorers/types.ts +37 -0
- package/package.json +1 -1
|
@@ -5,8 +5,11 @@ export type Explorer = {
|
|
|
5
5
|
readonly url: string;
|
|
6
6
|
readonly apiUrl: string;
|
|
7
7
|
readonly getAddressTransactionHashes: FunctionGetAddressTransactionHashes;
|
|
8
|
+
readonly getAddressTransactionHashesWithTimestamp: FunctionGetAddressTransactionHashesWithTimestamp;
|
|
8
9
|
readonly getAddressInternalTransactions: FunctionGetAddressInternalTransactions;
|
|
10
|
+
readonly getAddressInternalTransactionsWithTimestamp: FunctionGetAddressInternalTransactionsWithTimestamp;
|
|
9
11
|
readonly getAddressTokenTransferHashes: FunctionGetAddressTokenTransferHashes;
|
|
12
|
+
readonly getAddressTokenTransferHashesWithTimestamp: FunctionGetAddressTokenTransferHashesWithTimestamp;
|
|
10
13
|
readonly getBlockNumberOfTimestamp: (timestamp: number, logger?: Logger) => Promise<bigint>;
|
|
11
14
|
readonly getContract: FunctionGetContract;
|
|
12
15
|
readonly getInternalTransactionOfTransaction: FunctionGetInternalTransactionOfTransaction;
|
|
@@ -17,6 +20,15 @@ type FunctionGetAddressTransactionHashes = (parameters: {
|
|
|
17
20
|
readonly endBlock?: bigint;
|
|
18
21
|
readonly logger?: Logger;
|
|
19
22
|
}) => Promise<readonly Hex[]>;
|
|
23
|
+
type FunctionGetAddressTransactionHashesWithTimestamp = (parameters: {
|
|
24
|
+
readonly address: Hex;
|
|
25
|
+
readonly startBlock?: bigint;
|
|
26
|
+
readonly endBlock?: bigint;
|
|
27
|
+
readonly logger?: Logger;
|
|
28
|
+
}) => Promise<readonly {
|
|
29
|
+
readonly hash: Hex;
|
|
30
|
+
readonly timestamp: number;
|
|
31
|
+
}[]>;
|
|
20
32
|
type FunctionGetAddressInternalTransactions = (parameters: {
|
|
21
33
|
readonly address: Hex;
|
|
22
34
|
readonly startBlock?: bigint;
|
|
@@ -24,12 +36,30 @@ type FunctionGetAddressInternalTransactions = (parameters: {
|
|
|
24
36
|
readonly nativeCurrency: CryptoCurrency;
|
|
25
37
|
readonly logger?: Logger;
|
|
26
38
|
}) => Promise<readonly InternalTransaction<undefined>[]>;
|
|
39
|
+
type FunctionGetAddressInternalTransactionsWithTimestamp = (parameters: {
|
|
40
|
+
readonly address: Hex;
|
|
41
|
+
readonly startBlock?: bigint;
|
|
42
|
+
readonly endBlock?: bigint;
|
|
43
|
+
readonly nativeCurrency: CryptoCurrency;
|
|
44
|
+
readonly logger?: Logger;
|
|
45
|
+
}) => Promise<readonly (InternalTransaction<undefined> & {
|
|
46
|
+
readonly timestamp: number;
|
|
47
|
+
})[]>;
|
|
27
48
|
type FunctionGetAddressTokenTransferHashes = (parameters: {
|
|
28
49
|
readonly address: Hex;
|
|
29
50
|
readonly startBlock?: bigint;
|
|
30
51
|
readonly endBlock?: bigint;
|
|
31
52
|
readonly logger?: Logger;
|
|
32
53
|
}) => Promise<readonly Hex[]>;
|
|
54
|
+
type FunctionGetAddressTokenTransferHashesWithTimestamp = (parameters: {
|
|
55
|
+
readonly address: Hex;
|
|
56
|
+
readonly startBlock?: bigint;
|
|
57
|
+
readonly endBlock?: bigint;
|
|
58
|
+
readonly logger?: Logger;
|
|
59
|
+
}) => Promise<readonly {
|
|
60
|
+
readonly hash: Hex;
|
|
61
|
+
readonly timestamp: number;
|
|
62
|
+
}[]>;
|
|
33
63
|
type FunctionGetContract = (address: Hex, logger?: Logger) => Promise<{
|
|
34
64
|
readonly name: string;
|
|
35
65
|
readonly abi: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../explorers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,KAAK,EAAE,GAAG,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAExD,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,2BAA2B,EAAE,mCAAmC,CAAA;IACzE,QAAQ,CAAC,8BAA8B,EAAE,sCAAsC,CAAA;IAC/E,QAAQ,CAAC,6BAA6B,EAAE,qCAAqC,CAAA;IAC7E,QAAQ,CAAC,yBAAyB,EAAE,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,KACZ,OAAO,CAAC,MAAM,CAAC,CAAA;IACpB,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAA;IACzC,QAAQ,CAAC,mCAAmC,EAAE,2CAA2C,CAAA;CAC1F,CAAA;AAED,KAAK,mCAAmC,GAAG,CAAC,UAAU,EAAE;IACtD,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAA;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,KAAK,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC,CAAA;AAE7B,KAAK,sCAAsC,GAAG,CAAC,UAAU,EAAE;IACzD,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAA;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,KAAK,OAAO,CAAC,SAAS,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;AAExD,KAAK,qCAAqC,GAAG,CAAC,UAAU,EAAE;IACxD,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAA;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,KAAK,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC,CAAA;AAE7B,KAAK,mBAAmB,GAAG,CACzB,OAAO,EAAE,GAAG,EACZ,MAAM,CAAC,EAAE,MAAM,KACZ,OAAO,CACR;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,GACD,SAAS,CACZ,CAAA;AAED,KAAK,2CAA2C,GAAG,CAAC,UAAU,EAAE;IAC9D,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAA;IAClB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,KAAK,OAAO,CAAC,SAAS,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../explorers/types.ts"],"names":[],"mappings":"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"}
|
package/decoder/tests.ts
CHANGED
|
@@ -73,6 +73,15 @@ const testExplorer: Explorer = {
|
|
|
73
73
|
getInternalTransactionOfTransaction: () => {
|
|
74
74
|
throw new Error('Not implemented')
|
|
75
75
|
},
|
|
76
|
+
getAddressTransactionHashesWithTimestamp: () => {
|
|
77
|
+
throw new Error('not implemented')
|
|
78
|
+
},
|
|
79
|
+
getAddressInternalTransactionsWithTimestamp: () => {
|
|
80
|
+
throw new Error('not implemented')
|
|
81
|
+
},
|
|
82
|
+
getAddressTokenTransferHashesWithTimestamp: () => {
|
|
83
|
+
throw new Error('not implemented')
|
|
84
|
+
},
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
export const testChain = createEthereumChainCustom({
|
|
@@ -133,7 +133,7 @@ export const createBlockscout = <
|
|
|
133
133
|
const loop = true
|
|
134
134
|
const hashSet = new Set<LowerHex>()
|
|
135
135
|
|
|
136
|
-
//
|
|
136
|
+
// token transfer
|
|
137
137
|
let mut_startBlock = startBlock
|
|
138
138
|
while (loop) {
|
|
139
139
|
const transfers = await getTokenTransfersByAddress({
|
|
@@ -202,4 +202,144 @@ export const createBlockscout = <
|
|
|
202
202
|
price: undefined,
|
|
203
203
|
}))
|
|
204
204
|
},
|
|
205
|
+
getAddressTransactionHashesWithTimestamp: async ({
|
|
206
|
+
address,
|
|
207
|
+
startBlock,
|
|
208
|
+
endBlock,
|
|
209
|
+
logger,
|
|
210
|
+
}) => {
|
|
211
|
+
const loop = true
|
|
212
|
+
const mut_hashesWithTimestamp: {
|
|
213
|
+
readonly hash: LowerHex
|
|
214
|
+
readonly timestamp: number
|
|
215
|
+
}[] = []
|
|
216
|
+
let mut_startBlock = startBlock
|
|
217
|
+
while (loop) {
|
|
218
|
+
const transactions = await getNormalTransactionsByAddress({
|
|
219
|
+
apiEndpoint: apiUrl,
|
|
220
|
+
address,
|
|
221
|
+
startBlock: mut_startBlock,
|
|
222
|
+
endBlock,
|
|
223
|
+
logger,
|
|
224
|
+
})
|
|
225
|
+
for (const { hash, timeStamp } of transactions) {
|
|
226
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
227
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (transactions.length < 10_000) {
|
|
231
|
+
break
|
|
232
|
+
}
|
|
233
|
+
const maxTxBlockNumber = transactions.reduce(
|
|
234
|
+
(max, { blockNumber }) =>
|
|
235
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
236
|
+
0n,
|
|
237
|
+
)
|
|
238
|
+
if (maxTxBlockNumber === 0n || maxTxBlockNumber === mut_startBlock) {
|
|
239
|
+
break
|
|
240
|
+
}
|
|
241
|
+
mut_startBlock = maxTxBlockNumber
|
|
242
|
+
}
|
|
243
|
+
return mut_hashesWithTimestamp
|
|
244
|
+
},
|
|
245
|
+
getAddressInternalTransactionsWithTimestamp: async ({
|
|
246
|
+
address,
|
|
247
|
+
startBlock,
|
|
248
|
+
endBlock,
|
|
249
|
+
nativeCurrency,
|
|
250
|
+
logger,
|
|
251
|
+
}) => {
|
|
252
|
+
const loop = true
|
|
253
|
+
const mut_internalTransactionsWithTimestamp: (InternalTransaction<undefined> & {
|
|
254
|
+
readonly timestamp: number
|
|
255
|
+
})[] = []
|
|
256
|
+
let mut_startBlock = startBlock
|
|
257
|
+
while (loop) {
|
|
258
|
+
const transactions = await getInternalTransactionsByAddress({
|
|
259
|
+
apiEndpoint: apiUrl,
|
|
260
|
+
address,
|
|
261
|
+
startBlock: mut_startBlock,
|
|
262
|
+
endBlock,
|
|
263
|
+
logger,
|
|
264
|
+
})
|
|
265
|
+
for (const transaction of transactions) {
|
|
266
|
+
if (
|
|
267
|
+
mut_internalTransactionsWithTimestamp.some(
|
|
268
|
+
({ transactionHash, from, to, value }) =>
|
|
269
|
+
transaction.transactionHash === transactionHash &&
|
|
270
|
+
transaction.from === from &&
|
|
271
|
+
transaction.to === to &&
|
|
272
|
+
transaction.value === value,
|
|
273
|
+
)
|
|
274
|
+
) {
|
|
275
|
+
continue
|
|
276
|
+
}
|
|
277
|
+
mut_internalTransactionsWithTimestamp.push({
|
|
278
|
+
...transaction,
|
|
279
|
+
type: 'InternalTransaction',
|
|
280
|
+
to: transaction.to,
|
|
281
|
+
contractAddress: transaction.contractAddress,
|
|
282
|
+
txType: transaction.type,
|
|
283
|
+
currency: nativeCurrency,
|
|
284
|
+
price: undefined,
|
|
285
|
+
timestamp: transaction.timeStamp,
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
if (transactions.length < 10_000) {
|
|
289
|
+
break
|
|
290
|
+
}
|
|
291
|
+
const maxTxBlockNumber = transactions.reduce(
|
|
292
|
+
(max, { blockNumber }) =>
|
|
293
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
294
|
+
0n,
|
|
295
|
+
)
|
|
296
|
+
if (maxTxBlockNumber === 0n || maxTxBlockNumber === mut_startBlock) {
|
|
297
|
+
break
|
|
298
|
+
}
|
|
299
|
+
mut_startBlock = maxTxBlockNumber
|
|
300
|
+
}
|
|
301
|
+
return mut_internalTransactionsWithTimestamp
|
|
302
|
+
},
|
|
303
|
+
getAddressTokenTransferHashesWithTimestamp: async ({
|
|
304
|
+
address,
|
|
305
|
+
startBlock,
|
|
306
|
+
endBlock,
|
|
307
|
+
logger,
|
|
308
|
+
}) => {
|
|
309
|
+
const loop = true
|
|
310
|
+
const mut_hashesWithTimestamp: {
|
|
311
|
+
readonly hash: LowerHex
|
|
312
|
+
readonly timestamp: number
|
|
313
|
+
}[] = []
|
|
314
|
+
|
|
315
|
+
// token transfer
|
|
316
|
+
let mut_startBlock = startBlock
|
|
317
|
+
while (loop) {
|
|
318
|
+
const transfers = await getTokenTransfersByAddress({
|
|
319
|
+
apiEndpoint: apiUrl,
|
|
320
|
+
address,
|
|
321
|
+
startBlock: mut_startBlock,
|
|
322
|
+
endBlock,
|
|
323
|
+
logger,
|
|
324
|
+
})
|
|
325
|
+
for (const { hash, timeStamp } of transfers) {
|
|
326
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
327
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (transfers.length < 10_000) {
|
|
331
|
+
break
|
|
332
|
+
}
|
|
333
|
+
const maxTxBlockNumber = transfers.reduce(
|
|
334
|
+
(max, { blockNumber }) =>
|
|
335
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
336
|
+
0n,
|
|
337
|
+
)
|
|
338
|
+
if (maxTxBlockNumber === 0n || maxTxBlockNumber === mut_startBlock) {
|
|
339
|
+
break
|
|
340
|
+
}
|
|
341
|
+
mut_startBlock = maxTxBlockNumber
|
|
342
|
+
}
|
|
343
|
+
return mut_hashesWithTimestamp
|
|
344
|
+
},
|
|
205
345
|
})
|
|
@@ -276,4 +276,215 @@ export const createEtherscan = <
|
|
|
276
276
|
price: undefined,
|
|
277
277
|
}))
|
|
278
278
|
},
|
|
279
|
+
getAddressTransactionHashesWithTimestamp: async ({
|
|
280
|
+
address,
|
|
281
|
+
startBlock,
|
|
282
|
+
endBlock,
|
|
283
|
+
logger,
|
|
284
|
+
}) => {
|
|
285
|
+
const loop = true
|
|
286
|
+
const mut_hashesWithTimestamp: {
|
|
287
|
+
readonly hash: LowerHex
|
|
288
|
+
readonly timestamp: number
|
|
289
|
+
}[] = []
|
|
290
|
+
let mut_startBlock = startBlock
|
|
291
|
+
while (loop) {
|
|
292
|
+
const transactions = await getNormalTransactionsByAddress({
|
|
293
|
+
apiEndpoint: apiUrl,
|
|
294
|
+
apiKey,
|
|
295
|
+
address,
|
|
296
|
+
startBlock: mut_startBlock,
|
|
297
|
+
endBlock,
|
|
298
|
+
logger,
|
|
299
|
+
})
|
|
300
|
+
for (const { hash, timeStamp } of transactions) {
|
|
301
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
302
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (transactions.length < 10_000) {
|
|
306
|
+
break
|
|
307
|
+
}
|
|
308
|
+
const maxTxBlockNumber = transactions.reduce(
|
|
309
|
+
(max, { blockNumber }) =>
|
|
310
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
311
|
+
0n,
|
|
312
|
+
)
|
|
313
|
+
if (maxTxBlockNumber === 0n || maxTxBlockNumber === mut_startBlock) {
|
|
314
|
+
break
|
|
315
|
+
}
|
|
316
|
+
mut_startBlock = maxTxBlockNumber
|
|
317
|
+
}
|
|
318
|
+
return mut_hashesWithTimestamp
|
|
319
|
+
},
|
|
320
|
+
getAddressInternalTransactionsWithTimestamp: async ({
|
|
321
|
+
address,
|
|
322
|
+
startBlock,
|
|
323
|
+
endBlock,
|
|
324
|
+
nativeCurrency,
|
|
325
|
+
logger,
|
|
326
|
+
}) => {
|
|
327
|
+
const loop = true
|
|
328
|
+
const mut_internalTransactionsWithTimestamp: (InternalTransaction<undefined> & {
|
|
329
|
+
readonly timestamp: number
|
|
330
|
+
})[] = []
|
|
331
|
+
let mut_startBlock = startBlock
|
|
332
|
+
while (loop) {
|
|
333
|
+
const transactions = await getInternalTransactionsByAddress({
|
|
334
|
+
apiEndpoint: apiUrl,
|
|
335
|
+
apiKey,
|
|
336
|
+
address,
|
|
337
|
+
startBlock: mut_startBlock,
|
|
338
|
+
endBlock,
|
|
339
|
+
logger,
|
|
340
|
+
})
|
|
341
|
+
for (const transaction of transactions) {
|
|
342
|
+
if (
|
|
343
|
+
mut_internalTransactionsWithTimestamp.some(
|
|
344
|
+
({ transactionHash, from, to, value }) =>
|
|
345
|
+
transaction.hash === transactionHash &&
|
|
346
|
+
transaction.from === from &&
|
|
347
|
+
transaction.to === to &&
|
|
348
|
+
transaction.value === value,
|
|
349
|
+
)
|
|
350
|
+
) {
|
|
351
|
+
continue
|
|
352
|
+
}
|
|
353
|
+
mut_internalTransactionsWithTimestamp.push({
|
|
354
|
+
...transaction,
|
|
355
|
+
type: 'InternalTransaction',
|
|
356
|
+
transactionHash: transaction.hash,
|
|
357
|
+
to: transaction.to,
|
|
358
|
+
contractAddress: transaction.contractAddress,
|
|
359
|
+
txType: transaction.type,
|
|
360
|
+
currency: nativeCurrency,
|
|
361
|
+
price: undefined,
|
|
362
|
+
timestamp: transaction.timeStamp,
|
|
363
|
+
})
|
|
364
|
+
}
|
|
365
|
+
if (transactions.length < 10_000) {
|
|
366
|
+
break
|
|
367
|
+
}
|
|
368
|
+
const maxTxBlockNumber = transactions.reduce(
|
|
369
|
+
(max, { blockNumber }) =>
|
|
370
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
371
|
+
0n,
|
|
372
|
+
)
|
|
373
|
+
if (maxTxBlockNumber === 0n || maxTxBlockNumber === mut_startBlock) {
|
|
374
|
+
break
|
|
375
|
+
}
|
|
376
|
+
mut_startBlock = maxTxBlockNumber
|
|
377
|
+
}
|
|
378
|
+
return mut_internalTransactionsWithTimestamp
|
|
379
|
+
},
|
|
380
|
+
getAddressTokenTransferHashesWithTimestamp: async ({
|
|
381
|
+
address,
|
|
382
|
+
startBlock,
|
|
383
|
+
endBlock,
|
|
384
|
+
logger,
|
|
385
|
+
}) => {
|
|
386
|
+
const loop = true
|
|
387
|
+
const mut_hashesWithTimestamp: {
|
|
388
|
+
readonly hash: LowerHex
|
|
389
|
+
readonly timestamp: number
|
|
390
|
+
}[] = []
|
|
391
|
+
|
|
392
|
+
// erc20 transfer
|
|
393
|
+
let mut_erc20StartBlock = startBlock
|
|
394
|
+
while (loop) {
|
|
395
|
+
const transfers = await getErc20TokenTransfersByAddress({
|
|
396
|
+
apiEndpoint: apiUrl,
|
|
397
|
+
apiKey,
|
|
398
|
+
address,
|
|
399
|
+
startBlock: mut_erc20StartBlock,
|
|
400
|
+
endBlock,
|
|
401
|
+
logger,
|
|
402
|
+
})
|
|
403
|
+
for (const { hash, timeStamp } of transfers) {
|
|
404
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
405
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (transfers.length < 10_000) {
|
|
409
|
+
break
|
|
410
|
+
}
|
|
411
|
+
const maxTxBlockNumber = transfers.reduce(
|
|
412
|
+
(max, { blockNumber }) =>
|
|
413
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
414
|
+
0n,
|
|
415
|
+
)
|
|
416
|
+
if (
|
|
417
|
+
maxTxBlockNumber === 0n ||
|
|
418
|
+
maxTxBlockNumber === mut_erc20StartBlock
|
|
419
|
+
) {
|
|
420
|
+
break
|
|
421
|
+
}
|
|
422
|
+
mut_erc20StartBlock = maxTxBlockNumber
|
|
423
|
+
}
|
|
424
|
+
// erc721 transfer
|
|
425
|
+
let mut_erc721StartBlock = startBlock
|
|
426
|
+
while (loop) {
|
|
427
|
+
const transfers = await getErc721TokenTransfersByAddress({
|
|
428
|
+
apiEndpoint: apiUrl,
|
|
429
|
+
apiKey,
|
|
430
|
+
address,
|
|
431
|
+
startBlock: mut_erc721StartBlock,
|
|
432
|
+
endBlock,
|
|
433
|
+
logger,
|
|
434
|
+
})
|
|
435
|
+
for (const { hash, timeStamp } of transfers) {
|
|
436
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
437
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (transfers.length < 10_000) {
|
|
441
|
+
break
|
|
442
|
+
}
|
|
443
|
+
const maxTxBlockNumber = transfers.reduce(
|
|
444
|
+
(max, { blockNumber }) =>
|
|
445
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
446
|
+
0n,
|
|
447
|
+
)
|
|
448
|
+
if (
|
|
449
|
+
maxTxBlockNumber === 0n ||
|
|
450
|
+
maxTxBlockNumber === mut_erc721StartBlock
|
|
451
|
+
) {
|
|
452
|
+
break
|
|
453
|
+
}
|
|
454
|
+
mut_erc721StartBlock = maxTxBlockNumber
|
|
455
|
+
}
|
|
456
|
+
// erc1155 transfer
|
|
457
|
+
let mut_erc1155StartBlock = startBlock
|
|
458
|
+
while (loop) {
|
|
459
|
+
const transfers = await getErc1155TokenTransfersByAddress({
|
|
460
|
+
apiEndpoint: apiUrl,
|
|
461
|
+
apiKey,
|
|
462
|
+
address,
|
|
463
|
+
startBlock: mut_erc1155StartBlock,
|
|
464
|
+
endBlock,
|
|
465
|
+
logger,
|
|
466
|
+
})
|
|
467
|
+
for (const { hash, timeStamp } of transfers) {
|
|
468
|
+
if (mut_hashesWithTimestamp.every(({ hash: h }) => h !== hash)) {
|
|
469
|
+
mut_hashesWithTimestamp.push({ hash, timestamp: timeStamp })
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (transfers.length < 10_000) {
|
|
473
|
+
break
|
|
474
|
+
}
|
|
475
|
+
const maxTxBlockNumber = transfers.reduce(
|
|
476
|
+
(max, { blockNumber }) =>
|
|
477
|
+
max < BigInt(blockNumber) ? BigInt(blockNumber) : max,
|
|
478
|
+
0n,
|
|
479
|
+
)
|
|
480
|
+
if (
|
|
481
|
+
maxTxBlockNumber === 0n ||
|
|
482
|
+
maxTxBlockNumber === mut_erc1155StartBlock
|
|
483
|
+
) {
|
|
484
|
+
break
|
|
485
|
+
}
|
|
486
|
+
mut_erc1155StartBlock = maxTxBlockNumber
|
|
487
|
+
}
|
|
488
|
+
return mut_hashesWithTimestamp
|
|
489
|
+
},
|
|
279
490
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Hex } from 'viem'
|
|
2
|
+
import type { LowerHex } from '../../types'
|
|
2
3
|
import {
|
|
3
4
|
getInternalTransactionByHash,
|
|
4
5
|
getNormalTransactionsByAddress,
|
|
@@ -147,4 +148,102 @@ export const createRoninExplorer = <
|
|
|
147
148
|
price: undefined,
|
|
148
149
|
}))
|
|
149
150
|
},
|
|
151
|
+
getAddressTransactionHashesWithTimestamp: async ({
|
|
152
|
+
address,
|
|
153
|
+
startBlock,
|
|
154
|
+
endBlock,
|
|
155
|
+
logger,
|
|
156
|
+
}) => {
|
|
157
|
+
const mut_hashesWithTimestamp: {
|
|
158
|
+
readonly hash: LowerHex
|
|
159
|
+
readonly timestamp: number
|
|
160
|
+
}[] = []
|
|
161
|
+
let mut_from = 0
|
|
162
|
+
while (mut_from >= 0) {
|
|
163
|
+
const { total, transactions } = await getNormalTransactionsByAddress({
|
|
164
|
+
apiEndpoint: explorerApiUrl,
|
|
165
|
+
address,
|
|
166
|
+
size: 100,
|
|
167
|
+
from: mut_from,
|
|
168
|
+
logger,
|
|
169
|
+
})
|
|
170
|
+
for (const transaction of transactions) {
|
|
171
|
+
if (
|
|
172
|
+
startBlock !== undefined &&
|
|
173
|
+
BigInt(transaction.block_number) < startBlock
|
|
174
|
+
) {
|
|
175
|
+
return mut_hashesWithTimestamp
|
|
176
|
+
}
|
|
177
|
+
if (
|
|
178
|
+
(endBlock === undefined ||
|
|
179
|
+
BigInt(transaction.block_number) <= endBlock) &&
|
|
180
|
+
mut_hashesWithTimestamp.every(
|
|
181
|
+
({ hash }) => hash !== transaction.hash,
|
|
182
|
+
)
|
|
183
|
+
) {
|
|
184
|
+
mut_hashesWithTimestamp.push({
|
|
185
|
+
hash: transaction.hash,
|
|
186
|
+
timestamp: transaction.timestamp,
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
mut_from += transactions.length
|
|
191
|
+
if (mut_from + transactions.length >= total) {
|
|
192
|
+
break
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return mut_hashesWithTimestamp
|
|
196
|
+
},
|
|
197
|
+
getAddressInternalTransactionsWithTimestamp: ({ logger }) => {
|
|
198
|
+
if (logger !== undefined) {
|
|
199
|
+
logger.info('getAddressInternalTransactions is not implemented')
|
|
200
|
+
}
|
|
201
|
+
return Promise.resolve([])
|
|
202
|
+
},
|
|
203
|
+
getAddressTokenTransferHashesWithTimestamp: async ({
|
|
204
|
+
address,
|
|
205
|
+
startBlock,
|
|
206
|
+
endBlock,
|
|
207
|
+
logger,
|
|
208
|
+
}) => {
|
|
209
|
+
const mut_hashesWithTimestamp: {
|
|
210
|
+
readonly hash: LowerHex
|
|
211
|
+
readonly timestamp: number
|
|
212
|
+
}[] = []
|
|
213
|
+
let mut_from = 0
|
|
214
|
+
while (mut_from >= 0) {
|
|
215
|
+
const { total, transfers } = await getTokenTransfersByAddress({
|
|
216
|
+
apiEndpoint: explorerApiUrl,
|
|
217
|
+
address,
|
|
218
|
+
size: 100,
|
|
219
|
+
from: mut_from,
|
|
220
|
+
logger,
|
|
221
|
+
})
|
|
222
|
+
for (const transfer of transfers) {
|
|
223
|
+
if (
|
|
224
|
+
startBlock !== undefined &&
|
|
225
|
+
BigInt(transfer.block_number) < startBlock
|
|
226
|
+
) {
|
|
227
|
+
return mut_hashesWithTimestamp
|
|
228
|
+
}
|
|
229
|
+
if (
|
|
230
|
+
(endBlock === undefined ||
|
|
231
|
+
BigInt(transfer.block_number) <= endBlock) &&
|
|
232
|
+
mut_hashesWithTimestamp.every(
|
|
233
|
+
({ hash }) => hash !== transfer.tx_hash,
|
|
234
|
+
)
|
|
235
|
+
) {
|
|
236
|
+
mut_hashesWithTimestamp.push({
|
|
237
|
+
hash: transfer.tx_hash,
|
|
238
|
+
timestamp: transfer.timestamp,
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
mut_from += transfers.length
|
|
243
|
+
if (mut_from + transfers.length >= total) {
|
|
244
|
+
break
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return mut_hashesWithTimestamp
|
|
248
|
+
},
|
|
150
249
|
})
|
|
@@ -54,4 +54,19 @@ export const createRoutescan = <
|
|
|
54
54
|
await new Promise((resolve) => setTimeout(resolve))
|
|
55
55
|
throw new Error('not implemented')
|
|
56
56
|
},
|
|
57
|
+
getAddressTransactionHashesWithTimestamp: async () => {
|
|
58
|
+
// TODO implement
|
|
59
|
+
await new Promise((resolve) => setTimeout(resolve))
|
|
60
|
+
throw new Error('not implemented')
|
|
61
|
+
},
|
|
62
|
+
getAddressInternalTransactionsWithTimestamp: async () => {
|
|
63
|
+
// TODO implement
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve))
|
|
65
|
+
throw new Error('not implemented')
|
|
66
|
+
},
|
|
67
|
+
getAddressTokenTransferHashesWithTimestamp: async () => {
|
|
68
|
+
// TODO implement
|
|
69
|
+
await new Promise((resolve) => setTimeout(resolve))
|
|
70
|
+
throw new Error('not implemented')
|
|
71
|
+
},
|
|
57
72
|
})
|
package/explorers/types.ts
CHANGED
|
@@ -6,8 +6,11 @@ export type Explorer = {
|
|
|
6
6
|
readonly url: string
|
|
7
7
|
readonly apiUrl: string
|
|
8
8
|
readonly getAddressTransactionHashes: FunctionGetAddressTransactionHashes
|
|
9
|
+
readonly getAddressTransactionHashesWithTimestamp: FunctionGetAddressTransactionHashesWithTimestamp
|
|
9
10
|
readonly getAddressInternalTransactions: FunctionGetAddressInternalTransactions
|
|
11
|
+
readonly getAddressInternalTransactionsWithTimestamp: FunctionGetAddressInternalTransactionsWithTimestamp
|
|
10
12
|
readonly getAddressTokenTransferHashes: FunctionGetAddressTokenTransferHashes
|
|
13
|
+
readonly getAddressTokenTransferHashesWithTimestamp: FunctionGetAddressTokenTransferHashesWithTimestamp
|
|
11
14
|
readonly getBlockNumberOfTimestamp: (
|
|
12
15
|
timestamp: number,
|
|
13
16
|
logger?: Logger,
|
|
@@ -23,6 +26,18 @@ type FunctionGetAddressTransactionHashes = (parameters: {
|
|
|
23
26
|
readonly logger?: Logger
|
|
24
27
|
}) => Promise<readonly Hex[]>
|
|
25
28
|
|
|
29
|
+
type FunctionGetAddressTransactionHashesWithTimestamp = (parameters: {
|
|
30
|
+
readonly address: Hex
|
|
31
|
+
readonly startBlock?: bigint
|
|
32
|
+
readonly endBlock?: bigint
|
|
33
|
+
readonly logger?: Logger
|
|
34
|
+
}) => Promise<
|
|
35
|
+
readonly {
|
|
36
|
+
readonly hash: Hex
|
|
37
|
+
readonly timestamp: number
|
|
38
|
+
}[]
|
|
39
|
+
>
|
|
40
|
+
|
|
26
41
|
type FunctionGetAddressInternalTransactions = (parameters: {
|
|
27
42
|
readonly address: Hex
|
|
28
43
|
readonly startBlock?: bigint
|
|
@@ -31,6 +46,16 @@ type FunctionGetAddressInternalTransactions = (parameters: {
|
|
|
31
46
|
readonly logger?: Logger
|
|
32
47
|
}) => Promise<readonly InternalTransaction<undefined>[]>
|
|
33
48
|
|
|
49
|
+
type FunctionGetAddressInternalTransactionsWithTimestamp = (parameters: {
|
|
50
|
+
readonly address: Hex
|
|
51
|
+
readonly startBlock?: bigint
|
|
52
|
+
readonly endBlock?: bigint
|
|
53
|
+
readonly nativeCurrency: CryptoCurrency
|
|
54
|
+
readonly logger?: Logger
|
|
55
|
+
}) => Promise<
|
|
56
|
+
readonly (InternalTransaction<undefined> & { readonly timestamp: number })[]
|
|
57
|
+
>
|
|
58
|
+
|
|
34
59
|
type FunctionGetAddressTokenTransferHashes = (parameters: {
|
|
35
60
|
readonly address: Hex
|
|
36
61
|
readonly startBlock?: bigint
|
|
@@ -38,6 +63,18 @@ type FunctionGetAddressTokenTransferHashes = (parameters: {
|
|
|
38
63
|
readonly logger?: Logger
|
|
39
64
|
}) => Promise<readonly Hex[]>
|
|
40
65
|
|
|
66
|
+
type FunctionGetAddressTokenTransferHashesWithTimestamp = (parameters: {
|
|
67
|
+
readonly address: Hex
|
|
68
|
+
readonly startBlock?: bigint
|
|
69
|
+
readonly endBlock?: bigint
|
|
70
|
+
readonly logger?: Logger
|
|
71
|
+
}) => Promise<
|
|
72
|
+
readonly {
|
|
73
|
+
readonly hash: Hex
|
|
74
|
+
readonly timestamp: number
|
|
75
|
+
}[]
|
|
76
|
+
>
|
|
77
|
+
|
|
41
78
|
type FunctionGetContract = (
|
|
42
79
|
address: Hex,
|
|
43
80
|
logger?: Logger,
|