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