@indexing/jiti 0.0.31 → 0.0.33

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/dist/main.js CHANGED
@@ -64,6 +64,246 @@ const $59fb8e0333a5d25f$var$rawTemplate = {
64
64
  var $59fb8e0333a5d25f$export$2e2bcd8739ae039 = $59fb8e0333a5d25f$var$rawTemplate;
65
65
 
66
66
 
67
+ const $25d5bdd23cba31eb$export$ace043a4f2efe476 = {
68
+ match: (block)=>[
69
+ "APTOS",
70
+ "APTOS_TESTNET"
71
+ ].includes(block._network),
72
+ transform (block) {
73
+ let transfers = [];
74
+ for (const tx of block.transactions){
75
+ if (!tx?.events || !Array.isArray(tx.events)) continue;
76
+ const timestamp = tx.timestamp ? new Date(parseInt(tx.timestamp, 10) / 1000).toISOString() : null;
77
+ const transfersByKey = {};
78
+ for (const evt of tx.events){
79
+ const evtType = evt.type;
80
+ if (/::(Withdraw|Deposit)[^:]*/.test(evtType)) {
81
+ const data = evt.data;
82
+ const amount = data.amount;
83
+ const accountAddr = data.store_owner || evt.guid?.account_address || "";
84
+ let tokenAddr = "0x1::aptos_coin::AptosCoin";
85
+ if (data.store) tokenAddr = tx.changes.find((c)=>c.address === data.store && c.data.type === "0x1::fungible_asset::FungibleStore")?.data?.data?.metadata?.inner || data.store;
86
+ const compositeKey = `${tx.hash}-${tokenAddr}-${amount}`;
87
+ if (!transfersByKey[compositeKey]) transfersByKey[compositeKey] = {
88
+ amount: amount,
89
+ tokenAddress: tokenAddr
90
+ };
91
+ if (/::Withdraw[^:]*/.test(evtType)) transfersByKey[compositeKey].from = accountAddr;
92
+ else transfersByKey[compositeKey].to = accountAddr;
93
+ }
94
+ }
95
+ for (const partial of Object.values(transfersByKey)){
96
+ if (!partial.from || !partial.to) continue;
97
+ const fromAddr = partial.from.length < 66 ? `0x0${partial.from.slice(2)}` : partial.from;
98
+ const toAddr = partial.to.length < 66 ? `0x0${partial.to.slice(2)}` : partial.to;
99
+ let finalToken = null;
100
+ let finalTokenType = "TOKEN";
101
+ if (partial.tokenAddress?.toLowerCase().includes("aptos_coin")) finalToken = null;
102
+ else finalToken = partial.tokenAddress?.toLowerCase();
103
+ const gasUsed = BigInt(tx.gas_used || "0");
104
+ transfers.push({
105
+ amount: BigInt(partial.amount),
106
+ blockNumber: parseInt(block.block_height, 10),
107
+ from: fromAddr,
108
+ to: toAddr,
109
+ timestamp: timestamp,
110
+ token: finalToken,
111
+ tokenType: finalTokenType,
112
+ transactionGasFee: gasUsed,
113
+ transactionHash: tx.hash
114
+ });
115
+ }
116
+ }
117
+ return transfers;
118
+ },
119
+ tests: [
120
+ {
121
+ params: {
122
+ network: "APTOS",
123
+ walletAddress: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00"
124
+ },
125
+ payload: "https://jiti.indexing.co/networks/aptos/297956660",
126
+ output: [
127
+ {
128
+ amount: 1611839920n,
129
+ blockNumber: 297956660,
130
+ from: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00",
131
+ to: "0x3b5d2e7e8da86903beb19d5a7135764aac812e18af193895d75f3a8f6a066cb0",
132
+ timestamp: "2025-03-02T21:07:06.002Z",
133
+ token: null,
134
+ tokenType: "TOKEN",
135
+ transactionGasFee: 13n,
136
+ transactionHash: "0xfbdef795d11df124cca264f3370b09fb04fb1c1d24a2d2e1df0693c096a76d13"
137
+ },
138
+ {
139
+ amount: 1502138836n,
140
+ blockNumber: 297956660,
141
+ from: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00",
142
+ to: "0x04b2b6bc8c2c5794c51607c962f482593f9b5ea09373a8ce249a1f799cca7a1e",
143
+ timestamp: "2025-03-02T21:07:06.002Z",
144
+ token: null,
145
+ tokenType: "TOKEN",
146
+ transactionGasFee: 13n,
147
+ transactionHash: "0xfbdef795d11df124cca264f3370b09fb04fb1c1d24a2d2e1df0693c096a76d13"
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ params: {
153
+ network: "APTOS",
154
+ contractAddress: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b"
155
+ },
156
+ payload: "https://jiti.indexing.co/networks/aptos/303623631",
157
+ output: [
158
+ {
159
+ amount: 1000060n,
160
+ blockNumber: 303623631,
161
+ from: "0xa4e7455d27731ab857e9701b1e6ed72591132b909fe6e4fd99b66c1d6318d9e8",
162
+ timestamp: "2025-03-14T15:39:49.845Z",
163
+ to: "0x9317336bfc9ba6987d40492ddea8d41e11b7c2e473f3556a9c82309d326e79ce",
164
+ token: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
165
+ tokenType: "TOKEN",
166
+ transactionGasFee: 16n,
167
+ transactionHash: "0x24b8854bad1f6543b35069eacd6ec40a583ca7fa452b422b04d747d24b65279c"
168
+ }
169
+ ]
170
+ }
171
+ ]
172
+ };
173
+
174
+
175
+ const $60d24c82dc5feb2e$export$893111d8d332e195 = {
176
+ match: (block)=>[
177
+ "CARDANO"
178
+ ].includes(block._network),
179
+ transform (block) {
180
+ let transfers = [];
181
+ const blockTimestamp = new Date(block.timestamp * 1000).toISOString();
182
+ for (const tx of block.transactions){
183
+ const typedTx = tx;
184
+ if (!Array.isArray(typedTx.operations)) continue;
185
+ const transactionHash = typedTx.transaction_identifier?.hash || "";
186
+ const inputs = typedTx.operations.filter((op)=>op.type === "input");
187
+ const outputs = typedTx.operations.filter((op)=>op.type === "output");
188
+ if (!inputs.length && !outputs.length) continue;
189
+ const fromAddress = inputs[0]?.account?.address;
190
+ if (!fromAddress) continue;
191
+ const sumInputs = inputs.reduce((acc, op)=>{
192
+ const val = BigInt(op.amount?.value || "0");
193
+ return acc + val;
194
+ }, BigInt(0));
195
+ const sumOutputs = outputs.reduce((acc, op)=>{
196
+ const val = BigInt(op.amount?.value || "0");
197
+ return acc + val;
198
+ }, BigInt(0));
199
+ const transactionFee = sumInputs + BigInt(sumOutputs);
200
+ for (const out of outputs){
201
+ const rawValue = out.amount?.value || "0";
202
+ const absoluteValue = BigInt(rawValue);
203
+ transfers.push({
204
+ amount: absoluteValue < 0 ? -absoluteValue : absoluteValue,
205
+ blockNumber: block.block_identifier.index,
206
+ from: fromAddress,
207
+ timestamp: blockTimestamp,
208
+ to: out.account?.address || "",
209
+ token: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? null : out.amount?.currency?.symbol,
210
+ tokenType: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? "NATIVE" : "TOKEN",
211
+ transactionGasFee: transactionFee < 0 ? -transactionFee : transactionFee,
212
+ transactionHash: transactionHash
213
+ });
214
+ }
215
+ }
216
+ return transfers;
217
+ },
218
+ tests: [
219
+ {
220
+ params: {
221
+ network: "CARDANO",
222
+ walletAddress: "addr1q9syxu908lef7r6rsvk0h7gsx3rxj22cuykgx2a2l4hcfd8e9y2e9vtv4w9dyej96w99wwj8hwgc273862lk6a3vt30qjjrund",
223
+ contractAddress: ""
224
+ },
225
+ payload: "https://jiti.indexing.co/networks/cardano/11443286",
226
+ output: [
227
+ {
228
+ amount: 1110000n,
229
+ blockNumber: 11443286,
230
+ from: "addr1qymdv285few5tyqvya86rl97r9e608njs37shfew6l2nn473aw2pcnrcvfwfgg2dnew99m4tjj0apsu7232w2euzwpysndh0h3",
231
+ timestamp: "+057068-01-19T05:23:20.000Z",
232
+ to: "addr1q9syxu908lef7r6rsvk0h7gsx3rxj22cuykgx2a2l4hcfd8e9y2e9vtv4w9dyej96w99wwj8hwgc273862lk6a3vt30qjjrund",
233
+ token: null,
234
+ tokenType: "NATIVE",
235
+ transactionGasFee: 174257n,
236
+ transactionHash: "261c42ba9124f55d8e169ebb692cd3759d796a54369acb316ee449b546e79309"
237
+ }
238
+ ]
239
+ }
240
+ ]
241
+ };
242
+
243
+
244
+
245
+
246
+
247
+
248
+ var $f9ab50a3e879ac1c$require$Buffer = $8zHUo$buffer.Buffer;
249
+ const $f9ab50a3e879ac1c$export$b5fd4920e8b7d913 = {
250
+ match: (block)=>!!block.block,
251
+ transform (block) {
252
+ let transfers = [];
253
+ const typedBlock = block;
254
+ const blockNumber = Number(typedBlock.block.header.height);
255
+ const blockTimestamp = new Date(typedBlock.block.header.time).toISOString();
256
+ for (const txRaw of typedBlock.block.data.txs || []){
257
+ const decoded = (0, $8zHUo$cosmjsprotosigning.decodeTxRaw)(new Uint8Array($f9ab50a3e879ac1c$require$Buffer.from(txRaw, "base64")));
258
+ const txHash = (0, $8zHUo$viem.sha256)(new Uint8Array($f9ab50a3e879ac1c$require$Buffer.from(txRaw, "base64")));
259
+ const transactionGasFee = BigInt(decoded.authInfo.fee?.amount?.[0]?.amount || "0");
260
+ const registry = new (0, $8zHUo$cosmjsprotosigning.Registry)((0, $8zHUo$cosmjsstargate.defaultRegistryTypes));
261
+ for (const message of decoded.body.messages)if ([
262
+ "/ibc.applications.transfer.v1.MsgTransfer",
263
+ "/cosmos.bank.v1beta1.MsgSend"
264
+ ].includes(message.typeUrl)) {
265
+ const decodedMsg = registry.decode(message);
266
+ transfers.push({
267
+ blockNumber: blockNumber,
268
+ from: decodedMsg.sender,
269
+ to: decodedMsg.receiver,
270
+ amount: BigInt(decodedMsg.token.amount),
271
+ token: decodedMsg.token.denom,
272
+ tokenType: "NATIVE",
273
+ timestamp: blockTimestamp,
274
+ transactionHash: txHash.slice(2).toUpperCase(),
275
+ transactionGasFee: transactionGasFee
276
+ });
277
+ }
278
+ }
279
+ return transfers;
280
+ },
281
+ tests: [
282
+ {
283
+ params: {
284
+ network: "COSMOS",
285
+ walletAddress: "cosmos1x4qvmtcfc02pklttfgxzdccxcsyzklrxavteyz",
286
+ contractAddress: "ibc/F663521BF1836B00F5F177680F74BFB9A8B5654A694D0D2BC249E03CF2509013"
287
+ },
288
+ payload: "https://jiti.indexing.co/networks/cosmos/24419691",
289
+ output: [
290
+ {
291
+ blockNumber: 24419691,
292
+ from: "cosmos1x4qvmtcfc02pklttfgxzdccxcsyzklrxavteyz",
293
+ to: "noble1x4qvmtcfc02pklttfgxzdccxcsyzklrx4073uv",
294
+ amount: 500000n,
295
+ token: "ibc/F663521BF1836B00F5F177680F74BFB9A8B5654A694D0D2BC249E03CF2509013",
296
+ tokenType: "NATIVE",
297
+ timestamp: "2025-02-14T21:48:22.809Z",
298
+ transactionHash: "963D4D7BB59C1280F58A7ECA2F1934E2AA005109A989193C815C7B98EDCD7445",
299
+ transactionGasFee: 4860n
300
+ }
301
+ ]
302
+ }
303
+ ]
304
+ };
305
+
306
+
67
307
  var $d7167569386d0d4c$exports = {};
68
308
  var $596a656635c74d50$exports = {};
69
309
 
@@ -275,709 +515,131 @@ $parcel$exportWildcard($d7167569386d0d4c$exports, $f7a3fb164436c9c3$exports);
275
515
  $parcel$exportWildcard($d7167569386d0d4c$exports, $414c83047563e72e$exports);
276
516
 
277
517
 
278
-
279
-
280
-
281
-
282
- var $6144a02851f23907$require$Buffer = $8zHUo$buffer.Buffer;
283
- const $6144a02851f23907$var$NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
284
- const $6144a02851f23907$var$tokenTransfersTemplate = {
285
- key: "token_transfers",
286
- name: "Token Transfers",
287
- description: "Get all token transfers for a set of token types.",
288
- tags: [
289
- "EVM",
290
- "ERC20",
291
- "ERC721",
292
- "NFT",
293
- "TOKEN"
294
- ],
295
- disabled: false,
296
- params: [
297
- {
298
- key: "network",
299
- name: "Network",
300
- type: "NETWORK",
301
- optional: false
302
- },
303
- {
304
- key: "contractAddress",
305
- name: "Contract Address",
306
- type: "ADDRESS",
307
- optional: true
308
- },
309
- {
310
- key: "walletAddress",
311
- name: "Wallet Address",
312
- type: "ADDRESS",
313
- optional: true
314
- },
315
- {
316
- key: "tokenTypes",
317
- name: "Token Types",
318
- type: "STRING",
319
- multiple: true,
320
- optional: true,
321
- values: [
322
- "NATIVE",
323
- "TOKEN",
324
- "NFT"
325
- ]
326
- }
327
- ],
328
- transform: (block, _ctx)=>{
518
+ const $8deaea1ef39b6485$var$NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
519
+ const $8deaea1ef39b6485$export$5beebc5708fabf3c = {
520
+ match: ()=>true,
521
+ transform (block, _ctx) {
329
522
  const TOKEN_TYPES = _ctx.params.tokenTypes || [];
330
523
  let transfers = [];
331
- switch(block._network){
332
- case "APTOS":
333
- case "APTOS_TESTNET":
334
- for (const tx of block.transactions){
335
- if (!tx?.events || !Array.isArray(tx.events)) continue;
336
- const timestamp = tx.timestamp ? new Date(parseInt(tx.timestamp, 10) / 1000).toISOString() : null;
337
- const transfersByKey = {};
338
- for (const evt of tx.events){
339
- const evtType = evt.type;
340
- if (/::(Withdraw|Deposit)[^:]*/.test(evtType)) {
341
- const data = evt.data;
342
- const amount = data.amount;
343
- const accountAddr = data.store_owner || evt.guid?.account_address || "";
344
- let tokenAddr = "0x1::aptos_coin::AptosCoin";
345
- if (data.store) tokenAddr = tx.changes.find((c)=>c.address === data.store && c.data.type === "0x1::fungible_asset::FungibleStore")?.data?.data?.metadata?.inner || data.store;
346
- const compositeKey = `${tx.hash}-${tokenAddr}-${amount}`;
347
- if (!transfersByKey[compositeKey]) transfersByKey[compositeKey] = {
348
- amount: amount,
349
- tokenAddress: tokenAddr
350
- };
351
- if (/::Withdraw[^:]*/.test(evtType)) transfersByKey[compositeKey].from = accountAddr;
352
- else transfersByKey[compositeKey].to = accountAddr;
353
- }
354
- }
355
- for (const partial of Object.values(transfersByKey)){
356
- if (!partial.from || !partial.to) continue;
357
- const fromAddr = partial.from.length < 66 ? `0x0${partial.from.slice(2)}` : partial.from;
358
- const toAddr = partial.to.length < 66 ? `0x0${partial.to.slice(2)}` : partial.to;
359
- let finalToken = null;
360
- let finalTokenType = "TOKEN";
361
- if (partial.tokenAddress?.toLowerCase().includes("aptos_coin")) finalToken = null;
362
- else finalToken = partial.tokenAddress?.toLowerCase();
363
- const gasUsed = BigInt(tx.gas_used || "0");
364
- transfers.push({
365
- amount: BigInt(partial.amount),
366
- blockNumber: parseInt(block.block_height, 10),
367
- from: fromAddr,
368
- to: toAddr,
369
- timestamp: timestamp,
370
- token: finalToken,
371
- tokenType: finalTokenType,
372
- transactionGasFee: gasUsed,
373
- transactionHash: tx.hash
374
- });
375
- }
376
- }
377
- break;
378
- case "BITCOIN":
379
- case "BITCOIN_TESTNET":
380
- case "LITCOIN":
381
- case "DOGECOIN":
382
- for (const tx of block.tx){
383
- const timestamp = tx.time ? new Date(tx.time * 1000).toISOString() : null;
384
- const vin = tx.vin[0];
385
- const vout = tx.vout;
386
- const fromVout = Math.min(vin.vout || 1000, vout.length - 1);
387
- const fromAddress = vin.prevout?.scriptPubKey?.address || vout[fromVout]?.scriptPubKey?.address || vout[fromVout]?.scriptPubKey?.addresses?.[0];
388
- if (!fromAddress) continue;
389
- for (const v of vout)transfers.push({
390
- amount: BigInt(Math.round(v.value * Math.pow(10, 8))),
391
- blockNumber: block.height,
392
- from: fromAddress,
393
- timestamp: timestamp,
394
- to: v.scriptPubKey.address || v.scriptPubKey.addresses?.[0],
395
- transactionGasFee: BigInt(Math.round((tx.fee || 0) * Math.pow(10, 8))),
396
- transactionHash: tx.txid,
397
- token: null,
398
- tokenType: "NATIVE"
399
- });
400
- }
401
- break;
402
- case "CARDANO":
403
- {
404
- const blockTimestamp = new Date(block.timestamp * 1000).toISOString();
405
- for (const tx of block.transactions){
406
- const typedTx = tx;
407
- if (!Array.isArray(typedTx.operations)) continue;
408
- const transactionHash = typedTx.transaction_identifier?.hash || "";
409
- const inputs = typedTx.operations.filter((op)=>op.type === "input");
410
- const outputs = typedTx.operations.filter((op)=>op.type === "output");
411
- if (!inputs.length && !outputs.length) continue;
412
- const fromAddress = inputs[0]?.account?.address;
413
- if (!fromAddress) continue;
414
- const sumInputs = inputs.reduce((acc, op)=>{
415
- const val = BigInt(op.amount?.value || "0");
416
- return acc + val;
417
- }, BigInt(0));
418
- const sumOutputs = outputs.reduce((acc, op)=>{
419
- const val = BigInt(op.amount?.value || "0");
420
- return acc + val;
421
- }, BigInt(0));
422
- const transactionFee = sumInputs + BigInt(sumOutputs);
423
- for (const out of outputs){
424
- const rawValue = out.amount?.value || "0";
425
- const absoluteValue = BigInt(rawValue);
426
- transfers.push({
427
- amount: absoluteValue < 0 ? -absoluteValue : absoluteValue,
428
- blockNumber: block.block_identifier.index,
429
- from: fromAddress,
430
- timestamp: blockTimestamp,
431
- to: out.account?.address || "",
432
- token: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? null : out.amount?.currency?.symbol,
433
- tokenType: out.amount?.currency?.symbol?.toUpperCase() === "ADA" ? "NATIVE" : "TOKEN",
434
- transactionGasFee: transactionFee < 0 ? -transactionFee : transactionFee,
435
- transactionHash: transactionHash
436
- });
437
- }
438
- }
439
- break;
440
- }
441
- case "RIPPLE":
442
- if (!Array.isArray(block.transactions)) break;
443
- for (const rawTx of block.transactions){
444
- const typedTx = rawTx;
445
- if (typedTx.TransactionType !== "Payment") continue;
446
- const deliveredOrAmount = typedTx.metaData?.delivered_amount ?? typedTx.Amount ?? "0";
447
- let tokenSymbol = "XRP";
448
- let tokenType = "NATIVE";
449
- let parsedAmount;
450
- if (typeof deliveredOrAmount === "object") {
451
- tokenSymbol = deliveredOrAmount.currency?.toUpperCase() ?? "UNKNOWN";
452
- tokenType = "TOKEN";
453
- const floatVal = parseFloat(deliveredOrAmount.value);
454
- const smallestUnit = Math.round(floatVal * 1000000);
455
- parsedAmount = BigInt(smallestUnit);
456
- } else parsedAmount = BigInt(String(deliveredOrAmount));
524
+ for (const tx of block.transactions){
525
+ if (!tx.receipt) continue;
526
+ const timestamp = new Date(block.timestamp * 1000).toISOString();
527
+ const transactionGasFee = BigInt(tx.receipt.gasUsed) * BigInt(tx.receipt.effectiveGasPrice);
528
+ // track direct ETH transfers
529
+ if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("NATIVE")) {
530
+ // pull from traces, if available
531
+ if (Array.isArray(tx.traces)) for (const trace of tx.traces.filter((t)=>t.action)){
532
+ const action = trace.action;
533
+ if (!action?.value) continue;
457
534
  transfers.push({
458
- amount: parsedAmount,
459
- blockNumber: parseInt(block.ledger_index, 10),
460
- from: typedTx.Account ?? "UNKNOWN",
461
- timestamp: block.close_time_iso ? block.close_time_iso : null,
462
- to: typedTx.Destination ?? "UNKNOWN",
463
- token: tokenSymbol,
464
- tokenType: tokenType,
465
- transactionGasFee: BigInt(typedTx.Fee ?? "0"),
466
- transactionHash: typedTx.hash ?? ""
535
+ amount: BigInt(action.value),
536
+ blockNumber: tx.blockNumber,
537
+ from: action.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
538
+ index: trace.traceAddress?.join("-"),
539
+ timestamp: timestamp,
540
+ to: action.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
541
+ tokenType: "NATIVE",
542
+ transactionGasFee: transactionGasFee,
543
+ transactionHash: tx.hash
467
544
  });
468
545
  }
469
- break;
470
- case "SOLANA":
471
- for (const tx of block.transactions){
472
- const solanaTx = tx;
473
- const txHash = solanaTx.transaction.signatures[0];
474
- const timestamp = block.blockTime ? new Date(block.blockTime * 1000).toISOString() : null;
475
- const allAccounts = solanaTx.transaction.message.accountKeys.concat(solanaTx.meta.loadedAddresses.writable).concat(solanaTx.meta.loadedAddresses.readonly);
476
- let txFee = BigInt(solanaTx.meta.fee);
477
- if (txFee < BigInt(10)) txFee = txFee * BigInt(Math.pow(10, 9));
478
- const transfersByKey = {};
479
- for (const post of solanaTx.meta.postTokenBalances){
480
- let matched = false;
481
- for (const pre of solanaTx.meta.preTokenBalances)if (post.mint === pre.mint && post.owner === pre.owner) {
482
- let diff = BigInt(post.uiTokenAmount.amount) - BigInt(pre.uiTokenAmount.amount);
483
- if (diff === BigInt(0)) continue;
484
- const isNegDiff = diff < 0;
485
- if (diff < 0) diff = -diff;
486
- const key = `${post.mint}-${diff.toString()}`;
487
- const txfer = {
488
- amount: diff,
489
- blockNumber: block.blockHeight,
490
- from: pre.owner,
491
- timestamp: timestamp,
492
- to: post.owner,
493
- transactionGasFee: txFee,
494
- transactionHash: txHash,
495
- token: post.mint,
496
- tokenType: "TOKEN"
497
- };
498
- if (isNegDiff) delete txfer.to;
499
- else delete txfer.from;
500
- transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
501
- matched = true;
502
- }
503
- if (!matched) {
504
- let diff = BigInt(post.uiTokenAmount.amount);
505
- const isNegDiff = diff < 0;
506
- if (diff < 0) diff = -diff;
507
- const key = `${post.mint}-${diff.toString()}`;
508
- const txfer = {
509
- amount: diff,
510
- blockNumber: block.blockHeight,
511
- from: null,
512
- timestamp: timestamp,
513
- to: post.owner,
514
- token: post.mint,
515
- tokenType: "TOKEN",
516
- transactionGasFee: txFee,
517
- transactionHash: txHash
518
- };
519
- if (isNegDiff) delete txfer.to;
520
- else delete txfer.from;
521
- transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
522
- }
523
- }
524
- for(let i = 1; i < solanaTx.meta.postBalances.length; i += 1){
525
- const post = solanaTx.meta.postBalances[i];
526
- const pre = solanaTx.meta.preBalances[i];
527
- if (post !== undefined && pre !== undefined && post !== pre) {
528
- let diff = BigInt(post) - BigInt(pre);
529
- if (diff < 0) diff = -diff;
530
- const key = `null-${diff.toString()}`;
531
- const txfer = {
532
- amount: diff,
533
- blockNumber: block.blockHeight,
534
- from: post > pre ? typeof allAccounts[0] === "string" ? allAccounts[0] : allAccounts[0]?.pubkey : typeof allAccounts[i] === "string" ? allAccounts[i] : allAccounts[i]?.pubkey,
535
- timestamp: timestamp,
536
- to: typeof allAccounts[i] === "string" ? allAccounts[i] : allAccounts[i]?.pubkey?.toString(),
537
- token: null,
538
- tokenType: "NATIVE",
539
- transactionGasFee: txFee,
540
- transactionHash: txHash
541
- };
542
- if (post > pre) {
543
- if (transfersByKey[key]) delete txfer.from;
544
- } else delete txfer.to;
545
- transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
546
- }
547
- }
548
- const unmatchedFrom = {};
549
- const unmatchedTo = {};
550
- for(const key in transfersByKey){
551
- const txfer = transfersByKey[key];
552
- if (!txfer.from) {
553
- if (!unmatchedFrom[txfer.token]) unmatchedFrom[txfer.token] = [];
554
- unmatchedFrom[txfer.token].push(txfer);
555
- delete transfersByKey[key];
556
- } else if (!txfer.to) {
557
- if (!unmatchedTo[txfer.token]) unmatchedTo[txfer.token] = [];
558
- unmatchedTo[txfer.token].push(txfer);
559
- delete transfersByKey[key];
560
- }
561
- }
562
- for(const token in unmatchedFrom)if (unmatchedTo[token]?.length && unmatchedTo[token].reduce((a, b)=>a + BigInt(b.amount), BigInt(0)) - unmatchedFrom[token].reduce((a, b)=>a + BigInt(b.amount), BigInt(0)) === BigInt(0)) {
563
- unmatchedTo[token].sort((a, b)=>a.amount > b.amount ? 1 : -1);
564
- unmatchedFrom[token].forEach((um)=>{
565
- um.from = unmatchedTo[token][0].from;
566
- transfersByKey[`${token}-${um.amount.toString()}`] = um;
567
- });
568
- }
569
- transfers.push(...Object.values(transfersByKey));
570
- }
571
- break;
572
- case "STARKNET":
573
- if (!Array.isArray(block.transactions)) break;
574
- for (const tx of block.transactions){
575
- const typedTx = tx;
576
- const timestamp = block.timestamp ? new Date(block.timestamp * 1000).toISOString() : null;
577
- let transactionGasFee = BigInt(0);
578
- if (typedTx?.receipt?.actual_fee?.amount) transactionGasFee = BigInt(typedTx.receipt.actual_fee.amount);
579
- const transactionHash = typedTx.transaction_hash;
580
- if (!typedTx.receipt?.events) continue;
581
- for (const event of typedTx.receipt.events){
582
- if (!event.keys.includes("0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")) continue;
583
- if (event.data.length < 3) continue;
584
- const [from, to, amountHex] = event.data;
585
- const amount = BigInt(amountHex);
546
+ else if (tx.value?.length >= 3 || /\d+/.test(tx.value)) transfers.push({
547
+ amount: BigInt(tx.value),
548
+ blockNumber: tx.blockNumber,
549
+ from: tx.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
550
+ timestamp: timestamp,
551
+ to: tx.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
552
+ tokenType: "NATIVE",
553
+ transactionGasFee: transactionGasFee,
554
+ transactionHash: tx.hash
555
+ });
556
+ }
557
+ // track ERC20 transfers
558
+ if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("TOKEN")) for (const log of tx.receipt.logs){
559
+ const txfer = (0, $da55be3e40667945$export$cf548b70626e2eb9)(log, [
560
+ "Transfer(address indexed from, address indexed to, uint256 value)"
561
+ ]);
562
+ if (txfer) transfers.push({
563
+ amount: txfer.decoded.value,
564
+ blockNumber: tx.blockNumber,
565
+ from: txfer.decoded.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
566
+ index: log.logIndex,
567
+ timestamp: timestamp,
568
+ to: txfer.decoded.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
569
+ token: log.address.toLowerCase(),
570
+ tokenType: "TOKEN",
571
+ transactionGasFee: transactionGasFee,
572
+ transactionHash: tx.hash
573
+ });
574
+ }
575
+ if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("NFT")) for (const log of tx.receipt.logs){
576
+ const txfer = (0, $da55be3e40667945$export$cf548b70626e2eb9)(log, [
577
+ "Transfer(address indexed from, address indexed to, uint256 indexed value)",
578
+ "TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value)",
579
+ "TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values)"
580
+ ]);
581
+ if (!txfer) continue;
582
+ switch(txfer.metadata.name){
583
+ case "Transfer":
586
584
  transfers.push({
587
- amount: amount,
588
- blockNumber: block.block_number,
589
- from: from,
585
+ amount: 1,
586
+ blockNumber: tx.blockNumber,
587
+ from: txfer.decoded.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
588
+ index: log.logIndex,
590
589
  timestamp: timestamp,
591
- to: to,
592
- token: null,
593
- tokenType: "NATIVE",
590
+ to: txfer.decoded.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
591
+ token: log.address.toLowerCase(),
592
+ tokenId: txfer.decoded.value.toString(),
593
+ tokenType: "NFT",
594
594
  transactionGasFee: transactionGasFee,
595
- transactionHash: transactionHash
596
- });
597
- }
598
- }
599
- break;
600
- case "STELLAR":
601
- for (const tx of block.transactions){
602
- const typedTx = tx;
603
- for (const op of typedTx.operations)if (op.type === "payment") transfers.push({
604
- amount: BigInt(op.amount.replace(".", "")),
605
- blockNumber: block.sequence,
606
- from: op.from,
607
- timestamp: typedTx.created_at,
608
- to: op.to,
609
- token: op.asset_type === "native" ? null : op.asset_issuer,
610
- tokenType: op.asset_type === "native" ? "NATIVE" : "TOKEN",
611
- transactionGasFee: BigInt(typedTx.fee_charged),
612
- transactionHash: typedTx.hash
613
- });
614
- }
615
- break;
616
- case "SUI":
617
- {
618
- const blockNumber = parseInt(block.sequence, 10);
619
- const blockTimestamp = new Date(parseInt(block.timestamp, 10)).toISOString();
620
- const transactions = block.transactions || [];
621
- for (const tx of transactions){
622
- const transactionHash = tx.digest;
623
- let transactionGasFee = BigInt(0);
624
- if (tx.effects?.gasUsed) {
625
- const gu = tx.effects.gasUsed;
626
- transactionGasFee = BigInt(gu.computationCost) + BigInt(gu.storageCost) - BigInt(gu.storageRebate) + BigInt(gu.nonRefundableStorageFee);
627
- if (transactionGasFee < 0n) transactionGasFee = 0n;
628
- }
629
- const balanceChanges = tx.balanceChanges || [];
630
- for (const bc of balanceChanges){
631
- let rawAmt = BigInt(bc.amount);
632
- if (rawAmt === 0n) continue;
633
- let fromAddr;
634
- let toAddr;
635
- const rawOwner = bc.owner?.AddressOwner || bc.owner?.ObjectOwner || bc.owner?.Shared?.initial_shared_version || "UNKNOWN_OWNER";
636
- if (rawAmt < 0n) {
637
- fromAddr = String(rawOwner);
638
- toAddr = undefined;
639
- rawAmt = -rawAmt;
640
- } else {
641
- fromAddr = undefined;
642
- toAddr = String(rawOwner);
643
- }
644
- transfers.push({
645
- blockNumber: blockNumber,
646
- from: fromAddr,
647
- to: toAddr,
648
- amount: rawAmt,
649
- token: bc.coinType,
650
- tokenType: "NATIVE",
651
- timestamp: blockTimestamp,
652
- transactionHash: transactionHash,
653
- transactionGasFee: transactionGasFee
654
- });
655
- }
656
- }
657
- break;
658
- }
659
- case "TON":
660
- {
661
- const blockNumber = block.seqno;
662
- const blockTimestamp = new Date(block.shards?.[0]?.gen_utime * 1000).toISOString();
663
- for (const shard of block.shards || [])for (const tx of shard.transactions || []){
664
- const transactionLT = tx.transaction_id.lt;
665
- const transactionHash = tx.transaction_id.hash;
666
- const transactionFee = BigInt(tx.fee || "0");
667
- const inVal = BigInt(tx.in_msg?.value || "0");
668
- if (inVal > 0n) transfers.push({
669
- blockNumber: blockNumber,
670
- from: tx.in_msg?.source?.account_address,
671
- to: tx.address?.account_address,
672
- amount: inVal,
673
- token: "TON",
674
- tokenType: "NATIVE",
675
- timestamp: blockTimestamp,
676
- transactionHash: transactionHash,
677
- transactionGasFee: transactionFee
595
+ transactionHash: tx.hash
678
596
  });
679
- for (const outMsg of tx.out_msgs || []){
680
- const outVal = BigInt(outMsg.value || "0");
681
- if (outVal > 0n) transfers.push({
682
- blockNumber: blockNumber,
683
- from: outMsg.source?.account_address,
684
- to: outMsg.destination?.account_address,
685
- amount: outVal,
686
- token: "TON",
687
- tokenType: "NATIVE",
688
- timestamp: blockTimestamp,
689
- transactionHash: transactionHash,
690
- transactionGasFee: transactionFee
691
- });
692
- }
693
- }
694
- break;
695
- }
696
- case "ASTAR":
697
- case "ENJIN":
698
- case "KUSAMA":
699
- case "POLKADOT":
700
- case "BITTENSOR":
701
- {
702
- const typedBlock = block;
703
- const blockNumber = typedBlock.blockNumber;
704
- const timestampExtrinsic = typedBlock.extrinsics.find((ex)=>ex.method === "timestamp.set");
705
- const blockTimestamp = timestampExtrinsic ? new Date(Number(timestampExtrinsic.args[0].toString().replace(/,/g, ""))).toISOString() : new Date().toISOString();
706
- for (const extrinsic of typedBlock.extrinsics)if ([
707
- "balances.transfer",
708
- "balances.transferKeepAlive"
709
- ].includes(extrinsic.method)) {
710
- const from = extrinsic.signer;
711
- const to = extrinsic.args[0]?.Id || "";
712
- const amount = BigInt(extrinsic.args[1].replace(/,/g, ""));
597
+ break;
598
+ case "TransferSingle":
713
599
  transfers.push({
714
- amount: amount,
715
- blockNumber: blockNumber,
716
- from: from,
717
- to: to,
718
- token: null,
719
- tokenType: "NATIVE",
720
- timestamp: blockTimestamp,
721
- transactionGasFee: 0n,
722
- transactionHash: extrinsic.hash
723
- });
724
- }
725
- break;
726
- }
727
- case "FILECOIN":
728
- {
729
- const typedBlock = block;
730
- const blockNumber = typedBlock.Height;
731
- const blockTimestamp = new Date(typedBlock.Blocks[0].Timestamp * 1000).toISOString();
732
- const parentBaseFee = BigInt(typedBlock.Blocks[0].ParentBaseFee);
733
- let receiptIndex = 0;
734
- for (const msgGroup of typedBlock.messages){
735
- const secpkMessages = msgGroup.blockMessages.SecpkMessages || [];
736
- for (const msg of secpkMessages){
737
- const receipt = typedBlock.receipts[receiptIndex++];
738
- const gasUsed = receipt ? BigInt(receipt.GasUsed) : BigInt(0);
739
- const gasFeeCap = BigInt(msg.Message.GasFeeCap);
740
- const gasPremium = BigInt(msg.Message.GasPremium);
741
- const baseFeeBurn = gasUsed * parentBaseFee;
742
- const minerTip = gasUsed * (gasPremium < gasFeeCap - parentBaseFee ? gasPremium : gasFeeCap - parentBaseFee);
743
- const transactionGasFee = baseFeeBurn + minerTip;
744
- transfers.push({
745
- amount: BigInt(msg.Message.Value),
746
- blockNumber: blockNumber,
747
- from: msg.Message.From,
748
- to: msg.Message.To,
749
- token: null,
750
- tokenType: "NATIVE",
751
- timestamp: blockTimestamp,
752
- transactionGasFee: transactionGasFee,
753
- transactionHash: msg.CID["/"]
754
- });
755
- }
756
- }
757
- break;
758
- }
759
- // attempt to introspect data types
760
- default:
761
- // try Cosmos
762
- if (block.block) {
763
- const typedBlock = block;
764
- const blockNumber = Number(typedBlock.block.header.height);
765
- const blockTimestamp = new Date(typedBlock.block.header.time).toISOString();
766
- for (const txRaw of typedBlock.block.data.txs || []){
767
- const decoded = (0, $8zHUo$cosmjsprotosigning.decodeTxRaw)(new Uint8Array($6144a02851f23907$require$Buffer.from(txRaw, "base64")));
768
- const txHash = (0, $8zHUo$viem.sha256)(new Uint8Array($6144a02851f23907$require$Buffer.from(txRaw, "base64")));
769
- const transactionGasFee = BigInt(decoded.authInfo.fee?.amount?.[0]?.amount || "0");
770
- const registry = new (0, $8zHUo$cosmjsprotosigning.Registry)((0, $8zHUo$cosmjsstargate.defaultRegistryTypes));
771
- for (const message of decoded.body.messages)if ([
772
- "/ibc.applications.transfer.v1.MsgTransfer",
773
- "/cosmos.bank.v1beta1.MsgSend"
774
- ].includes(message.typeUrl)) {
775
- const decodedMsg = registry.decode(message);
776
- transfers.push({
777
- blockNumber: blockNumber,
778
- from: decodedMsg.sender,
779
- to: decodedMsg.receiver,
780
- amount: BigInt(decodedMsg.token.amount),
781
- token: decodedMsg.token.denom,
782
- tokenType: "NATIVE",
783
- timestamp: blockTimestamp,
784
- transactionHash: txHash.slice(2).toUpperCase(),
785
- transactionGasFee: transactionGasFee
786
- });
787
- }
788
- }
789
- break;
790
- }
791
- // otherwise assume EVM
792
- for (const tx of block.transactions){
793
- if (!tx.receipt) continue;
794
- const timestamp = new Date(block.timestamp * 1000).toISOString();
795
- const transactionGasFee = BigInt(tx.receipt.gasUsed) * BigInt(tx.receipt.effectiveGasPrice);
796
- // track direct ETH transfers
797
- if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("NATIVE")) {
798
- // pull from traces, if available
799
- if (Array.isArray(tx.traces)) for (const trace of tx.traces.filter((t)=>t.action)){
800
- const action = trace.action;
801
- if (!action?.value) continue;
802
- transfers.push({
803
- amount: BigInt(action.value),
804
- blockNumber: tx.blockNumber,
805
- from: action.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
806
- index: trace.traceAddress?.join("-"),
807
- timestamp: timestamp,
808
- to: action.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
809
- tokenType: "NATIVE",
810
- transactionGasFee: transactionGasFee,
811
- transactionHash: tx.hash
812
- });
813
- }
814
- else if (tx.value?.length >= 3 || /\d+/.test(tx.value)) transfers.push({
815
- amount: BigInt(tx.value),
600
+ amount: txfer.decoded.value,
816
601
  blockNumber: tx.blockNumber,
817
- from: tx.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
602
+ from: txfer.decoded.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
603
+ index: log.logIndex,
818
604
  timestamp: timestamp,
819
- to: tx.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
820
- tokenType: "NATIVE",
605
+ to: txfer.decoded.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
606
+ token: log.address.toLowerCase(),
607
+ tokenId: txfer.decoded.id.toString(),
608
+ tokenType: "NFT",
821
609
  transactionGasFee: transactionGasFee,
822
610
  transactionHash: tx.hash
823
611
  });
824
- }
825
- // track ERC20 transfers
826
- if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("TOKEN")) for (const log of tx.receipt.logs){
827
- const txfer = (0, $da55be3e40667945$export$cf548b70626e2eb9)(log, [
828
- "Transfer(address indexed from, address indexed to, uint256 value)"
829
- ]);
830
- if (txfer) transfers.push({
831
- amount: txfer.decoded.value,
612
+ break;
613
+ case "TransferBatch":
614
+ for(let i = 0; i < txfer.decoded.ids.length; i += 1)transfers.push({
615
+ amount: txfer.decoded.values[i],
832
616
  blockNumber: tx.blockNumber,
833
- from: txfer.decoded.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
617
+ from: txfer.decoded.from?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
834
618
  index: log.logIndex,
835
619
  timestamp: timestamp,
836
- to: txfer.decoded.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
620
+ to: txfer.decoded.to?.toLowerCase() || $8deaea1ef39b6485$var$NULL_ADDRESS,
837
621
  token: log.address.toLowerCase(),
838
- tokenType: "TOKEN",
622
+ tokenId: txfer.decoded.ids[i].toString(),
623
+ tokenType: "NFT",
839
624
  transactionGasFee: transactionGasFee,
840
625
  transactionHash: tx.hash
841
626
  });
842
- }
843
- if (!TOKEN_TYPES.length || TOKEN_TYPES.includes("NFT")) for (const log of tx.receipt.logs){
844
- const txfer = (0, $da55be3e40667945$export$cf548b70626e2eb9)(log, [
845
- "Transfer(address indexed from, address indexed to, uint256 indexed value)",
846
- "TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value)",
847
- "TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values)"
848
- ]);
849
- if (!txfer) continue;
850
- switch(txfer.metadata.name){
851
- case "Transfer":
852
- transfers.push({
853
- amount: 1,
854
- blockNumber: tx.blockNumber,
855
- from: txfer.decoded.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
856
- index: log.logIndex,
857
- timestamp: timestamp,
858
- to: txfer.decoded.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
859
- token: log.address.toLowerCase(),
860
- tokenId: txfer.decoded.value.toString(),
861
- tokenType: "NFT",
862
- transactionGasFee: transactionGasFee,
863
- transactionHash: tx.hash
864
- });
865
- break;
866
- case "TransferSingle":
867
- transfers.push({
868
- amount: txfer.decoded.value,
869
- blockNumber: tx.blockNumber,
870
- from: txfer.decoded.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
871
- index: log.logIndex,
872
- timestamp: timestamp,
873
- to: txfer.decoded.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
874
- token: log.address.toLowerCase(),
875
- tokenId: txfer.decoded.id.toString(),
876
- tokenType: "NFT",
877
- transactionGasFee: transactionGasFee,
878
- transactionHash: tx.hash
879
- });
880
- break;
881
- case "TransferBatch":
882
- for(let i = 0; i < txfer.decoded.ids.length; i += 1)transfers.push({
883
- amount: txfer.decoded.values[i],
884
- blockNumber: tx.blockNumber,
885
- from: txfer.decoded.from?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
886
- index: log.logIndex,
887
- timestamp: timestamp,
888
- to: txfer.decoded.to?.toLowerCase() || $6144a02851f23907$var$NULL_ADDRESS,
889
- token: log.address.toLowerCase(),
890
- tokenId: txfer.decoded.ids[i].toString(),
891
- tokenType: "NFT",
892
- transactionGasFee: transactionGasFee,
893
- transactionHash: tx.hash
894
- });
895
- break;
896
- }
897
- }
627
+ break;
898
628
  }
899
- if (typeof _ctx.params.contractAddress === "string") _ctx.params.contractAddress = _ctx.params.contractAddress.toLowerCase();
900
- if (typeof _ctx.params.walletAddress === "string") _ctx.params.walletAddress = _ctx.params.walletAddress.toLowerCase();
901
- break;
629
+ }
902
630
  }
903
- const seenTransfers = new Set();
904
- transfers = transfers.filter((txfer)=>{
905
- if (txfer.amount <= BigInt(0)) return false;
906
- if (_ctx.params.contractAddress && _ctx.params.contractAddress !== txfer.token && txfer.token) return false;
907
- if (_ctx.params.walletAddress && ![
908
- txfer.from,
909
- txfer.to
910
- ].includes(_ctx.params.walletAddress)) return false;
911
- const key = `${txfer.transactionHash}-${txfer.from}-${txfer.to}-${txfer.amount}-${txfer.token}`;
912
- if (seenTransfers.has(key)) return false;
913
- seenTransfers.add(key);
914
- return true;
915
- });
631
+ if (typeof _ctx.params.contractAddress === "string") _ctx.params.contractAddress = _ctx.params.contractAddress.toLowerCase();
632
+ if (typeof _ctx.params.walletAddress === "string") _ctx.params.walletAddress = _ctx.params.walletAddress.toLowerCase();
916
633
  return transfers;
917
634
  },
918
635
  tests: [
919
- // APTOS
920
636
  {
921
637
  params: {
922
- network: "APTOS",
923
- walletAddress: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00",
924
- contractAddress: "0x3b5d2e7e8da86903beb19d5a7135764aac812e18af193895d75f3a8f6a066cb0"
638
+ network: "BASE",
639
+ walletAddress: "0x4F80864cD68782144e3736626896990acAe15a11",
640
+ contractAddress: "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed"
925
641
  },
926
- payload: "https://jiti.indexing.co/networks/aptos/297956660",
927
- output: [
928
- {
929
- amount: 1611839920n,
930
- blockNumber: 297956660,
931
- from: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00",
932
- to: "0x3b5d2e7e8da86903beb19d5a7135764aac812e18af193895d75f3a8f6a066cb0",
933
- timestamp: "2025-03-02T21:07:06.002Z",
934
- token: null,
935
- tokenType: "TOKEN",
936
- transactionGasFee: 13n,
937
- transactionHash: "0xfbdef795d11df124cca264f3370b09fb04fb1c1d24a2d2e1df0693c096a76d13"
938
- },
939
- {
940
- amount: 1502138836n,
941
- blockNumber: 297956660,
942
- from: "0x5bd7de5c56d5691f32ea86c973c73fec7b1445e59736c97158020018c080bb00",
943
- to: "0x04b2b6bc8c2c5794c51607c962f482593f9b5ea09373a8ce249a1f799cca7a1e",
944
- timestamp: "2025-03-02T21:07:06.002Z",
945
- token: null,
946
- tokenType: "TOKEN",
947
- transactionGasFee: 13n,
948
- transactionHash: "0xfbdef795d11df124cca264f3370b09fb04fb1c1d24a2d2e1df0693c096a76d13"
949
- }
950
- ]
951
- },
952
- // APTOS
953
- {
954
- params: {
955
- network: "APTOS",
956
- contractAddress: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b"
957
- },
958
- payload: "https://jiti.indexing.co/networks/aptos/303623631",
959
- output: [
960
- {
961
- amount: 1000060n,
962
- blockNumber: 303623631,
963
- from: "0xa4e7455d27731ab857e9701b1e6ed72591132b909fe6e4fd99b66c1d6318d9e8",
964
- timestamp: "2025-03-14T15:39:49.845Z",
965
- to: "0x9317336bfc9ba6987d40492ddea8d41e11b7c2e473f3556a9c82309d326e79ce",
966
- token: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
967
- tokenType: "TOKEN",
968
- transactionGasFee: 16n,
969
- transactionHash: "0x24b8854bad1f6543b35069eacd6ec40a583ca7fa452b422b04d747d24b65279c"
970
- }
971
- ]
972
- },
973
- // BASE
974
- {
975
- params: {
976
- network: "BASE",
977
- walletAddress: "0x4F80864cD68782144e3736626896990acAe15a11",
978
- contractAddress: "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed"
979
- },
980
- payload: "https://jiti.indexing.co/networks/base/23507423",
642
+ payload: "https://jiti.indexing.co/networks/base/23507423",
981
643
  output: [
982
644
  {
983
645
  amount: 1000000000000000000000n,
@@ -993,100 +655,73 @@ const $6144a02851f23907$var$tokenTransfersTemplate = {
993
655
  }
994
656
  ]
995
657
  },
996
- // BITTENSOR
997
- {
998
- params: {
999
- network: "BITTENSOR",
1000
- walletAddress: "5G6WmJ4mym9oSQzUF5tr7LvsNMvH5vWtutZM8vMvRv1Wwy6J",
1001
- contractAddress: ""
1002
- },
1003
- payload: "https://jiti.indexing.co/networks/bittensor/2652896",
1004
- output: [
1005
- {
1006
- amount: 2154999850n,
1007
- blockNumber: 2652896,
1008
- from: "5G6WmJ4mym9oSQzUF5tr7LvsNMvH5vWtutZM8vMvRv1Wwy6J",
1009
- to: "5CFwmfLfL1Z6vXU6hgGksh6irDFpcVXaTTNRoqDGMyHrDKK1",
1010
- token: null,
1011
- tokenType: "NATIVE",
1012
- timestamp: "2024-03-28T12:53:36.001Z",
1013
- transactionGasFee: 0n,
1014
- transactionHash: "0x9ea55a8f40b8d7704f27964155476ab9c744ec2ef2b1f431ad0e05a3a6f3c1ab"
1015
- }
1016
- ]
1017
- },
1018
- // CARDANO
1019
658
  {
1020
659
  params: {
1021
- network: "CARDANO",
1022
- walletAddress: "addr1q9syxu908lef7r6rsvk0h7gsx3rxj22cuykgx2a2l4hcfd8e9y2e9vtv4w9dyej96w99wwj8hwgc273862lk6a3vt30qjjrund",
1023
- contractAddress: ""
660
+ network: "POLYGON",
661
+ walletAddress: "0x06D8c5E25B9aD46dA43FD71571E8a12aae341570",
662
+ contractAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
1024
663
  },
1025
- payload: "https://jiti.indexing.co/networks/cardano/11443286",
664
+ payload: "https://jiti.indexing.co/networks/polygon/70623684",
1026
665
  output: [
1027
666
  {
1028
- amount: 1110000n,
1029
- blockNumber: 11443286,
1030
- from: "addr1qymdv285few5tyqvya86rl97r9e608njs37shfew6l2nn473aw2pcnrcvfwfgg2dnew99m4tjj0apsu7232w2euzwpysndh0h3",
1031
- timestamp: "+057068-01-19T05:23:20.000Z",
1032
- to: "addr1q9syxu908lef7r6rsvk0h7gsx3rxj22cuykgx2a2l4hcfd8e9y2e9vtv4w9dyej96w99wwj8hwgc273862lk6a3vt30qjjrund",
1033
- token: null,
1034
- tokenType: "NATIVE",
1035
- transactionGasFee: 174257n,
1036
- transactionHash: "261c42ba9124f55d8e169ebb692cd3759d796a54369acb316ee449b546e79309"
1037
- }
1038
- ]
1039
- },
1040
- // COSMOS
1041
- {
1042
- params: {
1043
- network: "COSMOS",
1044
- walletAddress: "cosmos1x4qvmtcfc02pklttfgxzdccxcsyzklrxavteyz",
1045
- contractAddress: "ibc/F663521BF1836B00F5F177680F74BFB9A8B5654A694D0D2BC249E03CF2509013"
1046
- },
1047
- payload: "https://jiti.indexing.co/networks/cosmos/24419691",
1048
- output: [
1049
- {
1050
- blockNumber: 24419691,
1051
- from: "cosmos1x4qvmtcfc02pklttfgxzdccxcsyzklrxavteyz",
1052
- to: "noble1x4qvmtcfc02pklttfgxzdccxcsyzklrx4073uv",
1053
- amount: 500000n,
1054
- token: "ibc/F663521BF1836B00F5F177680F74BFB9A8B5654A694D0D2BC249E03CF2509013",
1055
- tokenType: "NATIVE",
1056
- timestamp: "2025-02-14T21:48:22.809Z",
1057
- transactionHash: "963D4D7BB59C1280F58A7ECA2F1934E2AA005109A989193C815C7B98EDCD7445",
1058
- transactionGasFee: 4860n
667
+ amount: 4877821n,
668
+ blockNumber: 70623684,
669
+ from: "0xcb39c5b0db9c5b6bd1d9273dccc2f98f532a8bc6",
670
+ index: 0,
671
+ timestamp: "2025-04-22T17:51:55.000Z",
672
+ to: "0x06d8c5e25b9ad46da43fd71571e8a12aae341570",
673
+ token: "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",
674
+ tokenType: "TOKEN",
675
+ transactionGasFee: 8950898176621703n,
676
+ transactionHash: "0x5235cbe22deba5dd8a42f36024b1df1c0f82a8e901e6cc176a38e2fe49b1d2e3"
1059
677
  }
1060
678
  ]
1061
- },
1062
- // DOGECOIN
1063
- {
1064
- params: {
1065
- network: "DOGECOIN",
1066
- walletAddress: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
1067
- contractAddress: ""
1068
- },
1069
- payload: "https://jiti.indexing.co/networks/dogecoin/1000075",
1070
- output: [
1071
- {
1072
- amount: 1008521000000n,
1073
- blockNumber: 1000075,
1074
- from: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
1075
- to: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
679
+ }
680
+ ]
681
+ };
682
+
683
+
684
+ const $5a4d345db3c04a51$export$d7ac970e8e789607 = {
685
+ match: (block)=>[
686
+ "FILECOIN"
687
+ ].includes(block._network),
688
+ transform (block) {
689
+ let transfers = [];
690
+ const typedBlock = block;
691
+ const blockNumber = typedBlock.Height;
692
+ const blockTimestamp = new Date(typedBlock.Blocks[0].Timestamp * 1000).toISOString();
693
+ const parentBaseFee = BigInt(typedBlock.Blocks[0].ParentBaseFee);
694
+ let receiptIndex = 0;
695
+ for (const msgGroup of typedBlock.messages){
696
+ const secpkMessages = msgGroup.blockMessages.SecpkMessages || [];
697
+ for (const msg of secpkMessages){
698
+ const receipt = typedBlock.receipts[receiptIndex++];
699
+ const gasUsed = receipt ? BigInt(receipt.GasUsed) : BigInt(0);
700
+ const gasFeeCap = BigInt(msg.Message.GasFeeCap);
701
+ const gasPremium = BigInt(msg.Message.GasPremium);
702
+ const baseFeeBurn = gasUsed * parentBaseFee;
703
+ const minerTip = gasUsed * (gasPremium < gasFeeCap - parentBaseFee ? gasPremium : gasFeeCap - parentBaseFee);
704
+ const transactionGasFee = baseFeeBurn + minerTip;
705
+ transfers.push({
706
+ amount: BigInt(msg.Message.Value),
707
+ blockNumber: blockNumber,
708
+ from: msg.Message.From,
709
+ to: msg.Message.To,
1076
710
  token: null,
1077
711
  tokenType: "NATIVE",
1078
- transactionGasFee: 0n,
1079
- transactionHash: "9873fe46ab29f61cefdec498b691af68e0ad29a7599c94f42d2d4e9a5d461dbe",
1080
- timestamp: "2015-12-13T19:59:52.000Z"
1081
- }
1082
- ]
1083
- },
1084
- // FILECOIN
712
+ timestamp: blockTimestamp,
713
+ transactionGasFee: transactionGasFee,
714
+ transactionHash: msg.CID["/"]
715
+ });
716
+ }
717
+ }
718
+ return transfers;
719
+ },
720
+ tests: [
1085
721
  {
1086
722
  params: {
1087
723
  network: "FILECOIN",
1088
- walletAddress: "f1e3aa3z6gkaqxxwmbbna5gf2frggswwjaeavx7bq",
1089
- contractAddress: "f1bqdligg7ipuiizvmdn7ijobhbkwaieh6z6lah5y"
724
+ walletAddress: "f1e3aa3z6gkaqxxwmbbna5gf2frggswwjaeavx7bq"
1090
725
  },
1091
726
  payload: "https://jiti.indexing.co/networks/filecoin/4818438",
1092
727
  output: [
@@ -1102,8 +737,47 @@ const $6144a02851f23907$var$tokenTransfersTemplate = {
1102
737
  transactionHash: "bafy2bzacecxud3tayyq3caagjej5srufcx5fufjuqkz3ltgfty27wdsrmqeew"
1103
738
  }
1104
739
  ]
1105
- },
1106
- // RIPPLE
740
+ }
741
+ ]
742
+ };
743
+
744
+
745
+ const $2e46ec862e47c14f$export$400f08bfae9ee97f = {
746
+ match: (block)=>[
747
+ "RIPPLE"
748
+ ].includes(block._network),
749
+ transform (block) {
750
+ let transfers = [];
751
+ if (!Array.isArray(block.transactions)) return [];
752
+ for (const rawTx of block.transactions){
753
+ const typedTx = rawTx;
754
+ if (typedTx.TransactionType !== "Payment") continue;
755
+ const deliveredOrAmount = typedTx.metaData?.delivered_amount ?? typedTx.Amount ?? "0";
756
+ let tokenSymbol = "XRP";
757
+ let tokenType = "NATIVE";
758
+ let parsedAmount;
759
+ if (typeof deliveredOrAmount === "object") {
760
+ tokenSymbol = deliveredOrAmount.currency?.toUpperCase() ?? "UNKNOWN";
761
+ tokenType = "TOKEN";
762
+ const floatVal = parseFloat(deliveredOrAmount.value);
763
+ const smallestUnit = Math.round(floatVal * 1000000);
764
+ parsedAmount = BigInt(smallestUnit);
765
+ } else parsedAmount = BigInt(String(deliveredOrAmount));
766
+ transfers.push({
767
+ amount: parsedAmount,
768
+ blockNumber: parseInt(block.ledger_index, 10),
769
+ from: typedTx.Account ?? "UNKNOWN",
770
+ timestamp: block.close_time_iso ? block.close_time_iso : null,
771
+ to: typedTx.Destination ?? "UNKNOWN",
772
+ token: tokenSymbol,
773
+ tokenType: tokenType,
774
+ transactionGasFee: BigInt(typedTx.Fee ?? "0"),
775
+ transactionHash: typedTx.hash ?? ""
776
+ });
777
+ }
778
+ return transfers;
779
+ },
780
+ tests: [
1107
781
  {
1108
782
  params: {
1109
783
  network: "RIPPLE",
@@ -1124,52 +798,59 @@ const $6144a02851f23907$var$tokenTransfersTemplate = {
1124
798
  transactionHash: "03564E6109261CDE73FCC5062C2A0A70F365CB1A0F9408C065B60EC3E94E4DBF"
1125
799
  }
1126
800
  ]
1127
- },
1128
- // STELLAR
1129
- {
1130
- params: {
1131
- network: "STELLAR",
1132
- walletAddress: "GA5KLTNAWV27IOTBX5PKUOMVWFMLX4X7CPMQJ4QLR3G266MMVL7NMA4X",
1133
- contractAddress: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA"
1134
- },
1135
- payload: "https://jiti.indexing.co/networks/stellar/51720546",
1136
- output: [
1137
- {
1138
- amount: 150000n,
1139
- blockNumber: 51720546,
1140
- from: "GA5KLTNAWV27IOTBX5PKUOMVWFMLX4X7CPMQJ4QLR3G266MMVL7NMA4X",
1141
- timestamp: "2024-05-18T04:41:39Z",
1142
- to: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA",
1143
- token: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA",
1144
- tokenType: "TOKEN",
1145
- transactionGasFee: 100n,
1146
- transactionHash: "4fb2441210cbe87f5003abdfa86f03bafa54f789ed041feccbda0bd054297c4d"
801
+ }
802
+ ]
803
+ };
804
+
805
+
806
+ const $3b9b8f5747dcca8e$export$722698bc663d0ac0 = {
807
+ match: (block)=>[
808
+ "SUI"
809
+ ].includes(block._network),
810
+ transform (block) {
811
+ let transfers = [];
812
+ const blockNumber = parseInt(block.sequence, 10);
813
+ const blockTimestamp = new Date(parseInt(block.timestamp, 10)).toISOString();
814
+ const transactions = block.transactions || [];
815
+ for (const tx of transactions){
816
+ const transactionHash = tx.digest;
817
+ let transactionGasFee = BigInt(0);
818
+ if (tx.effects?.gasUsed) {
819
+ const gu = tx.effects.gasUsed;
820
+ transactionGasFee = BigInt(gu.computationCost) + BigInt(gu.storageCost) - BigInt(gu.storageRebate) + BigInt(gu.nonRefundableStorageFee);
821
+ if (transactionGasFee < 0n) transactionGasFee = 0n;
822
+ }
823
+ const balanceChanges = tx.balanceChanges || [];
824
+ for (const bc of balanceChanges){
825
+ let rawAmt = BigInt(bc.amount);
826
+ if (rawAmt === 0n) continue;
827
+ let fromAddr;
828
+ let toAddr;
829
+ const rawOwner = bc.owner?.AddressOwner || bc.owner?.ObjectOwner || bc.owner?.Shared?.initial_shared_version || "UNKNOWN_OWNER";
830
+ if (rawAmt < 0n) {
831
+ fromAddr = String(rawOwner);
832
+ toAddr = undefined;
833
+ rawAmt = -rawAmt;
834
+ } else {
835
+ fromAddr = undefined;
836
+ toAddr = String(rawOwner);
1147
837
  }
1148
- ]
1149
- },
1150
- // STARKNET
1151
- {
1152
- params: {
1153
- network: "STARKNET",
1154
- walletAddress: "0x309e6b209031362268d62d646a067365e6f6d6eb7f571b5212cbdfd5f26fe54",
1155
- contractAddress: ""
1156
- },
1157
- payload: "https://jiti.indexing.co/networks/starknet/1149460",
1158
- output: [
1159
- {
1160
- amount: 0x1c286f74458fc6n,
1161
- blockNumber: 1149460,
1162
- from: "0x309e6b209031362268d62d646a067365e6f6d6eb7f571b5212cbdfd5f26fe54",
1163
- timestamp: "2025-02-13T17:36:52.000Z",
1164
- to: "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",
1165
- token: null,
838
+ transfers.push({
839
+ blockNumber: blockNumber,
840
+ from: fromAddr,
841
+ to: toAddr,
842
+ amount: rawAmt,
843
+ token: bc.coinType,
1166
844
  tokenType: "NATIVE",
1167
- transactionGasFee: 7925758505095110n,
1168
- transactionHash: "0x707203dba31f442ae9a5477e6a8906f3676effa0f1d3bb19cbbc14e1ddfe21"
1169
- }
1170
- ]
1171
- },
1172
- // SUI
845
+ timestamp: blockTimestamp,
846
+ transactionHash: transactionHash,
847
+ transactionGasFee: transactionGasFee
848
+ });
849
+ }
850
+ }
851
+ return transfers;
852
+ },
853
+ tests: [
1173
854
  {
1174
855
  params: {
1175
856
  network: "SUI",
@@ -1223,30 +904,123 @@ const $6144a02851f23907$var$tokenTransfersTemplate = {
1223
904
  transactionGasFee: 5408192n
1224
905
  }
1225
906
  ]
1226
- },
1227
- // TON
1228
- {
1229
- params: {
1230
- network: "TON",
1231
- walletAddress: "EQAFukUyzmHjUvOYDOjNE-wbZFFl2FWas1rFJoh8IiTsWD40",
1232
- contractAddress: ""
1233
- },
1234
- payload: "https://jiti.indexing.co/networks/ton/44919328",
1235
- output: [
1236
- {
1237
- blockNumber: 44919328,
1238
- from: "EQAFukUyzmHjUvOYDOjNE-wbZFFl2FWas1rFJoh8IiTsWD40",
1239
- to: "EQCFTFAHOU3vFt2NiZhRD5dwuS0k7GS59vIg3WfCKwfaQGW2",
1240
- amount: 10000000n,
1241
- token: "TON",
1242
- tokenType: "NATIVE",
1243
- timestamp: "2025-02-13T23:10:18.000Z",
1244
- transactionHash: "Vh5cWr2uvCsdhoouBQ+EiUcF54os9oqvh8A/62EroQc=",
1245
- transactionGasFee: 2355233n
907
+ }
908
+ ]
909
+ };
910
+
911
+
912
+ const $290fd8bc430da9f0$export$1f0fe79deb1b813b = {
913
+ match: (block)=>[
914
+ "SOLANA"
915
+ ].includes(block._network),
916
+ transform (block) {
917
+ let transfers = [];
918
+ for (const tx of block.transactions){
919
+ const solanaTx = tx;
920
+ const txHash = solanaTx.transaction.signatures[0];
921
+ const timestamp = block.blockTime ? new Date(block.blockTime * 1000).toISOString() : null;
922
+ const allAccounts = solanaTx.transaction.message.accountKeys.concat(solanaTx.meta.loadedAddresses.writable).concat(solanaTx.meta.loadedAddresses.readonly);
923
+ let txFee = BigInt(solanaTx.meta.fee);
924
+ if (txFee < BigInt(10)) txFee = txFee * BigInt(Math.pow(10, 9));
925
+ const transfersByKey = {};
926
+ for (const post of solanaTx.meta.postTokenBalances){
927
+ let matched = false;
928
+ for (const pre of solanaTx.meta.preTokenBalances)if (post.mint === pre.mint && post.owner === pre.owner) {
929
+ let diff = BigInt(post.uiTokenAmount.amount) - BigInt(pre.uiTokenAmount.amount);
930
+ if (diff === BigInt(0)) {
931
+ matched = true;
932
+ continue;
933
+ }
934
+ const isNegDiff = diff < 0;
935
+ if (diff < 0) diff = -diff;
936
+ const key = `${post.mint}-${diff.toString()}`;
937
+ const txfer = {
938
+ amount: diff,
939
+ blockNumber: block.blockHeight,
940
+ from: pre.owner,
941
+ timestamp: timestamp,
942
+ to: post.owner,
943
+ transactionGasFee: txFee,
944
+ transactionHash: txHash,
945
+ token: post.mint,
946
+ tokenType: "TOKEN"
947
+ };
948
+ if (isNegDiff) delete txfer.to;
949
+ else delete txfer.from;
950
+ transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
951
+ matched = true;
1246
952
  }
1247
- ]
1248
- },
1249
- // SOLANA
953
+ if (!matched) {
954
+ let diff = BigInt(post.uiTokenAmount.amount);
955
+ const isNegDiff = diff < 0;
956
+ if (diff < 0) diff = -diff;
957
+ const key = `${post.mint}-${diff.toString()}`;
958
+ const txfer = {
959
+ amount: diff,
960
+ blockNumber: block.blockHeight,
961
+ from: null,
962
+ timestamp: timestamp,
963
+ to: post.owner,
964
+ token: post.mint,
965
+ tokenType: "TOKEN",
966
+ transactionGasFee: txFee,
967
+ transactionHash: txHash
968
+ };
969
+ if (isNegDiff) delete txfer.to;
970
+ else delete txfer.from;
971
+ transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
972
+ }
973
+ }
974
+ for(let i = 1; i < solanaTx.meta.postBalances.length; i += 1){
975
+ const post = solanaTx.meta.postBalances[i];
976
+ const pre = solanaTx.meta.preBalances[i];
977
+ if (post !== undefined && pre !== undefined && post !== pre) {
978
+ let diff = BigInt(post) - BigInt(pre);
979
+ if (diff < 0) diff = -diff;
980
+ const key = `null-${diff.toString()}`;
981
+ const txfer = {
982
+ amount: diff,
983
+ blockNumber: block.blockHeight,
984
+ from: post > pre ? typeof allAccounts[0] === "string" ? allAccounts[0] : allAccounts[0]?.pubkey : typeof allAccounts[i] === "string" ? allAccounts[i] : allAccounts[i]?.pubkey,
985
+ timestamp: timestamp,
986
+ to: typeof allAccounts[i] === "string" ? allAccounts[i] : allAccounts[i]?.pubkey?.toString(),
987
+ token: null,
988
+ tokenType: "NATIVE",
989
+ transactionGasFee: txFee,
990
+ transactionHash: txHash
991
+ };
992
+ if (post > pre) {
993
+ if (transfersByKey[key]) delete txfer.from;
994
+ } else delete txfer.to;
995
+ transfersByKey[key] = Object.assign(transfersByKey[key] || {}, txfer);
996
+ }
997
+ }
998
+ const unmatchedFrom = {};
999
+ const unmatchedTo = {};
1000
+ for(const key in transfersByKey){
1001
+ const txfer = transfersByKey[key];
1002
+ if (!txfer.from) {
1003
+ if (!unmatchedFrom[txfer.token]) unmatchedFrom[txfer.token] = [];
1004
+ unmatchedFrom[txfer.token].push(txfer);
1005
+ delete transfersByKey[key];
1006
+ } else if (!txfer.to) {
1007
+ if (!unmatchedTo[txfer.token]) unmatchedTo[txfer.token] = [];
1008
+ unmatchedTo[txfer.token].push(txfer);
1009
+ delete transfersByKey[key];
1010
+ }
1011
+ }
1012
+ for(const token in unmatchedFrom)if (unmatchedTo[token]?.length && unmatchedTo[token].reduce((a, b)=>a + BigInt(b.amount), BigInt(0)) - unmatchedFrom[token].reduce((a, b)=>a + BigInt(b.amount), BigInt(0)) === BigInt(0)) {
1013
+ unmatchedTo[token].sort((a, b)=>a.amount > b.amount ? 1 : -1);
1014
+ unmatchedFrom[token].forEach((um)=>{
1015
+ um.from = unmatchedTo[token][0].from;
1016
+ transfersByKey[`${token}-${um.amount.toString()}`] = um;
1017
+ });
1018
+ }
1019
+ transfers.push(...Object.values(transfersByKey));
1020
+ }
1021
+ return transfers;
1022
+ },
1023
+ tests: [
1250
1024
  {
1251
1025
  params: {
1252
1026
  network: "SOLANA",
@@ -1362,15 +1136,436 @@ const $6144a02851f23907$var$tokenTransfersTemplate = {
1362
1136
  from: "4acL7mD2J6GYJy2g3iVTvfpmHCQSZ1rb8DBuupjcVzHJ"
1363
1137
  }
1364
1138
  ]
1139
+ },
1140
+ {
1141
+ params: {
1142
+ network: "SOLANA",
1143
+ walletAddress: "J1dHwpKBs8Jo4n7jWEJWwMGNH2DJQnApBFPnnYXg74v7",
1144
+ contractAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
1145
+ },
1146
+ payload: "https://jiti.indexing.co/networks/solana/332822080",
1147
+ output: [
1148
+ {
1149
+ amount: 2500000n,
1150
+ blockNumber: 311062104,
1151
+ from: "J1dHwpKBs8Jo4n7jWEJWwMGNH2DJQnApBFPnnYXg74v7",
1152
+ timestamp: "2025-04-11T19:36:39.000Z",
1153
+ to: "3LoAYHuSd7Gh8d7RTFnhvYtiTiefdZ5ByamU42vkzd76",
1154
+ token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1155
+ tokenType: "TOKEN",
1156
+ transactionGasFee: 350362n,
1157
+ transactionHash: "xKTWvnhSRErcHCMozRMEue4MriNr1Any6LiaQzXrR7imZ1MpZxRqbyv9LLg4JQoDq4oJZpDqPmzxLCtMCkgj2hn"
1158
+ },
1159
+ {
1160
+ amount: 1373625000n,
1161
+ blockNumber: 311062104,
1162
+ from: "J1dHwpKBs8Jo4n7jWEJWwMGNH2DJQnApBFPnnYXg74v7",
1163
+ timestamp: "2025-04-11T19:36:39.000Z",
1164
+ to: "5guD4Uz462GT4Y4gEuqyGsHZ59JGxFN4a3rF6KWguMcJ",
1165
+ token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1166
+ tokenType: "TOKEN",
1167
+ transactionGasFee: 350362n,
1168
+ transactionHash: "xKTWvnhSRErcHCMozRMEue4MriNr1Any6LiaQzXrR7imZ1MpZxRqbyv9LLg4JQoDq4oJZpDqPmzxLCtMCkgj2hn"
1169
+ },
1170
+ {
1171
+ amount: 1123875000n,
1172
+ blockNumber: 311062104,
1173
+ from: "J1dHwpKBs8Jo4n7jWEJWwMGNH2DJQnApBFPnnYXg74v7",
1174
+ timestamp: "2025-04-11T19:36:39.000Z",
1175
+ to: "DH4xmaWDnTzKXehVaPSNy9tMKJxnYL5Mo5U3oTHFtNYJ",
1176
+ token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1177
+ tokenType: "TOKEN",
1178
+ transactionGasFee: 350362n,
1179
+ transactionHash: "xKTWvnhSRErcHCMozRMEue4MriNr1Any6LiaQzXrR7imZ1MpZxRqbyv9LLg4JQoDq4oJZpDqPmzxLCtMCkgj2hn"
1180
+ }
1181
+ ]
1182
+ }
1183
+ ]
1184
+ };
1185
+
1186
+
1187
+ const $fc745f3cb8eb3f52$export$36783fc9701281c6 = {
1188
+ match: (block)=>[
1189
+ "STARKNET"
1190
+ ].includes(block._network),
1191
+ transform (block) {
1192
+ let transfers = [];
1193
+ if (!Array.isArray(block.transactions)) return [];
1194
+ for (const tx of block.transactions){
1195
+ const typedTx = tx;
1196
+ const timestamp = block.timestamp ? new Date(block.timestamp * 1000).toISOString() : null;
1197
+ let transactionGasFee = BigInt(0);
1198
+ if (typedTx?.receipt?.actual_fee?.amount) transactionGasFee = BigInt(typedTx.receipt.actual_fee.amount);
1199
+ const transactionHash = typedTx.transaction_hash;
1200
+ if (!typedTx.receipt?.events) continue;
1201
+ for (const event of typedTx.receipt.events){
1202
+ if (!event.keys.includes("0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9")) continue;
1203
+ if (event.data.length < 3) continue;
1204
+ const [from, to, amountHex] = event.data;
1205
+ const amount = BigInt(amountHex);
1206
+ transfers.push({
1207
+ amount: amount,
1208
+ blockNumber: block.block_number,
1209
+ from: from,
1210
+ timestamp: timestamp,
1211
+ to: to,
1212
+ token: null,
1213
+ tokenType: "NATIVE",
1214
+ transactionGasFee: transactionGasFee,
1215
+ transactionHash: transactionHash
1216
+ });
1217
+ }
1218
+ }
1219
+ return transfers;
1220
+ },
1221
+ tests: [
1222
+ {
1223
+ params: {
1224
+ network: "STARKNET",
1225
+ walletAddress: "0x309e6b209031362268d62d646a067365e6f6d6eb7f571b5212cbdfd5f26fe54",
1226
+ contractAddress: ""
1227
+ },
1228
+ payload: "https://jiti.indexing.co/networks/starknet/1149460",
1229
+ output: [
1230
+ {
1231
+ amount: 0x1c286f74458fc6n,
1232
+ blockNumber: 1149460,
1233
+ from: "0x309e6b209031362268d62d646a067365e6f6d6eb7f571b5212cbdfd5f26fe54",
1234
+ timestamp: "2025-02-13T17:36:52.000Z",
1235
+ to: "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",
1236
+ token: null,
1237
+ tokenType: "NATIVE",
1238
+ transactionGasFee: 7925758505095110n,
1239
+ transactionHash: "0x707203dba31f442ae9a5477e6a8906f3676effa0f1d3bb19cbbc14e1ddfe21"
1240
+ }
1241
+ ]
1242
+ }
1243
+ ]
1244
+ };
1245
+
1246
+
1247
+ const $3478cd776d185339$export$681f497010b17679 = {
1248
+ match: (block)=>[
1249
+ "STELLAR"
1250
+ ].includes(block._network),
1251
+ transform (block) {
1252
+ let transfers = [];
1253
+ for (const tx of block.transactions){
1254
+ const typedTx = tx;
1255
+ for (const op of typedTx.operations)if (op.type === "payment") transfers.push({
1256
+ amount: BigInt(op.amount.replace(".", "")),
1257
+ blockNumber: block.sequence,
1258
+ from: op.from,
1259
+ timestamp: typedTx.created_at,
1260
+ to: op.to,
1261
+ token: op.asset_type === "native" ? null : op.asset_issuer,
1262
+ tokenType: op.asset_type === "native" ? "NATIVE" : "TOKEN",
1263
+ transactionGasFee: BigInt(typedTx.fee_charged),
1264
+ transactionHash: typedTx.hash
1265
+ });
1266
+ }
1267
+ return transfers;
1268
+ },
1269
+ tests: [
1270
+ {
1271
+ params: {
1272
+ network: "STELLAR",
1273
+ walletAddress: "GA5KLTNAWV27IOTBX5PKUOMVWFMLX4X7CPMQJ4QLR3G266MMVL7NMA4X",
1274
+ contractAddress: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA"
1275
+ },
1276
+ payload: "https://jiti.indexing.co/networks/stellar/51720546",
1277
+ output: [
1278
+ {
1279
+ amount: 150000n,
1280
+ blockNumber: 51720546,
1281
+ from: "GA5KLTNAWV27IOTBX5PKUOMVWFMLX4X7CPMQJ4QLR3G266MMVL7NMA4X",
1282
+ timestamp: "2024-05-18T04:41:39Z",
1283
+ to: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA",
1284
+ token: "GC4Z2TDXU4GXVLHOS5P5SU6HKBCP7NKN4TJ5ZGTVRBW7MCBZTU7SNUSA",
1285
+ tokenType: "TOKEN",
1286
+ transactionGasFee: 100n,
1287
+ transactionHash: "4fb2441210cbe87f5003abdfa86f03bafa54f789ed041feccbda0bd054297c4d"
1288
+ }
1289
+ ]
1290
+ }
1291
+ ]
1292
+ };
1293
+
1294
+
1295
+ const $11a2c5b0fd56c033$export$bc6c7ab7e0727dd7 = {
1296
+ match: (block)=>[
1297
+ "ASTAR",
1298
+ "ENJIN",
1299
+ "KUSAMA",
1300
+ "POLKADOT",
1301
+ "BITTENSOR"
1302
+ ].includes(block._network),
1303
+ transform (block) {
1304
+ let transfers = [];
1305
+ const typedBlock = block;
1306
+ const blockNumber = typedBlock.blockNumber;
1307
+ const timestampExtrinsic = typedBlock.extrinsics.find((ex)=>ex.method === "timestamp.set");
1308
+ const blockTimestamp = timestampExtrinsic ? new Date(Number(timestampExtrinsic.args[0].toString().replace(/,/g, ""))).toISOString() : new Date().toISOString();
1309
+ for (const extrinsic of typedBlock.extrinsics)if ([
1310
+ "balances.transfer",
1311
+ "balances.transferKeepAlive"
1312
+ ].includes(extrinsic.method)) {
1313
+ const from = extrinsic.signer;
1314
+ const to = extrinsic.args[0]?.Id || "";
1315
+ const amount = BigInt(extrinsic.args[1].replace(/,/g, ""));
1316
+ transfers.push({
1317
+ amount: amount,
1318
+ blockNumber: blockNumber,
1319
+ from: from,
1320
+ to: to,
1321
+ token: null,
1322
+ tokenType: "NATIVE",
1323
+ timestamp: blockTimestamp,
1324
+ transactionGasFee: 0n,
1325
+ transactionHash: extrinsic.hash
1326
+ });
1327
+ }
1328
+ return transfers;
1329
+ },
1330
+ tests: [
1331
+ {
1332
+ params: {
1333
+ network: "BITTENSOR",
1334
+ walletAddress: "5G6WmJ4mym9oSQzUF5tr7LvsNMvH5vWtutZM8vMvRv1Wwy6J",
1335
+ contractAddress: ""
1336
+ },
1337
+ payload: "https://jiti.indexing.co/networks/bittensor/2652896",
1338
+ output: [
1339
+ {
1340
+ amount: 2154999850n,
1341
+ blockNumber: 2652896,
1342
+ from: "5G6WmJ4mym9oSQzUF5tr7LvsNMvH5vWtutZM8vMvRv1Wwy6J",
1343
+ to: "5CFwmfLfL1Z6vXU6hgGksh6irDFpcVXaTTNRoqDGMyHrDKK1",
1344
+ token: null,
1345
+ tokenType: "NATIVE",
1346
+ timestamp: "2024-03-28T12:53:36.001Z",
1347
+ transactionGasFee: 0n,
1348
+ transactionHash: "0x9ea55a8f40b8d7704f27964155476ab9c744ec2ef2b1f431ad0e05a3a6f3c1ab"
1349
+ }
1350
+ ]
1351
+ }
1352
+ ]
1353
+ };
1354
+
1355
+
1356
+ const $cd430dd11c31e572$export$608f3f42810b9879 = {
1357
+ match: (block)=>[
1358
+ "TON"
1359
+ ].includes(block._network),
1360
+ transform (block) {
1361
+ let transfers = [];
1362
+ const blockNumber = block.seqno;
1363
+ const blockTimestamp = new Date(block.shards?.[0]?.gen_utime * 1000).toISOString();
1364
+ for (const shard of block.shards || [])for (const tx of shard.transactions || []){
1365
+ const transactionLT = tx.transaction_id.lt;
1366
+ const transactionHash = tx.transaction_id.hash;
1367
+ const transactionFee = BigInt(tx.fee || "0");
1368
+ const inVal = BigInt(tx.in_msg?.value || "0");
1369
+ if (inVal > 0n) transfers.push({
1370
+ blockNumber: blockNumber,
1371
+ from: tx.in_msg?.source?.account_address,
1372
+ to: tx.address?.account_address,
1373
+ amount: inVal,
1374
+ token: "TON",
1375
+ tokenType: "NATIVE",
1376
+ timestamp: blockTimestamp,
1377
+ transactionHash: transactionHash,
1378
+ transactionGasFee: transactionFee
1379
+ });
1380
+ for (const outMsg of tx.out_msgs || []){
1381
+ const outVal = BigInt(outMsg.value || "0");
1382
+ if (outVal > 0n) transfers.push({
1383
+ blockNumber: blockNumber,
1384
+ from: outMsg.source?.account_address,
1385
+ to: outMsg.destination?.account_address,
1386
+ amount: outVal,
1387
+ token: "TON",
1388
+ tokenType: "NATIVE",
1389
+ timestamp: blockTimestamp,
1390
+ transactionHash: transactionHash,
1391
+ transactionGasFee: transactionFee
1392
+ });
1393
+ }
1394
+ }
1395
+ return transfers;
1396
+ },
1397
+ tests: [
1398
+ {
1399
+ params: {
1400
+ network: "TON",
1401
+ walletAddress: "EQAFukUyzmHjUvOYDOjNE-wbZFFl2FWas1rFJoh8IiTsWD40",
1402
+ contractAddress: ""
1403
+ },
1404
+ payload: "https://jiti.indexing.co/networks/ton/44919328",
1405
+ output: [
1406
+ {
1407
+ blockNumber: 44919328,
1408
+ from: "EQAFukUyzmHjUvOYDOjNE-wbZFFl2FWas1rFJoh8IiTsWD40",
1409
+ to: "EQCFTFAHOU3vFt2NiZhRD5dwuS0k7GS59vIg3WfCKwfaQGW2",
1410
+ amount: 10000000n,
1411
+ token: "TON",
1412
+ tokenType: "NATIVE",
1413
+ timestamp: "2025-02-13T23:10:18.000Z",
1414
+ transactionHash: "Vh5cWr2uvCsdhoouBQ+EiUcF54os9oqvh8A/62EroQc=",
1415
+ transactionGasFee: 2355233n
1416
+ }
1417
+ ]
1365
1418
  }
1366
1419
  ]
1367
1420
  };
1368
- var $6144a02851f23907$export$2e2bcd8739ae039 = $6144a02851f23907$var$tokenTransfersTemplate;
1421
+
1422
+
1423
+ const $990c4f660694d8bc$export$4f5322cf4718bd30 = {
1424
+ match: (block)=>[
1425
+ "BITCOIN",
1426
+ "BITCOIN_TESTNET",
1427
+ "LITECOIN",
1428
+ "DOGECOIN"
1429
+ ].includes(block._network),
1430
+ transform (block) {
1431
+ let transfers = [];
1432
+ const timestamp = block.time ? new Date(block.time * 1000).toISOString() : null;
1433
+ for (const tx of block.tx){
1434
+ const vin = tx.vin[0];
1435
+ const vout = tx.vout;
1436
+ const fromVout = Math.min(vin.vout || 1000, vout.length - 1);
1437
+ const fromAddress = vin.prevout?.scriptPubKey?.address || vout[fromVout]?.scriptPubKey?.address || vout[fromVout]?.scriptPubKey?.addresses?.[0];
1438
+ if (!fromAddress) continue;
1439
+ for (const v of vout)transfers.push({
1440
+ amount: BigInt(Math.round(v.value * Math.pow(10, 8))),
1441
+ blockNumber: block.height,
1442
+ from: fromAddress,
1443
+ timestamp: timestamp,
1444
+ to: v.scriptPubKey.address || v.scriptPubKey.addresses?.[0],
1445
+ transactionGasFee: BigInt(Math.round((tx.fee || 0) * Math.pow(10, 8))),
1446
+ transactionHash: tx.txid,
1447
+ token: null,
1448
+ tokenType: "NATIVE"
1449
+ });
1450
+ }
1451
+ return transfers;
1452
+ },
1453
+ tests: [
1454
+ {
1455
+ params: {
1456
+ network: "DOGECOIN",
1457
+ walletAddress: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
1458
+ contractAddress: ""
1459
+ },
1460
+ payload: "https://jiti.indexing.co/networks/dogecoin/1000075",
1461
+ output: [
1462
+ {
1463
+ amount: 1008521000000n,
1464
+ blockNumber: 1000075,
1465
+ from: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
1466
+ to: "DMqRVLrhbam3Kcfddpxd6EYvEBbpi3bEpP",
1467
+ token: null,
1468
+ tokenType: "NATIVE",
1469
+ transactionGasFee: 0n,
1470
+ transactionHash: "9873fe46ab29f61cefdec498b691af68e0ad29a7599c94f42d2d4e9a5d461dbe",
1471
+ timestamp: "2015-12-13T19:59:52.000Z"
1472
+ }
1473
+ ]
1474
+ }
1475
+ ]
1476
+ };
1477
+
1478
+
1479
+ const $7dd402f6ad0dab6a$var$SUB_TEMPLATES = [
1480
+ (0, $25d5bdd23cba31eb$export$ace043a4f2efe476),
1481
+ (0, $60d24c82dc5feb2e$export$893111d8d332e195),
1482
+ (0, $5a4d345db3c04a51$export$d7ac970e8e789607),
1483
+ (0, $2e46ec862e47c14f$export$400f08bfae9ee97f),
1484
+ (0, $290fd8bc430da9f0$export$1f0fe79deb1b813b),
1485
+ (0, $fc745f3cb8eb3f52$export$36783fc9701281c6),
1486
+ (0, $3478cd776d185339$export$681f497010b17679),
1487
+ (0, $11a2c5b0fd56c033$export$bc6c7ab7e0727dd7),
1488
+ (0, $3b9b8f5747dcca8e$export$722698bc663d0ac0),
1489
+ (0, $cd430dd11c31e572$export$608f3f42810b9879),
1490
+ (0, $990c4f660694d8bc$export$4f5322cf4718bd30)
1491
+ ];
1492
+ const $7dd402f6ad0dab6a$var$UNIVERSAL_SUB_TEMPLATES = [
1493
+ (0, $f9ab50a3e879ac1c$export$b5fd4920e8b7d913),
1494
+ (0, $8deaea1ef39b6485$export$5beebc5708fabf3c)
1495
+ ];
1496
+ const $7dd402f6ad0dab6a$var$tokenTransfersTemplate = {
1497
+ key: "token_transfers",
1498
+ name: "Token Transfers",
1499
+ description: "Get all token transfers for a set of token types.",
1500
+ tags: [
1501
+ "EVM",
1502
+ "ERC20",
1503
+ "ERC721",
1504
+ "NFT",
1505
+ "TOKEN"
1506
+ ],
1507
+ disabled: false,
1508
+ params: [
1509
+ {
1510
+ key: "network",
1511
+ name: "Network",
1512
+ type: "NETWORK",
1513
+ optional: false
1514
+ },
1515
+ {
1516
+ key: "contractAddress",
1517
+ name: "Contract Address",
1518
+ type: "ADDRESS",
1519
+ optional: true
1520
+ },
1521
+ {
1522
+ key: "walletAddress",
1523
+ name: "Wallet Address",
1524
+ type: "ADDRESS",
1525
+ optional: true
1526
+ },
1527
+ {
1528
+ key: "tokenTypes",
1529
+ name: "Token Types",
1530
+ type: "STRING",
1531
+ multiple: true,
1532
+ optional: true,
1533
+ values: [
1534
+ "NATIVE",
1535
+ "TOKEN",
1536
+ "NFT"
1537
+ ]
1538
+ }
1539
+ ],
1540
+ transform: (block, _ctx)=>{
1541
+ let transfers = [];
1542
+ for (const sub of $7dd402f6ad0dab6a$var$SUB_TEMPLATES.concat($7dd402f6ad0dab6a$var$UNIVERSAL_SUB_TEMPLATES))if (sub.match(block)) {
1543
+ transfers = sub.transform(block, _ctx);
1544
+ break;
1545
+ }
1546
+ const seenTransfers = new Set();
1547
+ transfers = transfers.filter((txfer)=>{
1548
+ if (txfer.amount <= BigInt(0)) return false;
1549
+ if (_ctx.params.contractAddress && _ctx.params.contractAddress !== txfer.token) return false;
1550
+ if (_ctx.params.walletAddress && ![
1551
+ txfer.from,
1552
+ txfer.to
1553
+ ].includes(_ctx.params.walletAddress)) return false;
1554
+ const key = `${txfer.transactionHash}-${txfer.from}-${txfer.to}-${txfer.amount}-${txfer.token}`;
1555
+ if (seenTransfers.has(key)) return false;
1556
+ seenTransfers.add(key);
1557
+ return true;
1558
+ });
1559
+ return transfers;
1560
+ },
1561
+ tests: $7dd402f6ad0dab6a$var$SUB_TEMPLATES.concat($7dd402f6ad0dab6a$var$UNIVERSAL_SUB_TEMPLATES).map((v)=>v.tests).flat()
1562
+ };
1563
+ var $7dd402f6ad0dab6a$export$2e2bcd8739ae039 = $7dd402f6ad0dab6a$var$tokenTransfersTemplate;
1369
1564
 
1370
1565
 
1371
1566
  const $48f9879a44dd1195$export$a8fc3402335b0b04 = [
1372
1567
  (0, $59fb8e0333a5d25f$export$2e2bcd8739ae039),
1373
- (0, $6144a02851f23907$export$2e2bcd8739ae039)
1568
+ (0, $7dd402f6ad0dab6a$export$2e2bcd8739ae039)
1374
1569
  ];
1375
1570
 
1376
1571