tx-indexer 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,18 @@ console.log(tx.classification.sender); // sender address
37
37
  console.log(tx.classification.receiver); // receiver address
38
38
  ```
39
39
 
40
+ ## RPC Compatibility
41
+
42
+ The SDK works with any Solana RPC for core features (transactions, balances, classification).
43
+
44
+ NFT metadata enrichment requires a DAS-compatible RPC (Helius, Triton, etc.). If using a standard RPC, disable it:
45
+
46
+ ```typescript
47
+ const txs = await indexer.getTransactions(address, {
48
+ enrichNftMetadata: false
49
+ });
50
+ ```
51
+
40
52
  ## Transaction Types
41
53
 
42
54
  - `transfer` - Wallet-to-wallet transfers
package/dist/client.js CHANGED
@@ -876,7 +876,7 @@ var SwapClassifier = class {
876
876
  name = "swap";
877
877
  priority = 80;
878
878
  classify(context) {
879
- const { legs, tx } = context;
879
+ const { legs, tx, walletAddress } = context;
880
880
  const feeLeg = legs.find(
881
881
  (leg) => leg.role === "fee" && leg.side === "debit"
882
882
  );
@@ -885,28 +885,45 @@ var SwapClassifier = class {
885
885
  return null;
886
886
  }
887
887
  const initiatorAccountId = `external:${initiator}`;
888
- const tokensOut = legs.filter(
888
+ const initiatorTokensOut = legs.filter(
889
889
  (leg) => leg.accountId === initiatorAccountId && leg.side === "debit" && (leg.role === "sent" || leg.role === "protocol_deposit")
890
890
  );
891
- const tokensIn = legs.filter(
891
+ const initiatorTokensIn = legs.filter(
892
892
  (leg) => leg.accountId === initiatorAccountId && leg.side === "credit" && (leg.role === "received" || leg.role === "protocol_withdraw")
893
893
  );
894
- if (tokensOut.length === 0 || tokensIn.length === 0) {
894
+ if (initiatorTokensOut.length === 0 || initiatorTokensIn.length === 0) {
895
895
  return null;
896
896
  }
897
- const tokenOut = tokensOut[0];
898
- const tokenIn = tokensIn[0];
899
- if (tokenOut.amount.token.symbol === tokenIn.amount.token.symbol) {
897
+ const initiatorOut = initiatorTokensOut[0];
898
+ const initiatorIn = initiatorTokensIn[0];
899
+ if (initiatorOut.amount.token.symbol === initiatorIn.amount.token.symbol) {
900
900
  return null;
901
901
  }
902
+ let tokenOut = initiatorOut;
903
+ let tokenIn = initiatorIn;
904
+ let perspectiveWallet = initiator;
905
+ if (walletAddress) {
906
+ const walletAccountId = `external:${walletAddress}`;
907
+ const walletOut = legs.find(
908
+ (leg) => leg.accountId === walletAccountId && leg.side === "debit" && (leg.role === "sent" || leg.role === "protocol_deposit")
909
+ );
910
+ const walletIn = legs.find(
911
+ (leg) => leg.accountId === walletAccountId && leg.side === "credit" && (leg.role === "received" || leg.role === "protocol_withdraw")
912
+ );
913
+ if (walletOut && walletIn && walletOut.amount.token.symbol !== walletIn.amount.token.symbol) {
914
+ tokenOut = walletOut;
915
+ tokenIn = walletIn;
916
+ perspectiveWallet = walletAddress;
917
+ }
918
+ }
902
919
  const hasDexProtocol = isDexProtocolById(tx.protocol?.id);
903
920
  const confidence = hasDexProtocol ? 0.95 : 0.75;
904
921
  return {
905
922
  primaryType: "swap",
906
923
  primaryAmount: tokenOut.amount,
907
924
  secondaryAmount: tokenIn.amount,
908
- sender: initiator,
909
- receiver: initiator,
925
+ sender: perspectiveWallet,
926
+ receiver: perspectiveWallet,
910
927
  counterparty: null,
911
928
  confidence,
912
929
  isRelevant: true,
@@ -1248,8 +1265,8 @@ var ClassificationService = class {
1248
1265
  this.classifiers.push(classifier);
1249
1266
  this.classifiers.sort((a, b) => b.priority - a.priority);
1250
1267
  }
1251
- classify(legs, tx) {
1252
- const context = { legs, tx };
1268
+ classify(legs, tx, walletAddress) {
1269
+ const context = { legs, tx, walletAddress };
1253
1270
  for (const classifier of this.classifiers) {
1254
1271
  const result = classifier.classify(context);
1255
1272
  if (result && result.isRelevant) {
@@ -1270,8 +1287,8 @@ var ClassificationService = class {
1270
1287
  }
1271
1288
  };
1272
1289
  var classificationService = new ClassificationService();
1273
- function classifyTransaction(legs, tx) {
1274
- return classificationService.classify(legs, tx);
1290
+ function classifyTransaction(legs, tx, walletAddress) {
1291
+ return classificationService.classify(legs, tx, walletAddress);
1275
1292
  }
1276
1293
 
1277
1294
  // ../domain/src/tx/spam-filter.ts
@@ -1448,10 +1465,11 @@ function createIndexer(options) {
1448
1465
  client.rpc,
1449
1466
  signatureObjects
1450
1467
  );
1468
+ const walletAddressStr2 = walletAddress.toString();
1451
1469
  const classified = transactions.map((tx) => {
1452
1470
  tx.protocol = detectProtocol(tx.programIds);
1453
1471
  const legs = transactionToLegs(tx);
1454
- const classification = classifyTransaction(legs, tx);
1472
+ const classification = classifyTransaction(legs, tx, walletAddressStr2);
1455
1473
  return { tx, classification, legs };
1456
1474
  });
1457
1475
  return enrichBatch(classified);
@@ -1460,6 +1478,7 @@ function createIndexer(options) {
1460
1478
  let currentBefore = before;
1461
1479
  const MAX_ITERATIONS = 10;
1462
1480
  let iteration = 0;
1481
+ const walletAddressStr = walletAddress.toString();
1463
1482
  while (accumulated.length < limit && iteration < MAX_ITERATIONS) {
1464
1483
  iteration++;
1465
1484
  const batchSize = iteration === 1 ? limit : limit * 2;
@@ -1481,7 +1500,7 @@ function createIndexer(options) {
1481
1500
  const classified = transactions.map((tx) => {
1482
1501
  tx.protocol = detectProtocol(tx.programIds);
1483
1502
  const legs = transactionToLegs(tx);
1484
- const classification = classifyTransaction(legs, tx);
1503
+ const classification = classifyTransaction(legs, tx, walletAddressStr);
1485
1504
  return { tx, classification, legs };
1486
1505
  });
1487
1506
  const nonSpam = filterSpamTransactions(classified, spamConfig);