tx-indexer 0.3.0 → 0.4.0
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/{classification.types-w82k4B1F.d.ts → classification.types-DlJe6bDZ.d.ts} +2 -6
- package/dist/{client-BS9KUBU7.d.ts → client-yGDWPKKf.d.ts} +6 -81
- package/dist/client.d.ts +2 -2
- package/dist/client.js +395 -255
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.js +395 -255
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../solana/src/rpc/client.ts","../../domain/src/money/token-registry.ts","../../solana/src/fetcher/balances.ts","../../solana/src/mappers/transaction-mapper.ts","../../solana/src/constants/program-ids.ts","../../../node_modules/.bun/base-x@5.0.1/node_modules/base-x/src/esm/index.js","../../../node_modules/.bun/bs58@6.0.0/node_modules/bs58/src/esm/index.js","../../solana/src/mappers/memo-parser.ts","../../solana/src/fetcher/transactions.ts","../../domain/src/tx/account-id.ts","../../solana/src/mappers/balance-parser.ts","../../solana/src/constants/protocol-constants.ts","../../solana/src/mappers/transaction-to-legs.ts","../../classification/src/classifiers/transfer-classifier.ts","../../classification/src/protocols/detector.ts","../../classification/src/classifiers/swap-classifier.ts","../../classification/src/classifiers/airdrop-classifier.ts","../../classification/src/classifiers/fee-only-classifier.ts","../../classification/src/classifiers/solana-pay-classifier.ts","../../classification/src/engine/classification-service.ts","../../domain/src/tx/spam-filter.ts","../src/client.ts","../../domain/src/tx/leg-validation.ts"],"names":["address","ALPHABET","esm_default","signature","DEX_PROTOCOL_IDS","primaryAmount","options"],"mappings":"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","file":"index.js","sourcesContent":["import {\n createSolanaRpc,\n createSolanaRpcSubscriptions,\n type Rpc,\n type RpcSubscriptions,\n type GetBalanceApi,\n type GetTokenAccountsByOwnerApi,\n type GetSignaturesForAddressApi,\n type GetTransactionApi,\n address,\n type Address,\n signature,\n type Signature,\n} from \"@solana/kit\";\n\n/**\n * Union type of all RPC APIs used by the transaction indexer.\n * \n * This ensures type safety when calling RPC methods while maintaining\n * flexibility for the complete indexer API surface.\n */\nexport type IndexerRpcApi = GetBalanceApi \n & GetTokenAccountsByOwnerApi \n & GetSignaturesForAddressApi \n & GetTransactionApi;\n\nexport interface SolanaClient {\n rpc: Rpc<IndexerRpcApi>;\n rpcSubscriptions: RpcSubscriptions<any>;\n}\n\n/**\n * Creates a Solana RPC client with both regular RPC and WebSocket subscriptions.\n * \n * @param rpcUrl - HTTP RPC endpoint URL\n * @param wsUrl - Optional WebSocket URL (defaults to rpcUrl with wss:// protocol)\n */\nexport function createSolanaClient(\n rpcUrl: string,\n wsUrl?: string\n): SolanaClient {\n const rpc = createSolanaRpc(rpcUrl);\n const rpcSubscriptions = wsUrl\n ? createSolanaRpcSubscriptions(wsUrl)\n : createSolanaRpcSubscriptions(rpcUrl.replace(\"https://\", \"wss://\"));\n\n return { rpc, rpcSubscriptions };\n}\n\n/**\n * Parses and validates a Solana address string.\n * \n * @param addr - Base58-encoded Solana address\n */\nexport function parseAddress(addr: string): Address {\n return address(addr);\n}\n\n/**\n * Parses and validates a Solana transaction signature string.\n * \n * @param sig - Base58-encoded transaction signature\n */\nexport function parseSignature(sig: string): Signature {\n return signature(sig);\n}\n\n","import type { TokenInfo } from \"./money.types\";\n\nexport const KNOWN_TOKENS = {\n SOL: \"So11111111111111111111111111111111111111112\",\n USDC: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n USDC_BRIDGED: \"A9mUU4qviSctJVPJdBJWkb28deg915LYJKrzQ19ji3FM\",\n USDG: \"2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH\",\n} as const;\n\nexport const TOKEN_INFO: Record<string, TokenInfo> = {\n [KNOWN_TOKENS.SOL]: {\n mint: KNOWN_TOKENS.SOL,\n symbol: \"SOL\",\n name: \"Solana\",\n decimals: 9,\n logoURI:\n \"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png\",\n },\n [KNOWN_TOKENS.USDC]: {\n mint: KNOWN_TOKENS.USDC,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n logoURI:\n \"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png\",\n },\n [KNOWN_TOKENS.USDC_BRIDGED]: {\n mint: KNOWN_TOKENS.USDC_BRIDGED,\n symbol: \"USDCet\",\n name: \"USDC (Bridged)\",\n decimals: 6,\n },\n [KNOWN_TOKENS.USDG]: {\n mint: KNOWN_TOKENS.USDG,\n symbol: \"USDG\",\n name: \"USD Glitter\",\n decimals: 6,\n },\n};\n\nexport function getTokenInfo(mint: string): TokenInfo | undefined {\n return TOKEN_INFO[mint];\n}\n\nexport function isSupportedToken(mint: string): boolean {\n return mint in TOKEN_INFO;\n}\n\nexport const SUPPORTED_STABLECOINS = [\n KNOWN_TOKENS.USDC,\n KNOWN_TOKENS.USDC_BRIDGED,\n KNOWN_TOKENS.USDG,\n] as const;\n\nexport const TRACKED_TOKENS = [\n KNOWN_TOKENS.SOL,\n KNOWN_TOKENS.USDC,\n] as const;\n\n","import {\n type Address,\n type Rpc,\n type GetBalanceApi,\n type GetTokenAccountsByOwnerApi,\n address,\n} from \"@solana/kit\";\n\nimport { getTokenInfo, KNOWN_TOKENS } from \"@tx-indexer/core/money/token-registry\";\n\nexport interface WalletBalance {\n address: string;\n sol: {\n lamports: bigint;\n ui: number;\n };\n tokens: TokenAccountBalance[];\n}\n\nexport interface TokenAccountBalance {\n mint: string;\n tokenAccount?: string;\n amount: {\n raw: string;\n ui: number;\n };\n decimals: number;\n symbol: string;\n}\n\n/**\n * Fetches wallet balance including SOL and SPL tokens\n *\n * @param rpc - Solana RPC client\n * @param walletAddress - Wallet address to query\n * @param tokenMints - Optional array of token mint addresses to track. If omitted, returns all tokens in wallet\n * @returns Wallet balance data with SOL and token balances\n *\n * @example\n * // Fetch all tokens\n * const allBalances = await fetchWalletBalance(rpc, address);\n *\n * @example\n * // Fetch specific tokens only\n * const usdcOnly = await fetchWalletBalance(rpc, address, [\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"]);\n */\nexport async function fetchWalletBalance(\n rpc: Rpc<GetBalanceApi & GetTokenAccountsByOwnerApi>,\n walletAddress: Address,\n tokenMints?: readonly string[]\n): Promise<WalletBalance> {\n const balanceResponse = await rpc.getBalance(walletAddress).send();\n const lamports = balanceResponse.value;\n\n const tokenAccounts = await fetchTokenAccounts(rpc, walletAddress);\n\n const tokens = tokenMints\n ? filterToTrackedTokens(tokenAccounts, tokenMints)\n : Array.from(tokenAccounts.values());\n\n return {\n address: walletAddress,\n sol: {\n lamports,\n ui: Number(lamports) / 1e9,\n },\n tokens,\n };\n}\n\nasync function fetchTokenAccounts(\n rpc: Rpc<GetBalanceApi & GetTokenAccountsByOwnerApi>,\n walletAddress: Address\n): Promise<Map<string, TokenAccountBalance>> {\n const accountsMap = new Map<string, TokenAccountBalance>();\n\n try {\n const response = await rpc\n .getTokenAccountsByOwner(\n walletAddress,\n { programId: address(\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\") },\n { encoding: \"jsonParsed\" }\n )\n .send();\n\n for (const account of response.value) {\n const parsedInfo = account.account.data.parsed.info;\n const mint = parsedInfo.mint;\n\n const tokenInfo = getTokenInfo(mint);\n const symbol = tokenInfo?.symbol || mint.substring(0, 8);\n\n accountsMap.set(mint, {\n mint,\n tokenAccount: account.pubkey.toString(),\n amount: {\n raw: parsedInfo.tokenAmount.amount,\n ui: parsedInfo.tokenAmount.uiAmountString\n ? parseFloat(parsedInfo.tokenAmount.uiAmountString)\n : 0,\n },\n decimals: parsedInfo.tokenAmount.decimals,\n symbol,\n });\n }\n } catch (error) {\n console.error(\"Error fetching token accounts:\", error);\n }\n\n return accountsMap;\n}\n\n/**\n * Filters token accounts to only include specified mints, adding zero balances for missing tokens\n *\n * @param fetchedAccounts - Map of mint addresses to token balances from RPC\n * @param tokenMints - Array of token mint addresses to include in results\n */\nfunction filterToTrackedTokens(\n fetchedAccounts: Map<string, TokenAccountBalance>,\n tokenMints: readonly string[]\n): TokenAccountBalance[] {\n const result: TokenAccountBalance[] = [];\n\n for (const mint of tokenMints) {\n if (mint === KNOWN_TOKENS.SOL) continue;\n\n const existing = fetchedAccounts.get(mint);\n if (existing) {\n result.push(existing);\n } else {\n const tokenInfo = getTokenInfo(mint);\n if (tokenInfo) {\n result.push({\n mint,\n amount: {\n raw: \"0\",\n ui: 0,\n },\n decimals: tokenInfo.decimals,\n symbol: tokenInfo.symbol,\n });\n }\n }\n }\n\n return result;\n}\n\nexport function formatBalance(balance: WalletBalance): string[] {\n const lines: string[] = [];\n\n lines.push(`Wallet: ${balance.address}`);\n lines.push(`SOL: ${balance.sol.ui.toFixed(9)}`);\n\n for (const token of balance.tokens) {\n lines.push(`${token.symbol}: ${token.amount.ui.toFixed(token.decimals)}`);\n }\n\n return lines;\n}\n","import type { SolanaTransaction } from \"@tx-indexer/solana/types/transaction.types\";\n\n/**\n * Extracts all unique program IDs from a transaction.\n *\n * @param transaction - Raw transaction object from RPC\n * @returns Array of program ID strings\n */\nexport function extractProgramIds(transaction: SolanaTransaction): string[] {\n const programIds = new Set<string>();\n\n const { message } = transaction;\n const { accountKeys, instructions } = message;\n\n for (const ix of instructions) {\n const { programIdIndex } = ix;\n if (programIdIndex !== undefined && accountKeys[programIdIndex]) {\n const key = accountKeys[programIdIndex];\n programIds.add(key.toString());\n }\n }\n\n return Array.from(programIds);\n}\n","/**\n * Solana Program IDs\n * \n * Centralized registry of known Solana program addresses.\n * These are public keys that identify on-chain programs.\n */\n\n// ============================================\n// Core Solana Programs\n// ============================================\n\nexport const SYSTEM_PROGRAM_ID = \"11111111111111111111111111111111\";\nexport const COMPUTE_BUDGET_PROGRAM_ID = \"ComputeBudget111111111111111111111111111111\";\nexport const STAKE_PROGRAM_ID = \"Stake11111111111111111111111111111111111111\";\n\n// ============================================\n// Token Programs\n// ============================================\n\nexport const TOKEN_PROGRAM_ID = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nexport const ASSOCIATED_TOKEN_PROGRAM_ID = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\n\n// ============================================\n// Memo Programs\n// ============================================\n\nexport const SPL_MEMO_PROGRAM_ID = \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\";\nexport const MEMO_V1_PROGRAM_ID = \"Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo\";\n\n// ============================================\n// DeFi Programs\n// ============================================\n\nexport const JUPITER_V6_PROGRAM_ID = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nexport const JUPITER_V4_PROGRAM_ID = \"JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB\";\nexport const RAYDIUM_PROGRAM_ID = \"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\";\nexport const ORCA_WHIRLPOOL_PROGRAM_ID = \"whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc\";\n\n// ============================================\n// NFT Programs\n// ============================================\n\nexport const METAPLEX_PROGRAM_ID = \"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\";\n\n// ============================================\n// Payment Facilitators\n// ============================================\n\nexport const PAYAI_FACILITATOR = \"2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHDBg4\";\n\n// ============================================\n// Helper Collections\n// ============================================\n\nexport const MEMO_PROGRAM_IDS = [\n SPL_MEMO_PROGRAM_ID,\n MEMO_V1_PROGRAM_ID,\n] as const;\n\nexport const TOKEN_PROGRAM_IDS = [\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n] as const;\n\nexport const DEX_PROGRAM_IDS = [\n JUPITER_V6_PROGRAM_ID,\n JUPITER_V4_PROGRAM_ID,\n RAYDIUM_PROGRAM_ID,\n ORCA_WHIRLPOOL_PROGRAM_ID,\n] as const;\n\nexport const KNOWN_FACILITATORS = [\n PAYAI_FACILITATOR,\n] as const;\n\nexport function detectFacilitator(accountKeys: string[]): string | null {\n for (const facilitator of KNOWN_FACILITATORS) {\n if (accountKeys.includes(facilitator)) {\n if (facilitator === PAYAI_FACILITATOR) {\n return \"payai\";\n }\n }\n }\n return null;\n}\n\n","// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n // eslint-disable-next-line no-empty\n if (source instanceof Uint8Array) { } else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source)\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n let zeroes = 0\n let length = 0\n let pbegin = 0\n const pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n let i = 0\n for (let it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n let it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n let str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n let psz = 0\n // Skip and count leading '1's.\n let zeroes = 0\n let length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n const b256 = new Uint8Array(size)\n // Process the characters.\n while (psz < source.length) {\n // Find code of next character\n const charCode = source.charCodeAt(psz)\n // Base map can not be indexed using char code\n if (charCode > 255) { return }\n // Decode character\n let carry = BASE_MAP[charCode]\n // Invalid character\n if (carry === 255) { return }\n let i = 0\n for (let it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip leading zeroes in b256.\n let it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n const vch = new Uint8Array(zeroes + (size - it4))\n let j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n const buffer = decodeUnsafe(string)\n if (buffer) { return buffer }\n throw new Error('Non-base' + BASE + ' character')\n }\n return {\n encode,\n decodeUnsafe,\n decode\n }\n}\nexport default base\n","import basex from 'base-x';\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\nexport default basex(ALPHABET);\n","import type { SolanaTransaction } from \"@tx-indexer/solana/types/transaction.types\";\nimport {\n SPL_MEMO_PROGRAM_ID,\n MEMO_V1_PROGRAM_ID,\n} from \"@tx-indexer/solana/constants/program-ids\";\nimport bs58 from \"bs58\";\n\ninterface TransactionWithLogs extends SolanaTransaction {\n meta?: {\n logMessages?: readonly string[] | null;\n };\n}\n\nfunction decodeMemoData(base64Data: string): string {\n const buffer = Buffer.from(base64Data, \"base64\");\n\n const text = buffer.toString(\"utf-8\");\n if (!text.includes(\"\\ufffd\") && /^[\\x20-\\x7E\\s]*$/.test(text)) {\n return text;\n }\n\n if (buffer.length === 32) {\n return bs58.encode(buffer);\n }\n\n if (buffer.length % 32 === 0 && buffer.length > 0) {\n const addresses: string[] = [];\n for (let i = 0; i < buffer.length; i += 32) {\n const chunk = buffer.subarray(i, i + 32);\n addresses.push(bs58.encode(chunk));\n }\n return addresses.join(\", \");\n }\n\n if (buffer.length >= 16) {\n const uuidBytes = buffer.subarray(0, 16);\n const uuid = [\n uuidBytes.subarray(0, 4).toString(\"hex\"),\n uuidBytes.subarray(4, 6).toString(\"hex\"),\n uuidBytes.subarray(6, 8).toString(\"hex\"),\n uuidBytes.subarray(8, 10).toString(\"hex\"),\n uuidBytes.subarray(10, 16).toString(\"hex\"),\n ].join(\"-\");\n\n if (buffer.length === 16) {\n return `Product: ${uuid}`;\n }\n\n const extraData = buffer.subarray(16);\n const extraHex = extraData.toString(\"hex\");\n return `Product: ${uuid} | Meta: ${extraHex}`;\n }\n\n return bs58.encode(buffer);\n}\n\n/**\n * Extracts memo data from a Solana transaction.\n * \n * First attempts to extract human-readable memos from program logs, which contain\n * the decoded text. Falls back to parsing memo program instructions for binary data.\n * Handles various memo formats including UTF-8 text, public keys, and Solana Pay metadata.\n * \n * @param transaction - Solana transaction with message and optional logs\n * @returns Extracted memo string, or null if no memo is found\n */\nexport function extractMemo(transaction: TransactionWithLogs): string | null {\n if (transaction.meta?.logMessages) {\n const memoLogPattern = /Program log: Memo \\(len \\d+\\): \"(.+)\"/;\n for (const log of transaction.meta.logMessages) {\n const match = log.match(memoLogPattern);\n if (match?.[1]) {\n return match[1];\n }\n }\n }\n\n const { message } = transaction;\n const { accountKeys, instructions } = message;\n\n for (const ix of instructions) {\n const programId = accountKeys[ix.programIdIndex]?.toString();\n\n if (programId === SPL_MEMO_PROGRAM_ID || programId === MEMO_V1_PROGRAM_ID) {\n if (ix.data) {\n try {\n return decodeMemoData(ix.data);\n } catch (e) {\n console.warn(\"Failed to decode memo:\", e);\n }\n }\n }\n }\n\n return null;\n}\n\nexport interface SolanaPayMemo {\n merchant?: string;\n item?: string;\n reference?: string;\n label?: string;\n message?: string;\n raw: string;\n}\n\n/**\n * Parses a Solana Pay memo string into structured fields.\n * \n * Attempts to parse the memo as JSON to extract merchant, item, reference,\n * label, and message fields. Falls back to returning just the raw memo if parsing fails.\n * \n * @param memo - Memo string to parse\n * @returns Parsed Solana Pay memo object with raw memo included\n */\nexport function parseSolanaPayMemo(memo: string): SolanaPayMemo {\n try {\n const parsed = JSON.parse(memo);\n return { ...parsed, raw: memo };\n } catch {\n return { raw: memo };\n }\n}\n\n/**\n * Determines if a transaction is a Solana Pay transaction.\n * \n * A transaction is considered Solana Pay if it includes the SPL Memo program\n * and has a non-null memo. Solana Pay uses memos to attach payment metadata.\n * \n * @param programIds - Program IDs involved in the transaction\n * @param memo - Extracted memo from the transaction\n * @returns True if this is a Solana Pay transaction\n */\nexport function isSolanaPayTransaction(\n programIds: string[],\n memo: string | null | undefined\n): boolean {\n const hasMemoProgram =\n programIds.includes(SPL_MEMO_PROGRAM_ID) ||\n programIds.includes(MEMO_V1_PROGRAM_ID);\n\n return hasMemoProgram && memo !== null && memo !== undefined;\n}\n","import type {\n Address,\n Rpc,\n Signature,\n GetSignaturesForAddressApi,\n GetTransactionApi,\n} from \"@solana/kit\";\nimport type { RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport { extractProgramIds } from \"@tx-indexer/solana/mappers/transaction-mapper\";\nimport { extractMemo } from \"@tx-indexer/solana/mappers/memo-parser\";\n\nexport interface FetchTransactionsConfig {\n limit?: number;\n before?: Signature;\n until?: Signature;\n}\n\n/**\n * Fetches transaction signatures for a wallet address.\n *\n * @param rpc - Solana RPC client\n * @param walletAddress - Wallet address to fetch signatures for\n * @param config - Optional pagination and limit configuration\n * @returns Array of raw transactions with basic metadata only\n */\nexport async function fetchWalletSignatures(\n rpc: Rpc<GetSignaturesForAddressApi>,\n walletAddress: Address,\n config: FetchTransactionsConfig = {}\n): Promise<RawTransaction[]> {\n const { limit = 100, before, until } = config;\n\n const response = await rpc\n .getSignaturesForAddress(walletAddress, {\n limit,\n before,\n until,\n })\n .send();\n\n return response.map((sig) => ({\n signature: sig.signature,\n slot: sig.slot,\n blockTime: sig.blockTime,\n err: sig.err,\n programIds: [],\n protocol: null,\n memo: sig.memo || null,\n }));\n}\n\n/**\n * Fetches a single transaction with full details including program IDs.\n *\n * @param rpc - Solana RPC client\n * @param signature - Transaction signature\n * @param commitment - Commitment level for fetching\n * @returns Full raw transaction with program IDs\n */\nexport async function fetchTransaction(\n rpc: Rpc<GetTransactionApi>,\n signature: Signature,\n commitment: \"confirmed\" | \"finalized\" = \"confirmed\"\n): Promise<RawTransaction | null> {\n const response = await rpc\n .getTransaction(signature, {\n commitment,\n maxSupportedTransactionVersion: 0,\n encoding: \"json\",\n })\n .send();\n\n if (!response) {\n return null;\n }\n\n // Try to get memo from response metadata first (already decoded by RPC)\n // Fall back to manual extraction if not available\n const transactionWithLogs = {\n ...response.transaction,\n meta: { logMessages: response.meta?.logMessages },\n };\n const memo = extractMemo(transactionWithLogs);\n\n return {\n signature,\n slot: response.slot,\n blockTime: response.blockTime,\n err: response.meta?.err ?? null,\n programIds: extractProgramIds(response.transaction),\n protocol: null,\n preTokenBalances: (response.meta?.preTokenBalances ?? []).map((bal) => ({\n accountIndex: bal.accountIndex,\n mint: bal.mint.toString(),\n owner: bal.owner?.toString(),\n programId: bal.programId?.toString(),\n uiTokenAmount: {\n amount: bal.uiTokenAmount.amount.toString(),\n decimals: bal.uiTokenAmount.decimals,\n uiAmountString: bal.uiTokenAmount.uiAmountString.toString(),\n },\n })),\n postTokenBalances: (response.meta?.postTokenBalances ?? []).map((bal) => ({\n accountIndex: bal.accountIndex,\n mint: bal.mint.toString(),\n owner: bal.owner?.toString(),\n programId: bal.programId?.toString(),\n uiTokenAmount: {\n amount: bal.uiTokenAmount.amount.toString(),\n decimals: bal.uiTokenAmount.decimals,\n uiAmountString: bal.uiTokenAmount.uiAmountString.toString(),\n },\n })),\n preBalances: (response.meta?.preBalances ?? []).map((bal) => Number(bal)),\n postBalances: (response.meta?.postBalances ?? []).map((bal) => Number(bal)),\n accountKeys: response.transaction.message.accountKeys.map((key) =>\n key.toString()\n ),\n memo,\n };\n}\n\n/**\n * Fetches multiple transactions in parallel.\n *\n * @param rpc - Solana RPC client\n * @param signatures - Array of transaction signatures\n * @param commitment - Commitment level for fetching\n * @returns Array of full raw transactions (nulls filtered out)\n */\nexport async function fetchTransactionsBatch(\n rpc: Rpc<GetTransactionApi>,\n signatures: Signature[],\n commitment: \"confirmed\" | \"finalized\" = \"confirmed\"\n): Promise<RawTransaction[]> {\n const promises = signatures.map((sig) =>\n fetchTransaction(rpc, sig, commitment)\n );\n const results = await Promise.all(promises);\n return results.filter((tx): tx is RawTransaction => tx !== null);\n}\n","export type AccountIdType = \"wallet\" | \"protocol\" | \"external\" | \"fee\";\n\nexport interface BuildAccountIdParams {\n type: AccountIdType;\n address: string;\n protocol?: string;\n token?: string;\n}\n\n/**\n * Builds a standardized account identifier string for transaction legs.\n * \n * Account IDs follow these formats:\n * - Wallet: `wallet:{address}`\n * - Protocol: `protocol:{protocol}:{token}:{address}` or `protocol:{protocol}:{address}`\n * - External: `external:{address}`\n * - Fee: `fee:network`\n * \n * @param params - Account identifier parameters\n * @returns Formatted account ID string\n * @throws Error if parameters are invalid for the account type\n */\nexport function buildAccountId(params: BuildAccountIdParams): string {\n const { type, address, protocol, token } = params;\n\n if (type === \"wallet\") {\n return `wallet:${address}`;\n }\n\n if (type === \"protocol\" && protocol) {\n if (token) {\n return `protocol:${protocol}:${token}:${address}`;\n }\n return `protocol:${protocol}:${address}`;\n }\n\n if (type === \"external\") {\n return `external:${address}`;\n }\n\n if (type === \"fee\") {\n return \"fee:network\";\n }\n \n throw new Error(\n `Invalid accountId parameters: type=${type}, address=${address}, protocol=${protocol}`\n );\n}\n\nexport interface ParsedAccountId {\n type: AccountIdType | \"unknown\";\n address?: string;\n protocol?: string;\n token?: string;\n}\n\n/**\n * Parses an account identifier string into its components.\n * \n * Extracts the account type, address, protocol, and token information from\n * a formatted account ID string. Returns `unknown` type for unrecognized formats.\n * \n * @param accountId - Account ID string to parse\n * @returns Parsed account identifier with type and optional metadata\n */\nexport function parseAccountId(accountId: string): ParsedAccountId {\n const parts = accountId.split(\":\");\n\n if (parts[0] === \"wallet\" && parts.length === 2) {\n return { type: \"wallet\", address: parts[1] };\n }\n\n if (parts[0] === \"protocol\") {\n if (parts.length === 4) {\n return {\n type: \"protocol\",\n protocol: parts[1],\n token: parts[2],\n address: parts[3],\n };\n }\n if (parts.length === 3) {\n return {\n type: \"protocol\",\n protocol: parts[1],\n address: parts[2],\n };\n }\n }\n\n if (parts[0] === \"external\" && parts.length === 2) {\n return { type: \"external\", address: parts[1] };\n }\n\n if (parts[0] === \"fee\" && parts[1] === \"network\") {\n return { type: \"fee\" };\n }\n\n return { type: \"unknown\", address: accountId };\n}\n","import type { Address } from \"@solana/kit\";\nimport type { RawTransaction, TokenBalance } from \"@tx-indexer/core/tx/tx.types\";\nimport type { MoneyAmount, TokenInfo } from \"@tx-indexer/core/money/money.types\";\nimport {\n getTokenInfo,\n KNOWN_TOKENS,\n TOKEN_INFO,\n} from \"@tx-indexer/core/money/token-registry\";\n\nexport interface TokenBalanceChange {\n mint: string;\n tokenInfo: TokenInfo;\n accountIndex: number;\n owner?: string;\n preBalance: {\n raw: string;\n ui: number;\n };\n postBalance: {\n raw: string;\n ui: number;\n };\n change: {\n raw: string;\n ui: number;\n };\n}\n\nexport interface SolBalanceChange {\n accountIndex: number;\n address: string;\n preBalance: bigint;\n postBalance: bigint;\n change: bigint;\n changeUi: number;\n}\n\n/**\n * Extracts all SPL token balance changes from a transaction.\n * \n * Compares pre and post token balances to calculate the change for each token account.\n * Unknown tokens are automatically included with a generated symbol from their mint address.\n * \n * @param tx - Raw transaction with token balance data\n * @param filterMints - Optional array of mint addresses to filter to specific tokens\n * @returns Array of token balance changes with mint, owner, and amount information\n */\nexport function extractTokenBalanceChanges(\n tx: RawTransaction,\n filterMints?: string[]\n): TokenBalanceChange[] {\n const { preTokenBalances = [], postTokenBalances = [] } = tx;\n\n const changes: TokenBalanceChange[] = [];\n\n const preBalanceMap = new Map<number, TokenBalance>();\n for (const bal of preTokenBalances) {\n preBalanceMap.set(bal.accountIndex, bal);\n }\n\n for (const postBal of postTokenBalances) {\n const { accountIndex, mint } = postBal;\n\n if (filterMints && !filterMints.includes(mint)) {\n continue;\n }\n\n let tokenInfo = getTokenInfo(mint);\n if (!tokenInfo) {\n tokenInfo = {\n mint,\n symbol: mint.slice(0, 8),\n decimals: postBal.uiTokenAmount.decimals,\n name: `Unknown Token (${mint.slice(0, 8)}...)`,\n };\n }\n\n const preBal = preBalanceMap.get(accountIndex);\n\n const preAmount = preBal?.uiTokenAmount.amount ?? \"0\";\n const postAmount = postBal.uiTokenAmount.amount;\n const preUi = preBal?.uiTokenAmount.uiAmountString\n ? parseFloat(preBal.uiTokenAmount.uiAmountString)\n : 0;\n const postUi = postBal.uiTokenAmount.uiAmountString\n ? parseFloat(postBal.uiTokenAmount.uiAmountString)\n : 0;\n\n const changeRaw = (BigInt(postAmount) - BigInt(preAmount)).toString();\n const changeUi = postUi - preUi;\n\n if (changeRaw !== \"0\") {\n changes.push({\n mint,\n tokenInfo,\n accountIndex,\n owner: postBal.owner,\n preBalance: {\n raw: preAmount,\n ui: preUi,\n },\n postBalance: {\n raw: postAmount,\n ui: postUi,\n },\n change: {\n raw: changeRaw,\n ui: changeUi,\n },\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Extracts SOL balance changes for all accounts in a transaction.\n * \n * Compares pre and post lamport balances for each account key to calculate\n * the SOL change. Only includes accounts with non-zero changes.\n * \n * @param tx - Raw transaction with SOL balance data\n * @returns Array of SOL balance changes with account address and amounts\n */\nexport function extractSolBalanceChanges(\n tx: RawTransaction\n): SolBalanceChange[] {\n const {\n preBalances = [],\n postBalances = [],\n accountKeys = [],\n } = tx;\n\n const changes: SolBalanceChange[] = [];\n\n for (let i = 0; i < accountKeys.length; i++) {\n const address = accountKeys[i];\n if (!address) continue;\n\n const preBal = BigInt(preBalances[i] ?? 0);\n const postBal = BigInt(postBalances[i] ?? 0);\n const change = postBal - preBal;\n\n if (change !== 0n) {\n changes.push({\n accountIndex: i,\n address,\n preBalance: preBal,\n postBalance: postBal,\n change,\n changeUi: Number(change) / 1e9,\n });\n }\n }\n\n return changes;\n}\n\nexport function getWalletTokenChanges(\n tx: RawTransaction,\n walletAddress: Address,\n filterMints?: string[]\n): TokenBalanceChange[] {\n const allChanges = extractTokenBalanceChanges(tx, filterMints);\n\n return allChanges.filter(\n (change) =>\n change.owner?.toLowerCase() === walletAddress.toLowerCase()\n );\n}\n\nexport function getWalletSolChange(\n tx: RawTransaction,\n walletAddress: Address\n): SolBalanceChange | null {\n if (!tx.accountKeys || tx.accountKeys.length === 0) {\n return null;\n }\n\n const allChanges = extractSolBalanceChanges(tx);\n\n return (\n allChanges.find(\n (change) => change.address.toLowerCase() === walletAddress.toLowerCase()\n ) ?? null\n );\n}\n\nexport function toMoneyAmount(change: TokenBalanceChange): MoneyAmount {\n return {\n token: change.tokenInfo,\n amountRaw: change.change.raw,\n amountUi: change.change.ui,\n };\n}\n\nexport function solChangeToMoneyAmount(change: SolBalanceChange): MoneyAmount {\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (!solInfo) {\n throw new Error(\"SOL token info not found in registry\");\n }\n return {\n token: solInfo,\n amountRaw: change.change.toString(),\n amountUi: change.changeUi,\n };\n}\n\n","/**\n * Constants for DEX protocol detection\n */\n\nexport const DEX_PROTOCOL_IDS = new Set([\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n]);\n\n","import type { Address } from \"@solana/kit\";\nimport type { RawTransaction, TxLeg, TxLegRole } from \"@tx-indexer/core/tx/tx.types\";\nimport type { ProtocolInfo } from \"@tx-indexer/core/actors/counterparty.types\";\nimport { buildAccountId } from \"@tx-indexer/core/tx/account-id\";\nimport {\n extractSolBalanceChanges,\n extractTokenBalanceChanges,\n type SolBalanceChange,\n type TokenBalanceChange,\n} from \"./balance-parser\";\nimport { KNOWN_TOKENS, TOKEN_INFO } from \"@tx-indexer/core/money/token-registry\";\nimport { DEX_PROTOCOL_IDS } from \"../constants/protocol-constants\";\n\nfunction isDexProtocol(protocol: ProtocolInfo | null | undefined): boolean {\n return protocol !== null && protocol !== undefined && DEX_PROTOCOL_IDS.has(protocol.id);\n}\n\n/**\n * Converts a raw Solana transaction into a double-entry accounting ledger.\n * \n * Creates TxLeg entries for all SOL and token balance changes, automatically\n * detecting and accounting for network fees. Each leg represents a debit or credit\n * for a specific account and token, enabling transaction classification and validation.\n * \n * @param tx - Raw transaction data with balance changes\n * @param walletAddress - Optional wallet address for perspective. When provided, legs are tagged\n * as \"wallet:\" or \"external:\". When omitted (observer mode), all legs are tagged as \"external:\".\n * @returns Array of transaction legs representing all balance movements\n */\nexport function transactionToLegs(\n tx: RawTransaction,\n walletAddress?: Address\n): TxLeg[] {\n const legs: TxLeg[] = [];\n const feePayer = tx.accountKeys?.[0]?.toLowerCase();\n\n const solChanges = extractSolBalanceChanges(tx);\n let totalSolDebits = 0n;\n let totalSolCredits = 0n;\n\n for (const change of solChanges) {\n if (change.change === 0n) continue;\n\n const isWallet = walletAddress\n ? change.address.toLowerCase() === walletAddress.toLowerCase()\n : false;\n const accountId = buildAccountId({\n type: isWallet ? \"wallet\" : \"external\",\n address: change.address,\n });\n\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (!solInfo) {\n throw new Error(\"SOL token info not found in registry\");\n }\n\n if (change.change > 0n) {\n totalSolCredits += change.change;\n } else {\n totalSolDebits += -change.change;\n }\n\n legs.push({\n accountId,\n side: change.change > 0n ? \"credit\" : \"debit\",\n amount: {\n token: solInfo,\n amountRaw: change.change.toString().replace(\"-\", \"\"),\n amountUi: Math.abs(change.changeUi),\n },\n role: determineSolRole(change, walletAddress, tx, feePayer),\n });\n }\n\n const networkFee = totalSolDebits - totalSolCredits;\n if (networkFee > 0n) {\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (solInfo) {\n legs.push({\n accountId: buildAccountId({ type: \"fee\", address: \"\" }),\n side: \"credit\",\n amount: {\n token: solInfo,\n amountRaw: networkFee.toString(),\n amountUi: Number(networkFee) / 1e9,\n },\n role: \"fee\",\n });\n }\n }\n\n const tokenChanges = extractTokenBalanceChanges(tx);\n for (const change of tokenChanges) {\n if (change.change.raw === \"0\") continue;\n\n const isWallet = walletAddress\n ? change.owner?.toLowerCase() === walletAddress.toLowerCase()\n : false;\n const isFeePayer = !walletAddress && feePayer\n ? change.owner?.toLowerCase() === feePayer\n : false;\n\n let accountId: string;\n if (isWallet && walletAddress) {\n accountId = buildAccountId({\n type: \"wallet\",\n address: change.owner || walletAddress,\n });\n } else if (isFeePayer && feePayer) {\n accountId = buildAccountId({\n type: \"external\",\n address: change.owner || feePayer,\n });\n } else if (isDexProtocol(tx.protocol) && walletAddress) {\n accountId = buildAccountId({\n type: \"protocol\",\n address: change.owner || change.tokenInfo.mint,\n protocol: tx.protocol!.id,\n token: change.tokenInfo.symbol,\n });\n } else {\n accountId = buildAccountId({\n type: \"external\",\n address: change.owner || change.tokenInfo.mint,\n });\n }\n\n legs.push({\n accountId,\n side: change.change.ui > 0 ? \"credit\" : \"debit\",\n amount: {\n token: change.tokenInfo,\n amountRaw: change.change.raw.replace(\"-\", \"\"),\n amountUi: Math.abs(change.change.ui),\n },\n role: determineTokenRole(change, walletAddress, tx, feePayer),\n });\n }\n\n return legs;\n}\n\n/**\n * Determines the role of a SOL balance change in the transaction context.\n * \n * @param change - SOL balance change for an account\n * @param walletAddress - Optional wallet address for perspective\n * @param tx - Raw transaction for additional context\n * @param feePayer - Optional fee payer address for observer mode\n * @returns The role of this SOL balance change\n */\nfunction determineSolRole(\n change: SolBalanceChange,\n walletAddress: Address | undefined,\n tx: RawTransaction,\n feePayer?: string\n): TxLegRole {\n const isWallet = walletAddress\n ? change.address.toLowerCase() === walletAddress.toLowerCase()\n : false;\n const isFeePayer = !walletAddress && feePayer\n ? change.address.toLowerCase() === feePayer\n : false;\n const isPositive = change.change > 0n;\n const amountSol = Math.abs(change.changeUi);\n\n if (isWallet) {\n if (!isPositive && amountSol < 0.01) {\n return \"fee\";\n }\n\n if (isPositive) {\n if (tx.protocol?.id === \"stake\") {\n return \"reward\";\n }\n return \"received\";\n }\n\n return \"sent\";\n }\n\n if (isFeePayer && !isPositive && amountSol < 0.01) {\n return \"fee\";\n }\n\n if (isPositive) {\n return \"received\";\n }\n\n return \"sent\";\n}\n\n/**\n * Determines the role of a token balance change in the transaction context.\n * \n * @param change - Token balance change for an account\n * @param walletAddress - Optional wallet address for perspective\n * @param tx - Raw transaction for protocol context\n * @param feePayer - Optional fee payer address for observer mode\n * @returns The role of this token balance change\n */\nfunction determineTokenRole(\n change: TokenBalanceChange,\n walletAddress: Address | undefined,\n tx: RawTransaction,\n feePayer?: string\n): TxLegRole {\n const isWallet = walletAddress\n ? change.owner?.toLowerCase() === walletAddress.toLowerCase()\n : false;\n const isFeePayer = !walletAddress && feePayer\n ? change.owner?.toLowerCase() === feePayer\n : false;\n const isPositive = change.change.ui > 0;\n\n if (isWallet || isFeePayer) {\n return isPositive ? \"received\" : \"sent\";\n }\n\n if (isDexProtocol(tx.protocol)) {\n return isPositive ? \"protocol_withdraw\" : \"protocol_deposit\";\n }\n\n return isPositive ? \"received\" : \"sent\";\n}\n\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { detectFacilitator } from \"@tx-indexer/solana/constants/program-ids\";\n\nexport class TransferClassifier implements Classifier {\n name = \"transfer\";\n priority = 20;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, walletAddress, tx } = context;\n\n const facilitator = tx.accountKeys\n ? detectFacilitator(tx.accountKeys)\n : null;\n\n const isObserverMode = !walletAddress;\n\n let participantAddress: string;\n let participantPrefix: string;\n\n if (walletAddress) {\n participantAddress = walletAddress.toLowerCase();\n participantPrefix = `wallet:${participantAddress}`;\n } else {\n const feeLeg = legs.find(\n (leg) => leg.role === \"fee\" && leg.accountId.startsWith(\"external:\")\n );\n if (!feeLeg) return null;\n participantAddress = feeLeg.accountId.replace(\"external:\", \"\").toLowerCase();\n participantPrefix = `external:${participantAddress}`;\n }\n\n const participantSent = legs.filter(\n (l) =>\n l.accountId.toLowerCase().startsWith(participantPrefix.toLowerCase()) &&\n l.side === \"debit\" &&\n l.role === \"sent\"\n );\n\n const participantReceived = legs.filter(\n (l) =>\n l.accountId.toLowerCase().startsWith(participantPrefix.toLowerCase()) &&\n l.side === \"credit\" &&\n l.role === \"received\"\n );\n\n const otherReceived = legs.filter(\n (l) =>\n !l.accountId.toLowerCase().startsWith(participantPrefix.toLowerCase()) &&\n l.accountId.startsWith(\"external:\") &&\n l.side === \"credit\" &&\n l.role === \"received\"\n );\n\n const otherSent = legs.filter(\n (l) =>\n !l.accountId.toLowerCase().startsWith(participantPrefix.toLowerCase()) &&\n l.accountId.startsWith(\"external:\") &&\n l.side === \"debit\" &&\n l.role === \"sent\"\n );\n\n for (const sent of participantSent) {\n const matchingReceived = otherReceived.find(\n (r) => r.amount.token.mint === sent.amount.token.mint\n );\n\n if (matchingReceived) {\n const receiverAddress = matchingReceived.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"transfer\",\n direction: isObserverMode ? \"neutral\" : \"outgoing\",\n primaryAmount: sent.amount,\n secondaryAmount: null,\n counterparty: {\n type: \"unknown\",\n address: receiverAddress,\n name: `${receiverAddress.slice(0, 8)}...`,\n },\n confidence: isObserverMode ? 0.9 : 0.95,\n isRelevant: true,\n metadata: {\n ...(isObserverMode && { observer_mode: true, sender: participantAddress }),\n ...(facilitator && { facilitator, payment_type: \"facilitated\" }),\n },\n };\n }\n }\n\n for (const received of participantReceived) {\n const matchingSent = otherSent.find(\n (s) => s.amount.token.mint === received.amount.token.mint\n );\n\n if (matchingSent) {\n const senderAddress = matchingSent.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"transfer\",\n direction: isObserverMode ? \"neutral\" : \"incoming\",\n primaryAmount: received.amount,\n secondaryAmount: null,\n counterparty: {\n type: \"unknown\",\n address: senderAddress,\n name: `${senderAddress.slice(0, 8)}...`,\n },\n confidence: isObserverMode ? 0.9 : 0.95,\n isRelevant: true,\n metadata: {\n ...(isObserverMode && { observer_mode: true, receiver: participantAddress }),\n ...(facilitator && { facilitator, payment_type: \"facilitated\" }),\n },\n };\n }\n }\n\n return null;\n }\n}\n","import type { ProtocolInfo } from \"@tx-indexer/core/actors/counterparty.types\";\nimport {\n JUPITER_V6_PROGRAM_ID,\n JUPITER_V4_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n SYSTEM_PROGRAM_ID,\n COMPUTE_BUDGET_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n METAPLEX_PROGRAM_ID,\n ORCA_WHIRLPOOL_PROGRAM_ID,\n RAYDIUM_PROGRAM_ID,\n STAKE_PROGRAM_ID,\n} from \"@tx-indexer/solana/constants/program-ids\";\n\nconst KNOWN_PROGRAMS: Record<string, ProtocolInfo> = {\n [JUPITER_V6_PROGRAM_ID]: {\n id: \"jupiter\",\n name: \"Jupiter\",\n },\n [JUPITER_V4_PROGRAM_ID]: {\n id: \"jupiter-v4\",\n name: \"Jupiter V4\",\n },\n [TOKEN_PROGRAM_ID]: {\n id: \"spl-token\",\n name: \"Token Program\",\n },\n [SYSTEM_PROGRAM_ID]: {\n id: \"system\",\n name: \"System Program\",\n },\n [COMPUTE_BUDGET_PROGRAM_ID]: {\n id: \"compute-budget\",\n name: \"Compute Budget\",\n },\n [ASSOCIATED_TOKEN_PROGRAM_ID]: {\n id: \"associated-token\",\n name: \"Associated Token Program\",\n },\n [METAPLEX_PROGRAM_ID]: {\n id: \"metaplex\",\n name: \"Metaplex\",\n },\n [ORCA_WHIRLPOOL_PROGRAM_ID]: {\n id: \"orca-whirlpool\",\n name: \"Orca Whirlpool\",\n },\n [RAYDIUM_PROGRAM_ID]: {\n id: \"raydium\",\n name: \"Raydium\",\n },\n [STAKE_PROGRAM_ID]: {\n id: \"stake\",\n name: \"Stake Program\",\n },\n};\n\nconst PRIORITY_ORDER = [\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n \"metaplex\",\n \"stake\",\n \"associated-token\",\n \"spl-token\",\n \"compute-budget\",\n \"system\",\n];\n\n/**\n * Protocol IDs that are DEX (decentralized exchange) protocols.\n * These protocols perform swaps and should have their legs tagged as \"protocol:\" \n * with deposit/withdraw roles.\n */\nconst DEX_PROTOCOL_IDS = new Set([\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n]);\n\n/**\n * Checks if a protocol is a DEX (decentralized exchange) that performs swaps.\n * DEX protocols should have their legs tagged as \"protocol:\" with deposit/withdraw roles.\n * Non-DEX protocols (like Associated Token Program) are infrastructure and should not\n * affect leg tagging.\n */\nexport function isDexProtocol(protocol: ProtocolInfo | null): boolean {\n return protocol !== null && DEX_PROTOCOL_IDS.has(protocol.id);\n}\n\n/**\n * Checks if a protocol ID string corresponds to a DEX protocol.\n * Useful when you only have the protocol ID string, not the full ProtocolInfo object.\n */\nexport function isDexProtocolById(protocolId: string | undefined): boolean {\n return protocolId !== undefined && DEX_PROTOCOL_IDS.has(protocolId);\n}\n\n/**\n * Detects the primary protocol used in a transaction based on its program IDs.\n * \n * When multiple protocols are detected, returns the highest priority protocol\n * according to the PRIORITY_ORDER (e.g., Jupiter > Raydium > Token Program).\n * \n * @param programIds - Array of program IDs involved in the transaction\n * @returns The detected protocol information, or null if no known protocol is found\n */\nexport function detectProtocol(programIds: string[]): ProtocolInfo | null {\n const detectedProtocols: ProtocolInfo[] = [];\n\n for (const programId of programIds) {\n const protocol = KNOWN_PROGRAMS[programId];\n if (protocol) {\n detectedProtocols.push(protocol);\n }\n }\n\n if (detectedProtocols.length === 0) {\n return null;\n }\n\n detectedProtocols.sort((a, b) => {\n const aPriority = PRIORITY_ORDER.indexOf(a.id);\n const bPriority = PRIORITY_ORDER.indexOf(b.id);\n return aPriority - bPriority;\n });\n\n return detectedProtocols[0] ?? null;\n}\n\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isDexProtocolById } from \"../protocols/detector\";\n\nexport class SwapClassifier implements Classifier {\n name = \"swap\";\n priority = 80;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, walletAddress, tx } = context;\n\n const protocolLegs = legs.filter((leg) =>\n leg.accountId.startsWith(\"protocol:\")\n );\n\n const hasDexProtocol = isDexProtocolById(tx.protocol?.id);\n\n if (protocolLegs.length === 0 && !hasDexProtocol) {\n return null;\n }\n\n const isObserverMode = !walletAddress;\n\n let participantPrefix: string;\n if (walletAddress) {\n participantPrefix = `wallet:${walletAddress}`;\n } else {\n const feeLeg = legs.find(\n (leg) => leg.role === \"fee\" && leg.accountId.startsWith(\"external:\")\n );\n if (!feeLeg) return null;\n const feePayerAddress = feeLeg.accountId.replace(\"external:\", \"\");\n participantPrefix = `external:${feePayerAddress}`;\n }\n\n const participantDebits = legs.filter(\n (leg) => leg.accountId.startsWith(participantPrefix) && leg.side === \"debit\"\n );\n\n const participantCredits = legs.filter(\n (leg) => leg.accountId.startsWith(participantPrefix) && leg.side === \"credit\"\n );\n\n const tokensOut = participantDebits.filter(\n (leg) => leg.role === \"sent\" || leg.role === \"protocol_deposit\"\n );\n\n const tokensIn = participantCredits.filter(\n (leg) => leg.role === \"received\" || leg.role === \"protocol_withdraw\"\n );\n\n if (tokensOut.length === 0 || tokensIn.length === 0) {\n return null;\n }\n\n if (tokensOut.length === 1 && tokensIn.length === 1) {\n const tokenOut = tokensOut[0]!;\n const tokenIn = tokensIn[0]!;\n\n if (tokenOut.amount.token.symbol !== tokenIn.amount.token.symbol) {\n return {\n primaryType: \"swap\",\n direction: \"neutral\",\n primaryAmount: tokenOut.amount,\n secondaryAmount: tokenIn.amount,\n counterparty: null,\n confidence: isObserverMode ? 0.85 : 0.9,\n isRelevant: true,\n metadata: {\n swap_type: \"token_to_token\",\n from_token: tokenOut.amount.token.symbol,\n to_token: tokenIn.amount.token.symbol,\n from_amount: tokenOut.amount.amountUi,\n to_amount: tokenIn.amount.amountUi,\n ...(isObserverMode && { observer_mode: true }),\n },\n };\n }\n }\n\n return null;\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { detectFacilitator } from \"@tx-indexer/solana/constants/program-ids\";\n\nexport class AirdropClassifier implements Classifier {\n name = \"airdrop\";\n priority = 70;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, walletAddress, tx } = context;\n \n const facilitator = tx.accountKeys \n ? detectFacilitator(tx.accountKeys) \n : null;\n\n const protocolLegs = legs.filter((leg) =>\n leg.accountId.startsWith(\"protocol:\")\n );\n\n if (protocolLegs.length === 0) {\n return null;\n }\n\n const isObserverMode = !walletAddress;\n const accountPrefix = walletAddress ? `wallet:${walletAddress}` : \"external:\";\n\n const participantCredits = legs.filter(\n (leg) => leg.accountId.startsWith(accountPrefix) && leg.side === \"credit\"\n );\n\n const participantDebits = legs.filter(\n (leg) => leg.accountId.startsWith(accountPrefix) && leg.side === \"debit\"\n );\n\n const tokenReceived = participantCredits.filter(\n (leg) => leg.role === \"received\" && leg.amount.token.symbol !== \"SOL\"\n );\n\n if (tokenReceived.length === 0) {\n return null;\n }\n\n const tokenSent = participantDebits.filter(\n (leg) => leg.role === \"sent\" && leg.amount.token.symbol !== \"SOL\"\n );\n\n if (tokenSent.length > 0) {\n return null;\n }\n\n const mainToken = tokenReceived[0]!;\n\n const senderLegs = legs.filter(\n (leg) =>\n leg.side === \"debit\" &&\n leg.amount.token.mint === mainToken.amount.token.mint &&\n !leg.accountId.startsWith(accountPrefix)\n );\n\n const sender = senderLegs.length > 0 ? senderLegs[0] : null;\n const receiverAddress = mainToken.accountId.replace(/^(external:|wallet:)/, \"\");\n\n return {\n primaryType: \"airdrop\",\n direction: isObserverMode ? \"neutral\" : \"incoming\",\n primaryAmount: mainToken.amount,\n secondaryAmount: null,\n counterparty: sender\n ? {\n type: \"unknown\",\n address: sender.accountId.replace(/^(external:|protocol:|wallet:)/, \"\"),\n }\n : null,\n confidence: isObserverMode ? 0.8 : 0.85,\n isRelevant: true,\n metadata: {\n airdrop_type: \"token\",\n token: mainToken.amount.token.symbol,\n amount: mainToken.amount.amountUi,\n ...(isObserverMode && { observer_mode: true, receiver: receiverAddress }),\n ...(facilitator && { facilitator, payment_type: \"facilitated\" }),\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\n\nexport class FeeOnlyClassifier implements Classifier {\n name = \"fee-only\";\n priority = 60;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, walletAddress } = context;\n\n const isObserverMode = !walletAddress;\n const accountPrefix = walletAddress ? `wallet:${walletAddress}` : \"external:\";\n\n const participantLegs = legs.filter((leg) => leg.accountId.startsWith(accountPrefix));\n const nonFeeParticipantLegs = participantLegs.filter((leg) => leg.role !== \"fee\");\n\n if (nonFeeParticipantLegs.length > 0) {\n return null;\n }\n\n const feeLegs = legs.filter((leg) => leg.role === \"fee\");\n\n if (feeLegs.length === 0) {\n return null;\n }\n\n const totalFee = feeLegs.find((leg) => leg.amount.token.symbol === \"SOL\");\n\n return {\n primaryType: \"fee_only\",\n direction: \"outgoing\",\n primaryAmount: totalFee?.amount ?? null,\n secondaryAmount: null,\n counterparty: null,\n confidence: isObserverMode ? 0.9 : 0.95,\n isRelevant: false,\n metadata: {\n fee_type: \"network\",\n ...(isObserverMode && { observer_mode: true }),\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport {\n isSolanaPayTransaction,\n parseSolanaPayMemo,\n} from \"@tx-indexer/solana/mappers/memo-parser\";\n\nexport class SolanaPayClassifier implements Classifier {\n name = \"solana-pay\";\n priority = 95;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { tx, walletAddress, legs } = context;\n\n if (!isSolanaPayTransaction(tx.programIds, tx.memo)) {\n return null;\n }\n\n const memo = parseSolanaPayMemo(tx.memo!);\n const isObserverMode = !walletAddress;\n\n if (isObserverMode) {\n const senderLeg = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.role === \"sent\"\n );\n\n const receiverLeg = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n leg.role === \"received\"\n );\n\n const primaryAmount = senderLeg?.amount ?? receiverLeg?.amount ?? null;\n const senderAddress = senderLeg?.accountId.replace(\"external:\", \"\");\n const receiverAddress = receiverLeg?.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"transfer\",\n direction: \"neutral\",\n primaryAmount,\n secondaryAmount: null,\n counterparty: memo.merchant\n ? { address: receiverAddress ?? \"\", name: memo.merchant, type: \"merchant\" }\n : null,\n confidence: 0.95,\n isRelevant: true,\n metadata: {\n payment_type: \"solana_pay\",\n observer_mode: true,\n sender: senderAddress,\n receiver: receiverAddress,\n memo: memo.raw,\n merchant: memo.merchant,\n item: memo.item,\n reference: memo.reference,\n label: memo.label,\n message: memo.message,\n },\n };\n }\n\n const walletPrefix = `wallet:${walletAddress}`;\n\n const userSent = legs.find(\n (leg) =>\n leg.accountId.includes(walletPrefix) &&\n leg.side === \"debit\" &&\n leg.role === \"sent\"\n );\n\n const userReceived = legs.find(\n (leg) =>\n leg.accountId.includes(walletPrefix) &&\n leg.side === \"credit\" &&\n leg.role === \"received\"\n );\n\n const direction = userSent ? \"outgoing\" : \"incoming\";\n const primaryAmount = userSent?.amount ?? userReceived?.amount ?? null;\n\n return {\n primaryType: \"transfer\",\n direction,\n primaryAmount,\n secondaryAmount: null,\n counterparty: memo.merchant\n ? { address: \"\", name: memo.merchant, type: \"merchant\" }\n : null,\n confidence: 0.98,\n isRelevant: true,\n metadata: {\n payment_type: \"solana_pay\",\n memo: memo.raw,\n merchant: memo.merchant,\n item: memo.item,\n reference: memo.reference,\n label: memo.label,\n message: memo.message,\n },\n };\n }\n}\n\n","import type { Address } from \"@solana/kit\";\nimport type { TxLeg, RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport type { Classifier, ClassifierContext } from \"./classifier.interface\";\nimport { TransferClassifier } from \"../classifiers/transfer-classifier\";\nimport { SwapClassifier } from \"../classifiers/swap-classifier\";\nimport { AirdropClassifier } from \"../classifiers/airdrop-classifier\";\nimport { FeeOnlyClassifier } from \"../classifiers/fee-only-classifier\";\nimport { SolanaPayClassifier } from \"../classifiers/solana-pay-classifier\";\n\nexport class ClassificationService {\n private classifiers: Classifier[] = [];\n\n constructor() {\n this.registerClassifier(new SolanaPayClassifier());\n this.registerClassifier(new SwapClassifier());\n this.registerClassifier(new AirdropClassifier());\n this.registerClassifier(new TransferClassifier());\n this.registerClassifier(new FeeOnlyClassifier());\n }\n\n registerClassifier(classifier: Classifier): void {\n this.classifiers.push(classifier);\n this.classifiers.sort((a, b) => b.priority - a.priority);\n }\n\n classify(\n legs: TxLeg[],\n walletAddress: Address | undefined,\n tx: RawTransaction\n ): TransactionClassification {\n const context: ClassifierContext = { legs, walletAddress, tx };\n\n for (const classifier of this.classifiers) {\n const result = classifier.classify(context);\n if (result && result.isRelevant) {\n return result;\n }\n }\n\n return {\n primaryType: \"other\",\n direction: \"neutral\",\n primaryAmount: null,\n secondaryAmount: null,\n counterparty: null,\n confidence: 0.0,\n isRelevant: false,\n metadata: {},\n };\n }\n}\n\nexport const classificationService = new ClassificationService();\n\n/**\n * Classifies a transaction based on its accounting legs and context.\n * \n * Uses a priority-ordered chain of classifiers (Solana Pay > Swap > Airdrop > Transfer > Fee-only)\n * to determine the transaction type, direction, amounts, and counterparty.\n * \n * @param legs - Transaction legs representing all balance movements\n * @param walletAddress - Optional wallet address for classification perspective. When omitted,\n * classifies from a neutral observer perspective.\n * @param tx - Raw transaction data for additional context (protocol, memo, etc.)\n * @returns Classification result with type, amounts, counterparty, and confidence\n */\nexport function classifyTransaction(\n legs: TxLeg[],\n walletAddress: Address | undefined,\n tx: RawTransaction\n): TransactionClassification {\n return classificationService.classify(legs, walletAddress, tx);\n}\n","import type { TransactionClassification } from \"./classification.types\";\nimport type { RawTransaction } from \"./tx.types\";\n\nexport interface SpamFilterConfig {\n minSolAmount?: number;\n minTokenAmountUsd?: number;\n minConfidence?: number;\n allowFailed?: boolean;\n}\n\nconst DEFAULT_CONFIG: Required<SpamFilterConfig> = {\n minSolAmount: 0.001,\n minTokenAmountUsd: 0.01,\n minConfidence: 0.5,\n allowFailed: false,\n};\n\n/**\n * Determines if a transaction should be filtered as spam or dust.\n * \n * A transaction is considered spam if it:\n * - Failed (and allowFailed is false)\n * - Has low classification confidence\n * - Is not relevant to the wallet\n * - Involves dust amounts below configured thresholds\n * \n * @param tx - Raw transaction data\n * @param classification - Transaction classification result\n * @param config - Optional spam filter configuration (uses defaults if omitted)\n * @returns True if the transaction should be filtered as spam\n */\nexport function isSpamTransaction(\n tx: RawTransaction,\n classification: TransactionClassification,\n config: SpamFilterConfig = {}\n): boolean {\n const cfg = { ...DEFAULT_CONFIG, ...config };\n\n if (!cfg.allowFailed && tx.err) {\n return true;\n }\n\n if (classification.confidence < cfg.minConfidence) {\n return true;\n }\n\n if (!classification.isRelevant) {\n return true;\n }\n\n if (isDustTransaction(classification, cfg)) {\n return true;\n }\n\n return false;\n}\n\nfunction isDustTransaction(\n classification: TransactionClassification,\n config: Required<SpamFilterConfig>\n): boolean {\n const { primaryAmount } = classification;\n \n if (!primaryAmount) {\n return false;\n }\n\n const { token, amountUi } = primaryAmount;\n\n if (token.symbol === \"SOL\") {\n return Math.abs(amountUi) < config.minSolAmount;\n }\n\n if (token.symbol === \"USDC\") {\n return Math.abs(amountUi) < config.minTokenAmountUsd;\n }\n\n return Math.abs(amountUi) < config.minTokenAmountUsd;\n}\n\n/**\n * Filters an array of transactions to remove spam and dust transactions.\n * \n * Applies spam detection criteria to each transaction while preserving\n * additional properties in the returned array items.\n * \n * @param transactions - Array of transaction objects with tx and classification\n * @param config - Optional spam filter configuration\n * @returns Filtered array with spam transactions removed\n */\nexport function filterSpamTransactions<T extends {\n tx: RawTransaction;\n classification: TransactionClassification;\n}>(\n transactions: T[],\n config?: SpamFilterConfig\n): T[] {\n return transactions.filter(\n ({ tx, classification }) => !isSpamTransaction(tx, classification, config)\n );\n}\n\n","import type { Address, Signature } from \"@solana/kit\";\nimport {\n createSolanaClient,\n parseSignature,\n type SolanaClient,\n} from \"@tx-indexer/solana/rpc/client\";\nimport { fetchWalletBalance } from \"@tx-indexer/solana/fetcher/balances\";\nimport {\n fetchWalletSignatures,\n fetchTransaction,\n fetchTransactionsBatch,\n type FetchTransactionsConfig,\n} from \"@tx-indexer/solana/fetcher/transactions\";\n\nexport type { FetchTransactionsConfig } from \"@tx-indexer/solana/fetcher/transactions\";\nimport { transactionToLegs } from \"@tx-indexer/solana/mappers/transaction-to-legs\";\nimport { classifyTransaction } from \"@tx-indexer/classification/engine/classification-service\";\nimport { detectProtocol } from \"@tx-indexer/classification/protocols/detector\";\nimport { filterSpamTransactions, type SpamFilterConfig } from \"@tx-indexer/core/tx/spam-filter\";\nimport type { WalletBalance } from \"@tx-indexer/solana/fetcher/balances\";\nimport type { RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\n\n/**\n * Configuration options for creating a transaction indexer.\n * \n * Use either `rpcUrl` to let the SDK create a client, or provide an existing `client`\n * to share connections across your application.\n */\nexport type TxIndexerOptions =\n | { \n /** Solana RPC URL (SDK creates a new client) */\n rpcUrl: string; \n /** Optional WebSocket URL for subscriptions */\n wsUrl?: string;\n }\n | { \n /** Existing Solana client to reuse (shares connections) */\n client: SolanaClient;\n };\n\n/**\n * Options for fetching and filtering transaction history.\n */\nexport interface GetTransactionsOptions {\n /** Maximum number of transactions to return (default: 10) */\n limit?: number;\n /** Fetch transactions before this signature (for pagination) */\n before?: Signature;\n /** Fetch transactions until this signature (for pagination) */\n until?: Signature;\n /** Whether to filter out spam transactions (default: true) */\n filterSpam?: boolean;\n /** Custom spam filter configuration */\n spamConfig?: SpamFilterConfig;\n}\n\n/**\n * A fully classified transaction with raw data, classification metadata, and accounting legs.\n */\nexport interface ClassifiedTransaction {\n /** Raw transaction data from the blockchain */\n tx: RawTransaction;\n /** Classification metadata (type, direction, amounts, counterparty) */\n classification: TransactionClassification;\n /** Accounting legs representing all balance movements */\n legs: ReturnType<typeof transactionToLegs>;\n}\n\n/**\n * Transaction indexer client for querying and classifying Solana transactions.\n * \n * Provides methods to fetch wallet balances, transaction history, and individual transactions\n * with automatic protocol detection and classification.\n */\nexport interface TxIndexer {\n /** Direct access to the underlying Solana RPC client */\n rpc: ReturnType<typeof createSolanaClient>[\"rpc\"];\n \n /**\n * Fetches the SOL and SPL token balances for a wallet.\n * \n * @param walletAddress - Wallet address to query balances for\n * @param tokenMints - Optional array of token mint addresses to filter\n * @returns Wallet balance data including SOL and token balances\n */\n getBalance(\n walletAddress: Address,\n tokenMints?: readonly string[]\n ): Promise<WalletBalance>;\n \n /**\n * Fetches and classifies transaction history for a wallet.\n * \n * @param walletAddress - Wallet address to fetch transaction history for\n * @param options - Configuration options for fetching and filtering\n * @returns Array of classified transactions with full metadata\n */\n getTransactions(\n walletAddress: Address,\n options?: GetTransactionsOptions\n ): Promise<ClassifiedTransaction[]>;\n \n /**\n * Fetches and classifies a single transaction by its signature.\n * \n * @param signature - Transaction signature to fetch\n * @param walletAddress - Optional wallet address for classification perspective.\n * When omitted, returns classification from observer mode (neutral perspective).\n * @returns Classified transaction with full metadata, or null if transaction not found\n */\n getTransaction(\n signature: Signature,\n walletAddress?: Address\n ): Promise<ClassifiedTransaction | null>;\n \n /**\n * Fetches a raw transaction without classification.\n * \n * @param signature - Transaction signature to fetch\n * @returns Raw transaction data from the blockchain, or null if not found\n */\n getRawTransaction(signature: Signature): Promise<RawTransaction | null>;\n}\n\n/**\n * Creates a transaction indexer client for querying and classifying Solana transactions.\n * \n * Accepts either an RPC URL (SDK creates client) or an existing SolanaClient (for sharing\n * connections across your app or with React providers).\n * \n * @param options - Configuration with RPC URL or existing client\n * @returns Transaction indexer client\n * \n * @example\n * // Option 1: SDK creates client\n * const indexer = createIndexer({ rpcUrl: \"https://api.mainnet-beta.solana.com\" });\n * \n * @example\n * // Option 2: Provide existing client (share connections)\n * const myClient = createSolanaClient(\"https://...\");\n * const indexer = createIndexer({ client: myClient });\n */\nexport function createIndexer(options: TxIndexerOptions): TxIndexer {\n const client = \"client\" in options\n ? options.client\n : createSolanaClient(options.rpcUrl, options.wsUrl);\n\n return {\n rpc: client.rpc,\n\n async getBalance(\n walletAddress: Address,\n tokenMints?: readonly string[]\n ): Promise<WalletBalance> {\n return fetchWalletBalance(client.rpc, walletAddress, tokenMints);\n },\n\n async getTransactions(\n walletAddress: Address,\n options: GetTransactionsOptions = {}\n ): Promise<ClassifiedTransaction[]> {\n const { limit = 10, before, until, filterSpam = true, spamConfig } = options;\n\n // If spam filtering is disabled, use original behavior (single fetch)\n if (!filterSpam) {\n const signatures = await fetchWalletSignatures(client.rpc, walletAddress, {\n limit,\n before,\n until,\n });\n\n if (signatures.length === 0) {\n return [];\n }\n\n const signatureObjects = signatures.map((sig) =>\n parseSignature(sig.signature)\n );\n const transactions = await fetchTransactionsBatch(\n client.rpc,\n signatureObjects\n );\n\n const classified = transactions.map((tx) => {\n tx.protocol = detectProtocol(tx.programIds);\n const legs = transactionToLegs(tx, walletAddress);\n const classification = classifyTransaction(legs, walletAddress, tx);\n return { tx, classification, legs };\n });\n\n return classified;\n }\n\n const accumulated: ClassifiedTransaction[] = [];\n let currentBefore = before;\n const MAX_ITERATIONS = 10;\n let iteration = 0;\n\n while (accumulated.length < limit && iteration < MAX_ITERATIONS) {\n iteration++;\n\n const batchSize = iteration === 1 ? limit : limit * 2;\n\n const signatures = await fetchWalletSignatures(client.rpc, walletAddress, {\n limit: batchSize,\n before: currentBefore,\n until,\n });\n\n if (signatures.length === 0) {\n break;\n }\n\n const signatureObjects = signatures.map((sig) =>\n parseSignature(sig.signature)\n );\n const transactions = await fetchTransactionsBatch(\n client.rpc,\n signatureObjects\n );\n\n const classified = transactions.map((tx) => {\n tx.protocol = detectProtocol(tx.programIds);\n const legs = transactionToLegs(tx, walletAddress);\n const classification = classifyTransaction(legs, walletAddress, tx);\n return { tx, classification, legs };\n });\n\n const nonSpam = filterSpamTransactions(classified, spamConfig);\n accumulated.push(...nonSpam);\n\n const lastSignature = signatures[signatures.length - 1];\n if (lastSignature) {\n currentBefore = parseSignature(lastSignature.signature);\n } else {\n break;\n }\n }\n\n return accumulated.slice(0, limit);\n },\n\n async getTransaction(\n signature: Signature,\n walletAddress?: Address\n ): Promise<ClassifiedTransaction | null> {\n const tx = await fetchTransaction(client.rpc, signature);\n\n if (!tx) {\n return null;\n }\n\n tx.protocol = detectProtocol(tx.programIds);\n\n const legs = transactionToLegs(tx, walletAddress);\n const classification = classifyTransaction(legs, walletAddress, tx);\n\n return { tx, classification, legs };\n },\n\n async getRawTransaction(signature: Signature): Promise<RawTransaction | null> {\n return fetchTransaction(client.rpc, signature);\n },\n };\n}\n","import type { TxLeg } from \"./tx.types\";\n\nexport interface LegTokenBalance {\n debits: number;\n credits: number;\n diff: number;\n}\n\nexport interface LegBalanceResult {\n isBalanced: boolean;\n byToken: Record<string, LegTokenBalance>;\n}\n\n/**\n * Validates that transaction legs balance according to double-entry accounting.\n * \n * For each token, verifies that total debits equal total credits (within a small tolerance\n * for floating-point precision). This ensures the transaction legs accurately represent\n * all balance movements.\n * \n * @param legs - Array of transaction legs to validate\n * @returns Validation result with per-token balance information\n */\nexport function validateLegsBalance(legs: TxLeg[]): LegBalanceResult {\n const byToken: Record<string, { debits: number; credits: number }> = {};\n\n for (const leg of legs) {\n const token = leg.amount.token.symbol;\n if (!byToken[token]) {\n byToken[token] = { debits: 0, credits: 0 };\n }\n\n if (leg.side === \"debit\") {\n byToken[token].debits += leg.amount.amountUi;\n } else {\n byToken[token].credits += leg.amount.amountUi;\n }\n }\n\n const result: Record<string, LegTokenBalance> = {};\n let isBalanced = true;\n\n for (const [token, amounts] of Object.entries(byToken)) {\n const diff = Math.abs(amounts.debits - amounts.credits);\n result[token] = { ...amounts, diff };\n\n if (diff > 0.000001) {\n isBalanced = false;\n }\n }\n\n return { isBalanced, byToken: result };\n}\n\n/**\n * Groups transaction legs by account ID.\n * \n * Useful for analyzing all balance movements for a specific account or\n * understanding counterparty interactions in a transaction.\n * \n * @param legs - Array of transaction legs to group\n * @returns Map of account IDs to their associated legs\n */\nexport function groupLegsByAccount(legs: TxLeg[]): Record<string, TxLeg[]> {\n const grouped: Record<string, TxLeg[]> = {};\n\n for (const leg of legs) {\n if (!grouped[leg.accountId]) {\n grouped[leg.accountId] = [];\n }\n grouped[leg.accountId]!.push(leg);\n }\n\n return grouped;\n}\n\n/**\n * Groups transaction legs by token symbol.\n * \n * Useful for analyzing all movements of a specific token or calculating\n * total amounts exchanged for each asset in the transaction.\n * \n * @param legs - Array of transaction legs to group\n * @returns Map of token symbols to their associated legs\n */\nexport function groupLegsByToken(legs: TxLeg[]): Record<string, TxLeg[]> {\n const grouped: Record<string, TxLeg[]> = {};\n\n for (const leg of legs) {\n const token = leg.amount.token.symbol;\n if (!grouped[token]) {\n grouped[token] = [];\n }\n grouped[token]!.push(leg);\n }\n\n return grouped;\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../solana/src/rpc/client.ts","../../domain/src/money/token-registry.ts","../../solana/src/fetcher/balances.ts","../../solana/src/mappers/transaction-mapper.ts","../../solana/src/constants/program-ids.ts","../../../node_modules/.bun/base-x@5.0.1/node_modules/base-x/src/esm/index.js","../../../node_modules/.bun/bs58@6.0.0/node_modules/bs58/src/esm/index.js","../../solana/src/mappers/memo-parser.ts","../../solana/src/fetcher/transactions.ts","../../domain/src/tx/account-id.ts","../../solana/src/mappers/balance-parser.ts","../../solana/src/constants/protocol-constants.ts","../../solana/src/mappers/transaction-to-legs.ts","../../classification/src/classifiers/transfer-classifier.ts","../../classification/src/protocols/detector.ts","../../classification/src/classifiers/swap-classifier.ts","../../classification/src/classifiers/airdrop-classifier.ts","../../classification/src/classifiers/fee-only-classifier.ts","../../classification/src/classifiers/solana-pay-classifier.ts","../../classification/src/classifiers/nft-mint-classifier.ts","../../classification/src/classifiers/stake-deposit-classifier.ts","../../classification/src/classifiers/stake-withdraw-classifier.ts","../../classification/src/classifiers/bridge-classifier.ts","../../classification/src/engine/classification-service.ts","../../domain/src/tx/spam-filter.ts","../src/client.ts","../../domain/src/tx/leg-validation.ts"],"names":["address","ALPHABET","esm_default","signature","DEX_PROTOCOL_IDS","options"],"mappings":"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","file":"index.js","sourcesContent":["import {\n createSolanaRpc,\n createSolanaRpcSubscriptions,\n type Rpc,\n type RpcSubscriptions,\n type GetBalanceApi,\n type GetTokenAccountsByOwnerApi,\n type GetSignaturesForAddressApi,\n type GetTransactionApi,\n address,\n type Address,\n signature,\n type Signature,\n} from \"@solana/kit\";\n\n/**\n * Union type of all RPC APIs used by the transaction indexer.\n * \n * This ensures type safety when calling RPC methods while maintaining\n * flexibility for the complete indexer API surface.\n */\nexport type IndexerRpcApi = GetBalanceApi \n & GetTokenAccountsByOwnerApi \n & GetSignaturesForAddressApi \n & GetTransactionApi;\n\nexport interface SolanaClient {\n rpc: Rpc<IndexerRpcApi>;\n rpcSubscriptions: RpcSubscriptions<any>;\n}\n\n/**\n * Creates a Solana RPC client with both regular RPC and WebSocket subscriptions.\n * \n * @param rpcUrl - HTTP RPC endpoint URL\n * @param wsUrl - Optional WebSocket URL (defaults to rpcUrl with wss:// protocol)\n */\nexport function createSolanaClient(\n rpcUrl: string,\n wsUrl?: string\n): SolanaClient {\n const rpc = createSolanaRpc(rpcUrl);\n const rpcSubscriptions = wsUrl\n ? createSolanaRpcSubscriptions(wsUrl)\n : createSolanaRpcSubscriptions(rpcUrl.replace(\"https://\", \"wss://\"));\n\n return { rpc, rpcSubscriptions };\n}\n\n/**\n * Parses and validates a Solana address string.\n * \n * @param addr - Base58-encoded Solana address\n */\nexport function parseAddress(addr: string): Address {\n return address(addr);\n}\n\n/**\n * Parses and validates a Solana transaction signature string.\n * \n * @param sig - Base58-encoded transaction signature\n */\nexport function parseSignature(sig: string): Signature {\n return signature(sig);\n}\n\n","import type { TokenInfo } from \"./money.types\";\n\nexport const KNOWN_TOKENS = {\n SOL: \"So11111111111111111111111111111111111111112\",\n USDC: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n USDC_BRIDGED: \"A9mUU4qviSctJVPJdBJWkb28deg915LYJKrzQ19ji3FM\",\n USDG: \"2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH\",\n} as const;\n\nexport const TOKEN_INFO: Record<string, TokenInfo> = {\n [KNOWN_TOKENS.SOL]: {\n mint: KNOWN_TOKENS.SOL,\n symbol: \"SOL\",\n name: \"Solana\",\n decimals: 9,\n logoURI:\n \"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png\",\n },\n [KNOWN_TOKENS.USDC]: {\n mint: KNOWN_TOKENS.USDC,\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n logoURI:\n \"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png\",\n },\n [KNOWN_TOKENS.USDC_BRIDGED]: {\n mint: KNOWN_TOKENS.USDC_BRIDGED,\n symbol: \"USDCet\",\n name: \"USDC (Bridged)\",\n decimals: 6,\n },\n [KNOWN_TOKENS.USDG]: {\n mint: KNOWN_TOKENS.USDG,\n symbol: \"USDG\",\n name: \"USD Glitter\",\n decimals: 6,\n },\n};\n\nexport function getTokenInfo(mint: string): TokenInfo | undefined {\n return TOKEN_INFO[mint];\n}\n\nexport function isSupportedToken(mint: string): boolean {\n return mint in TOKEN_INFO;\n}\n\nexport const SUPPORTED_STABLECOINS = [\n KNOWN_TOKENS.USDC,\n KNOWN_TOKENS.USDC_BRIDGED,\n KNOWN_TOKENS.USDG,\n] as const;\n\nexport const TRACKED_TOKENS = [\n KNOWN_TOKENS.SOL,\n KNOWN_TOKENS.USDC,\n] as const;\n\n","import {\n type Address,\n type Rpc,\n type GetBalanceApi,\n type GetTokenAccountsByOwnerApi,\n address,\n} from \"@solana/kit\";\n\nimport { getTokenInfo, KNOWN_TOKENS } from \"@tx-indexer/core/money/token-registry\";\n\nexport interface WalletBalance {\n address: string;\n sol: {\n lamports: bigint;\n ui: number;\n };\n tokens: TokenAccountBalance[];\n}\n\nexport interface TokenAccountBalance {\n mint: string;\n tokenAccount?: string;\n amount: {\n raw: string;\n ui: number;\n };\n decimals: number;\n symbol: string;\n}\n\n/**\n * Fetches wallet balance including SOL and SPL tokens\n *\n * @param rpc - Solana RPC client\n * @param walletAddress - Wallet address to query\n * @param tokenMints - Optional array of token mint addresses to track. If omitted, returns all tokens in wallet\n * @returns Wallet balance data with SOL and token balances\n *\n * @example\n * // Fetch all tokens\n * const allBalances = await fetchWalletBalance(rpc, address);\n *\n * @example\n * // Fetch specific tokens only\n * const usdcOnly = await fetchWalletBalance(rpc, address, [\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"]);\n */\nexport async function fetchWalletBalance(\n rpc: Rpc<GetBalanceApi & GetTokenAccountsByOwnerApi>,\n walletAddress: Address,\n tokenMints?: readonly string[]\n): Promise<WalletBalance> {\n const balanceResponse = await rpc.getBalance(walletAddress).send();\n const lamports = balanceResponse.value;\n\n const tokenAccounts = await fetchTokenAccounts(rpc, walletAddress);\n\n const tokens = tokenMints\n ? filterToTrackedTokens(tokenAccounts, tokenMints)\n : Array.from(tokenAccounts.values());\n\n return {\n address: walletAddress,\n sol: {\n lamports,\n ui: Number(lamports) / 1e9,\n },\n tokens,\n };\n}\n\nasync function fetchTokenAccounts(\n rpc: Rpc<GetBalanceApi & GetTokenAccountsByOwnerApi>,\n walletAddress: Address\n): Promise<Map<string, TokenAccountBalance>> {\n const accountsMap = new Map<string, TokenAccountBalance>();\n\n try {\n const response = await rpc\n .getTokenAccountsByOwner(\n walletAddress,\n { programId: address(\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\") },\n { encoding: \"jsonParsed\" }\n )\n .send();\n\n for (const account of response.value) {\n const parsedInfo = account.account.data.parsed.info;\n const mint = parsedInfo.mint;\n\n const tokenInfo = getTokenInfo(mint);\n const symbol = tokenInfo?.symbol || mint.substring(0, 8);\n\n accountsMap.set(mint, {\n mint,\n tokenAccount: account.pubkey.toString(),\n amount: {\n raw: parsedInfo.tokenAmount.amount,\n ui: parsedInfo.tokenAmount.uiAmountString\n ? parseFloat(parsedInfo.tokenAmount.uiAmountString)\n : 0,\n },\n decimals: parsedInfo.tokenAmount.decimals,\n symbol,\n });\n }\n } catch (error) {\n console.error(\"Error fetching token accounts:\", error);\n }\n\n return accountsMap;\n}\n\n/**\n * Filters token accounts to only include specified mints, adding zero balances for missing tokens\n *\n * @param fetchedAccounts - Map of mint addresses to token balances from RPC\n * @param tokenMints - Array of token mint addresses to include in results\n */\nfunction filterToTrackedTokens(\n fetchedAccounts: Map<string, TokenAccountBalance>,\n tokenMints: readonly string[]\n): TokenAccountBalance[] {\n const result: TokenAccountBalance[] = [];\n\n for (const mint of tokenMints) {\n if (mint === KNOWN_TOKENS.SOL) continue;\n\n const existing = fetchedAccounts.get(mint);\n if (existing) {\n result.push(existing);\n } else {\n const tokenInfo = getTokenInfo(mint);\n if (tokenInfo) {\n result.push({\n mint,\n amount: {\n raw: \"0\",\n ui: 0,\n },\n decimals: tokenInfo.decimals,\n symbol: tokenInfo.symbol,\n });\n }\n }\n }\n\n return result;\n}\n\nexport function formatBalance(balance: WalletBalance): string[] {\n const lines: string[] = [];\n\n lines.push(`Wallet: ${balance.address}`);\n lines.push(`SOL: ${balance.sol.ui.toFixed(9)}`);\n\n for (const token of balance.tokens) {\n lines.push(`${token.symbol}: ${token.amount.ui.toFixed(token.decimals)}`);\n }\n\n return lines;\n}\n","import type { SolanaTransaction } from \"@tx-indexer/solana/types/transaction.types\";\n\n/**\n * Extracts all unique program IDs from a transaction.\n *\n * @param transaction - Raw transaction object from RPC\n * @returns Array of program ID strings\n */\nexport function extractProgramIds(transaction: SolanaTransaction): string[] {\n const programIds = new Set<string>();\n\n const { message } = transaction;\n const { accountKeys, instructions } = message;\n\n for (const ix of instructions) {\n const { programIdIndex } = ix;\n if (programIdIndex !== undefined && accountKeys[programIdIndex]) {\n const key = accountKeys[programIdIndex];\n programIds.add(key.toString());\n }\n }\n\n return Array.from(programIds);\n}\n","/**\n * Solana Program IDs\n * \n * Centralized registry of known Solana program addresses.\n * These are public keys that identify on-chain programs.\n */\n\n// ============================================\n// Core Solana Programs\n// ============================================\n\nexport const SYSTEM_PROGRAM_ID = \"11111111111111111111111111111111\";\nexport const COMPUTE_BUDGET_PROGRAM_ID = \"ComputeBudget111111111111111111111111111111\";\nexport const STAKE_PROGRAM_ID = \"Stake11111111111111111111111111111111111111\";\nexport const STAKE_POOL_PROGRAM_ID = \"SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy\";\n\n// ============================================\n// Token Programs\n// ============================================\n\nexport const TOKEN_PROGRAM_ID = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nexport const ASSOCIATED_TOKEN_PROGRAM_ID = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\n\n// ============================================\n// Memo Programs\n// ============================================\n\nexport const SPL_MEMO_PROGRAM_ID = \"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\";\nexport const MEMO_V1_PROGRAM_ID = \"Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo\";\n\n// ============================================\n// DeFi Programs\n// ============================================\n\nexport const JUPITER_V6_PROGRAM_ID = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nexport const JUPITER_V4_PROGRAM_ID = \"JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB\";\nexport const RAYDIUM_PROGRAM_ID = \"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\";\nexport const ORCA_WHIRLPOOL_PROGRAM_ID = \"whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc\";\n\n// ============================================\n// NFT Programs\n// ============================================\n\nexport const METAPLEX_PROGRAM_ID = \"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\";\nexport const CANDY_MACHINE_V3_PROGRAM_ID = \"CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR\";\nexport const CANDY_GUARD_PROGRAM_ID = \"Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g\";\nexport const BUBBLEGUM_PROGRAM_ID = \"BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY\";\nexport const MAGIC_EDEN_CANDY_MACHINE_ID = \"CMZYPASGWeTz7RNGHaRJfCq2XQ5pYK6nDvVQxzkH51zb\";\n\n// ============================================\n// Bridge Programs\n// ============================================\n\nexport const WORMHOLE_PROGRAM_ID = \"worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth\";\nexport const WORMHOLE_TOKEN_BRIDGE_ID = \"wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb\";\nexport const DEGODS_BRIDGE_PROGRAM_ID = \"35iLrpYNNR9ygHLcvE1xKFHbHq6paHthrF6wSovdWgGu\";\nexport const DEBRIDGE_PROGRAM_ID = \"DEbrdGj3HsRsAzx6uH4MKyREKxVAfBydijLUF3ygsFfh\";\nexport const ALLBRIDGE_PROGRAM_ID = \"BrdgN2RPzEMWF96ZbnnJaUtQDQx7VRXYaHHbYCBvceWB\";\n\n// ============================================\n// Payment Facilitators\n// ============================================\n\nexport const PAYAI_FACILITATOR = \"2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHDBg4\";\n\n// ============================================\n// Helper Collections\n// ============================================\n\nexport const MEMO_PROGRAM_IDS = [\n SPL_MEMO_PROGRAM_ID,\n MEMO_V1_PROGRAM_ID,\n] as const;\n\nexport const TOKEN_PROGRAM_IDS = [\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n] as const;\n\nexport const DEX_PROGRAM_IDS = [\n JUPITER_V6_PROGRAM_ID,\n JUPITER_V4_PROGRAM_ID,\n RAYDIUM_PROGRAM_ID,\n ORCA_WHIRLPOOL_PROGRAM_ID,\n] as const;\n\nexport const NFT_PROGRAM_IDS = [\n METAPLEX_PROGRAM_ID,\n CANDY_MACHINE_V3_PROGRAM_ID,\n CANDY_GUARD_PROGRAM_ID,\n BUBBLEGUM_PROGRAM_ID,\n MAGIC_EDEN_CANDY_MACHINE_ID,\n] as const;\n\nexport const BRIDGE_PROGRAM_IDS = [\n WORMHOLE_PROGRAM_ID,\n WORMHOLE_TOKEN_BRIDGE_ID,\n DEGODS_BRIDGE_PROGRAM_ID,\n DEBRIDGE_PROGRAM_ID,\n ALLBRIDGE_PROGRAM_ID,\n] as const;\n\nexport const KNOWN_FACILITATORS = [\n PAYAI_FACILITATOR,\n] as const;\n\nexport function detectFacilitator(accountKeys: string[]): string | null {\n for (const facilitator of KNOWN_FACILITATORS) {\n if (accountKeys.includes(facilitator)) {\n if (facilitator === PAYAI_FACILITATOR) {\n return \"payai\";\n }\n }\n }\n return null;\n}\n\n","// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n // eslint-disable-next-line no-empty\n if (source instanceof Uint8Array) { } else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source)\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n let zeroes = 0\n let length = 0\n let pbegin = 0\n const pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n let i = 0\n for (let it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n let it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n let str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n let psz = 0\n // Skip and count leading '1's.\n let zeroes = 0\n let length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n const b256 = new Uint8Array(size)\n // Process the characters.\n while (psz < source.length) {\n // Find code of next character\n const charCode = source.charCodeAt(psz)\n // Base map can not be indexed using char code\n if (charCode > 255) { return }\n // Decode character\n let carry = BASE_MAP[charCode]\n // Invalid character\n if (carry === 255) { return }\n let i = 0\n for (let it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip leading zeroes in b256.\n let it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n const vch = new Uint8Array(zeroes + (size - it4))\n let j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n const buffer = decodeUnsafe(string)\n if (buffer) { return buffer }\n throw new Error('Non-base' + BASE + ' character')\n }\n return {\n encode,\n decodeUnsafe,\n decode\n }\n}\nexport default base\n","import basex from 'base-x';\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\nexport default basex(ALPHABET);\n","import type { SolanaTransaction } from \"@tx-indexer/solana/types/transaction.types\";\nimport {\n SPL_MEMO_PROGRAM_ID,\n MEMO_V1_PROGRAM_ID,\n} from \"@tx-indexer/solana/constants/program-ids\";\nimport bs58 from \"bs58\";\n\ninterface TransactionWithLogs extends SolanaTransaction {\n meta?: {\n logMessages?: readonly string[] | null;\n };\n}\n\nfunction decodeMemoData(base64Data: string): string {\n const buffer = Buffer.from(base64Data, \"base64\");\n\n const text = buffer.toString(\"utf-8\");\n if (!text.includes(\"\\ufffd\") && /^[\\x20-\\x7E\\s]*$/.test(text)) {\n return text;\n }\n\n if (buffer.length === 32) {\n return bs58.encode(buffer);\n }\n\n if (buffer.length % 32 === 0 && buffer.length > 0) {\n const addresses: string[] = [];\n for (let i = 0; i < buffer.length; i += 32) {\n const chunk = buffer.subarray(i, i + 32);\n addresses.push(bs58.encode(chunk));\n }\n return addresses.join(\", \");\n }\n\n if (buffer.length >= 16) {\n const uuidBytes = buffer.subarray(0, 16);\n const uuid = [\n uuidBytes.subarray(0, 4).toString(\"hex\"),\n uuidBytes.subarray(4, 6).toString(\"hex\"),\n uuidBytes.subarray(6, 8).toString(\"hex\"),\n uuidBytes.subarray(8, 10).toString(\"hex\"),\n uuidBytes.subarray(10, 16).toString(\"hex\"),\n ].join(\"-\");\n\n if (buffer.length === 16) {\n return `Product: ${uuid}`;\n }\n\n const extraData = buffer.subarray(16);\n const extraHex = extraData.toString(\"hex\");\n return `Product: ${uuid} | Meta: ${extraHex}`;\n }\n\n return bs58.encode(buffer);\n}\n\n/**\n * Extracts memo data from a Solana transaction.\n * \n * First attempts to extract human-readable memos from program logs, which contain\n * the decoded text. Falls back to parsing memo program instructions for binary data.\n * Handles various memo formats including UTF-8 text, public keys, and Solana Pay metadata.\n * \n * @param transaction - Solana transaction with message and optional logs\n * @returns Extracted memo string, or null if no memo is found\n */\nexport function extractMemo(transaction: TransactionWithLogs): string | null {\n if (transaction.meta?.logMessages) {\n const memoLogPattern = /Program log: Memo \\(len \\d+\\): \"(.+)\"/;\n for (const log of transaction.meta.logMessages) {\n const match = log.match(memoLogPattern);\n if (match?.[1]) {\n return match[1];\n }\n }\n }\n\n const { message } = transaction;\n const { accountKeys, instructions } = message;\n\n for (const ix of instructions) {\n const programId = accountKeys[ix.programIdIndex]?.toString();\n\n if (programId === SPL_MEMO_PROGRAM_ID || programId === MEMO_V1_PROGRAM_ID) {\n if (ix.data) {\n try {\n return decodeMemoData(ix.data);\n } catch (e) {\n console.warn(\"Failed to decode memo:\", e);\n }\n }\n }\n }\n\n return null;\n}\n\nexport interface SolanaPayMemo {\n merchant?: string;\n item?: string;\n reference?: string;\n label?: string;\n message?: string;\n raw: string;\n}\n\n/**\n * Parses a Solana Pay memo string into structured fields.\n * \n * Attempts to parse the memo as JSON to extract merchant, item, reference,\n * label, and message fields. Falls back to returning just the raw memo if parsing fails.\n * \n * @param memo - Memo string to parse\n * @returns Parsed Solana Pay memo object with raw memo included\n */\nexport function parseSolanaPayMemo(memo: string): SolanaPayMemo {\n try {\n const parsed = JSON.parse(memo);\n return { ...parsed, raw: memo };\n } catch {\n return { raw: memo };\n }\n}\n\n/**\n * Determines if a transaction is a Solana Pay transaction.\n * \n * A transaction is considered Solana Pay if it includes the SPL Memo program\n * and has a non-null memo. Solana Pay uses memos to attach payment metadata.\n * \n * @param programIds - Program IDs involved in the transaction\n * @param memo - Extracted memo from the transaction\n * @returns True if this is a Solana Pay transaction\n */\nexport function isSolanaPayTransaction(\n programIds: string[],\n memo: string | null | undefined\n): boolean {\n const hasMemoProgram =\n programIds.includes(SPL_MEMO_PROGRAM_ID) ||\n programIds.includes(MEMO_V1_PROGRAM_ID);\n\n return hasMemoProgram && memo !== null && memo !== undefined;\n}\n","import type {\n Address,\n Rpc,\n Signature,\n GetSignaturesForAddressApi,\n GetTransactionApi,\n} from \"@solana/kit\";\nimport type { RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport { extractProgramIds } from \"@tx-indexer/solana/mappers/transaction-mapper\";\nimport { extractMemo } from \"@tx-indexer/solana/mappers/memo-parser\";\n\nexport interface FetchTransactionsConfig {\n limit?: number;\n before?: Signature;\n until?: Signature;\n}\n\n/**\n * Fetches transaction signatures for a wallet address.\n *\n * @param rpc - Solana RPC client\n * @param walletAddress - Wallet address to fetch signatures for\n * @param config - Optional pagination and limit configuration\n * @returns Array of raw transactions with basic metadata only\n */\nexport async function fetchWalletSignatures(\n rpc: Rpc<GetSignaturesForAddressApi>,\n walletAddress: Address,\n config: FetchTransactionsConfig = {}\n): Promise<RawTransaction[]> {\n const { limit = 100, before, until } = config;\n\n const response = await rpc\n .getSignaturesForAddress(walletAddress, {\n limit,\n before,\n until,\n })\n .send();\n\n return response.map((sig) => ({\n signature: sig.signature,\n slot: sig.slot,\n blockTime: sig.blockTime,\n err: sig.err,\n programIds: [],\n protocol: null,\n memo: sig.memo || null,\n }));\n}\n\n/**\n * Fetches a single transaction with full details including program IDs.\n *\n * @param rpc - Solana RPC client\n * @param signature - Transaction signature\n * @param commitment - Commitment level for fetching\n * @returns Full raw transaction with program IDs\n */\nexport async function fetchTransaction(\n rpc: Rpc<GetTransactionApi>,\n signature: Signature,\n commitment: \"confirmed\" | \"finalized\" = \"confirmed\"\n): Promise<RawTransaction | null> {\n const response = await rpc\n .getTransaction(signature, {\n commitment,\n maxSupportedTransactionVersion: 0,\n encoding: \"json\",\n })\n .send();\n\n if (!response) {\n return null;\n }\n\n // Try to get memo from response metadata first (already decoded by RPC)\n // Fall back to manual extraction if not available\n const transactionWithLogs = {\n ...response.transaction,\n meta: { logMessages: response.meta?.logMessages },\n };\n const memo = extractMemo(transactionWithLogs);\n\n return {\n signature,\n slot: response.slot,\n blockTime: response.blockTime,\n err: response.meta?.err ?? null,\n programIds: extractProgramIds(response.transaction),\n protocol: null,\n preTokenBalances: (response.meta?.preTokenBalances ?? []).map((bal) => ({\n accountIndex: bal.accountIndex,\n mint: bal.mint.toString(),\n owner: bal.owner?.toString(),\n programId: bal.programId?.toString(),\n uiTokenAmount: {\n amount: bal.uiTokenAmount.amount.toString(),\n decimals: bal.uiTokenAmount.decimals,\n uiAmountString: bal.uiTokenAmount.uiAmountString.toString(),\n },\n })),\n postTokenBalances: (response.meta?.postTokenBalances ?? []).map((bal) => ({\n accountIndex: bal.accountIndex,\n mint: bal.mint.toString(),\n owner: bal.owner?.toString(),\n programId: bal.programId?.toString(),\n uiTokenAmount: {\n amount: bal.uiTokenAmount.amount.toString(),\n decimals: bal.uiTokenAmount.decimals,\n uiAmountString: bal.uiTokenAmount.uiAmountString.toString(),\n },\n })),\n preBalances: (response.meta?.preBalances ?? []).map((bal) => Number(bal)),\n postBalances: (response.meta?.postBalances ?? []).map((bal) => Number(bal)),\n accountKeys: response.transaction.message.accountKeys.map((key) =>\n key.toString()\n ),\n memo,\n };\n}\n\n/**\n * Fetches multiple transactions in parallel.\n *\n * @param rpc - Solana RPC client\n * @param signatures - Array of transaction signatures\n * @param commitment - Commitment level for fetching\n * @returns Array of full raw transactions (nulls filtered out)\n */\nexport async function fetchTransactionsBatch(\n rpc: Rpc<GetTransactionApi>,\n signatures: Signature[],\n commitment: \"confirmed\" | \"finalized\" = \"confirmed\"\n): Promise<RawTransaction[]> {\n const promises = signatures.map((sig) =>\n fetchTransaction(rpc, sig, commitment)\n );\n const results = await Promise.all(promises);\n return results.filter((tx): tx is RawTransaction => tx !== null);\n}\n","export type AccountIdType = \"wallet\" | \"protocol\" | \"external\" | \"fee\";\n\nexport interface BuildAccountIdParams {\n type: AccountIdType;\n address: string;\n protocol?: string;\n token?: string;\n}\n\n/**\n * Builds a standardized account identifier string for transaction legs.\n * \n * Account IDs follow these formats:\n * - Wallet: `wallet:{address}`\n * - Protocol: `protocol:{protocol}:{token}:{address}` or `protocol:{protocol}:{address}`\n * - External: `external:{address}`\n * - Fee: `fee:network`\n * \n * @param params - Account identifier parameters\n * @returns Formatted account ID string\n * @throws Error if parameters are invalid for the account type\n */\nexport function buildAccountId(params: BuildAccountIdParams): string {\n const { type, address, protocol, token } = params;\n\n if (type === \"wallet\") {\n return `wallet:${address}`;\n }\n\n if (type === \"protocol\" && protocol) {\n if (token) {\n return `protocol:${protocol}:${token}:${address}`;\n }\n return `protocol:${protocol}:${address}`;\n }\n\n if (type === \"external\") {\n return `external:${address}`;\n }\n\n if (type === \"fee\") {\n return \"fee:network\";\n }\n \n throw new Error(\n `Invalid accountId parameters: type=${type}, address=${address}, protocol=${protocol}`\n );\n}\n\nexport interface ParsedAccountId {\n type: AccountIdType | \"unknown\";\n address?: string;\n protocol?: string;\n token?: string;\n}\n\n/**\n * Parses an account identifier string into its components.\n * \n * Extracts the account type, address, protocol, and token information from\n * a formatted account ID string. Returns `unknown` type for unrecognized formats.\n * \n * @param accountId - Account ID string to parse\n * @returns Parsed account identifier with type and optional metadata\n */\nexport function parseAccountId(accountId: string): ParsedAccountId {\n const parts = accountId.split(\":\");\n\n if (parts[0] === \"wallet\" && parts.length === 2) {\n return { type: \"wallet\", address: parts[1] };\n }\n\n if (parts[0] === \"protocol\") {\n if (parts.length === 4) {\n return {\n type: \"protocol\",\n protocol: parts[1],\n token: parts[2],\n address: parts[3],\n };\n }\n if (parts.length === 3) {\n return {\n type: \"protocol\",\n protocol: parts[1],\n address: parts[2],\n };\n }\n }\n\n if (parts[0] === \"external\" && parts.length === 2) {\n return { type: \"external\", address: parts[1] };\n }\n\n if (parts[0] === \"fee\" && parts[1] === \"network\") {\n return { type: \"fee\" };\n }\n\n return { type: \"unknown\", address: accountId };\n}\n","import type { Address } from \"@solana/kit\";\nimport type { RawTransaction, TokenBalance } from \"@tx-indexer/core/tx/tx.types\";\nimport type { MoneyAmount, TokenInfo } from \"@tx-indexer/core/money/money.types\";\nimport {\n getTokenInfo,\n KNOWN_TOKENS,\n TOKEN_INFO,\n} from \"@tx-indexer/core/money/token-registry\";\n\nexport interface TokenBalanceChange {\n mint: string;\n tokenInfo: TokenInfo;\n accountIndex: number;\n owner?: string;\n preBalance: {\n raw: string;\n ui: number;\n };\n postBalance: {\n raw: string;\n ui: number;\n };\n change: {\n raw: string;\n ui: number;\n };\n}\n\nexport interface SolBalanceChange {\n accountIndex: number;\n address: string;\n preBalance: bigint;\n postBalance: bigint;\n change: bigint;\n changeUi: number;\n}\n\n/**\n * Extracts all SPL token balance changes from a transaction.\n * \n * Compares pre and post token balances to calculate the change for each token account.\n * Unknown tokens are automatically included with a generated symbol from their mint address.\n * \n * @param tx - Raw transaction with token balance data\n * @param filterMints - Optional array of mint addresses to filter to specific tokens\n * @returns Array of token balance changes with mint, owner, and amount information\n */\nexport function extractTokenBalanceChanges(\n tx: RawTransaction,\n filterMints?: string[]\n): TokenBalanceChange[] {\n const { preTokenBalances = [], postTokenBalances = [] } = tx;\n\n const changes: TokenBalanceChange[] = [];\n\n const preBalanceMap = new Map<number, TokenBalance>();\n for (const bal of preTokenBalances) {\n preBalanceMap.set(bal.accountIndex, bal);\n }\n\n for (const postBal of postTokenBalances) {\n const { accountIndex, mint } = postBal;\n\n if (filterMints && !filterMints.includes(mint)) {\n continue;\n }\n\n let tokenInfo = getTokenInfo(mint);\n if (!tokenInfo) {\n tokenInfo = {\n mint,\n symbol: mint.slice(0, 8),\n decimals: postBal.uiTokenAmount.decimals,\n name: `Unknown Token (${mint.slice(0, 8)}...)`,\n };\n }\n\n const preBal = preBalanceMap.get(accountIndex);\n\n const preAmount = preBal?.uiTokenAmount.amount ?? \"0\";\n const postAmount = postBal.uiTokenAmount.amount;\n const preUi = preBal?.uiTokenAmount.uiAmountString\n ? parseFloat(preBal.uiTokenAmount.uiAmountString)\n : 0;\n const postUi = postBal.uiTokenAmount.uiAmountString\n ? parseFloat(postBal.uiTokenAmount.uiAmountString)\n : 0;\n\n const changeRaw = (BigInt(postAmount) - BigInt(preAmount)).toString();\n const changeUi = postUi - preUi;\n\n if (changeRaw !== \"0\") {\n changes.push({\n mint,\n tokenInfo,\n accountIndex,\n owner: postBal.owner,\n preBalance: {\n raw: preAmount,\n ui: preUi,\n },\n postBalance: {\n raw: postAmount,\n ui: postUi,\n },\n change: {\n raw: changeRaw,\n ui: changeUi,\n },\n });\n }\n }\n\n return changes;\n}\n\n/**\n * Extracts SOL balance changes for all accounts in a transaction.\n * \n * Compares pre and post lamport balances for each account key to calculate\n * the SOL change. Only includes accounts with non-zero changes.\n * \n * @param tx - Raw transaction with SOL balance data\n * @returns Array of SOL balance changes with account address and amounts\n */\nexport function extractSolBalanceChanges(\n tx: RawTransaction\n): SolBalanceChange[] {\n const {\n preBalances = [],\n postBalances = [],\n accountKeys = [],\n } = tx;\n\n const changes: SolBalanceChange[] = [];\n\n for (let i = 0; i < accountKeys.length; i++) {\n const address = accountKeys[i];\n if (!address) continue;\n\n const preBal = BigInt(preBalances[i] ?? 0);\n const postBal = BigInt(postBalances[i] ?? 0);\n const change = postBal - preBal;\n\n if (change !== 0n) {\n changes.push({\n accountIndex: i,\n address,\n preBalance: preBal,\n postBalance: postBal,\n change,\n changeUi: Number(change) / 1e9,\n });\n }\n }\n\n return changes;\n}\n\nexport function getWalletTokenChanges(\n tx: RawTransaction,\n walletAddress: Address,\n filterMints?: string[]\n): TokenBalanceChange[] {\n const allChanges = extractTokenBalanceChanges(tx, filterMints);\n\n return allChanges.filter(\n (change) =>\n change.owner?.toLowerCase() === walletAddress.toLowerCase()\n );\n}\n\nexport function getWalletSolChange(\n tx: RawTransaction,\n walletAddress: Address\n): SolBalanceChange | null {\n if (!tx.accountKeys || tx.accountKeys.length === 0) {\n return null;\n }\n\n const allChanges = extractSolBalanceChanges(tx);\n\n return (\n allChanges.find(\n (change) => change.address.toLowerCase() === walletAddress.toLowerCase()\n ) ?? null\n );\n}\n\nexport function toMoneyAmount(change: TokenBalanceChange): MoneyAmount {\n return {\n token: change.tokenInfo,\n amountRaw: change.change.raw,\n amountUi: change.change.ui,\n };\n}\n\nexport function solChangeToMoneyAmount(change: SolBalanceChange): MoneyAmount {\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (!solInfo) {\n throw new Error(\"SOL token info not found in registry\");\n }\n return {\n token: solInfo,\n amountRaw: change.change.toString(),\n amountUi: change.changeUi,\n };\n}\n\n","/**\n * Constants for DEX protocol detection\n */\n\nexport const DEX_PROTOCOL_IDS = new Set([\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n]);\n\n","import type { RawTransaction, TxLeg, TxLegRole } from \"@tx-indexer/core/tx/tx.types\";\nimport type { ProtocolInfo } from \"@tx-indexer/core/actors/counterparty.types\";\nimport { buildAccountId } from \"@tx-indexer/core/tx/account-id\";\nimport {\n extractSolBalanceChanges,\n extractTokenBalanceChanges,\n type SolBalanceChange,\n type TokenBalanceChange,\n} from \"./balance-parser\";\nimport { KNOWN_TOKENS, TOKEN_INFO } from \"@tx-indexer/core/money/token-registry\";\nimport { DEX_PROTOCOL_IDS } from \"../constants/protocol-constants\";\n\nfunction isDexProtocol(protocol: ProtocolInfo | null | undefined): boolean {\n return protocol !== null && protocol !== undefined && DEX_PROTOCOL_IDS.has(protocol.id);\n}\n\n/**\n * Converts a raw Solana transaction into a double-entry accounting ledger.\n *\n * Creates TxLeg entries for all SOL and token balance changes, automatically\n * detecting and accounting for network fees. Each leg represents a debit or credit\n * for a specific account and token, enabling transaction classification and validation.\n *\n * All accounts are tagged as \"external:\" - the classification layer determines\n * the transaction type and direction from the initiator's (fee payer's) perspective.\n *\n * @param tx - Raw transaction data with balance changes\n * @returns Array of transaction legs representing all balance movements\n */\nexport function transactionToLegs(tx: RawTransaction): TxLeg[] {\n const legs: TxLeg[] = [];\n const feePayer = tx.accountKeys?.[0]?.toLowerCase();\n\n const solChanges = extractSolBalanceChanges(tx);\n let totalSolDebits = 0n;\n let totalSolCredits = 0n;\n\n for (const change of solChanges) {\n if (change.change === 0n) continue;\n\n const accountId = buildAccountId({\n type: \"external\",\n address: change.address,\n });\n\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (!solInfo) {\n throw new Error(\"SOL token info not found in registry\");\n }\n\n if (change.change > 0n) {\n totalSolCredits += change.change;\n } else {\n totalSolDebits += -change.change;\n }\n\n legs.push({\n accountId,\n side: change.change > 0n ? \"credit\" : \"debit\",\n amount: {\n token: solInfo,\n amountRaw: change.change.toString().replace(\"-\", \"\"),\n amountUi: Math.abs(change.changeUi),\n },\n role: determineSolRole(change, tx, feePayer),\n });\n }\n\n const networkFee = totalSolDebits - totalSolCredits;\n if (networkFee > 0n) {\n const solInfo = TOKEN_INFO[KNOWN_TOKENS.SOL];\n if (solInfo) {\n legs.push({\n accountId: buildAccountId({ type: \"fee\", address: \"\" }),\n side: \"credit\",\n amount: {\n token: solInfo,\n amountRaw: networkFee.toString(),\n amountUi: Number(networkFee) / 1e9,\n },\n role: \"fee\",\n });\n }\n }\n\n const tokenChanges = extractTokenBalanceChanges(tx);\n for (const change of tokenChanges) {\n if (change.change.raw === \"0\") continue;\n\n let accountId: string;\n if (isDexProtocol(tx.protocol)) {\n const isFeePayer = feePayer && change.owner?.toLowerCase() === feePayer;\n if (isFeePayer) {\n accountId = buildAccountId({\n type: \"external\",\n address: change.owner || feePayer,\n });\n } else {\n accountId = buildAccountId({\n type: \"protocol\",\n address: change.owner || change.tokenInfo.mint,\n protocol: tx.protocol!.id,\n token: change.tokenInfo.symbol,\n });\n }\n } else {\n accountId = buildAccountId({\n type: \"external\",\n address: change.owner || change.tokenInfo.mint,\n });\n }\n\n legs.push({\n accountId,\n side: change.change.ui > 0 ? \"credit\" : \"debit\",\n amount: {\n token: change.tokenInfo,\n amountRaw: change.change.raw.replace(\"-\", \"\"),\n amountUi: Math.abs(change.change.ui),\n },\n role: determineTokenRole(change, tx, feePayer),\n });\n }\n\n return legs;\n}\n\n/**\n * Determines the role of a SOL balance change in the transaction context.\n *\n * @param change - SOL balance change for an account\n * @param tx - Raw transaction for additional context\n * @param feePayer - Fee payer address\n * @returns The role of this SOL balance change\n */\nfunction determineSolRole(\n change: SolBalanceChange,\n tx: RawTransaction,\n feePayer?: string\n): TxLegRole {\n const isFeePayer = feePayer\n ? change.address.toLowerCase() === feePayer\n : false;\n const isPositive = change.change > 0n;\n const amountSol = Math.abs(change.changeUi);\n\n if (isFeePayer && !isPositive && amountSol < 0.01) {\n return \"fee\";\n }\n\n if (isPositive) {\n if (tx.protocol?.id === \"stake\") {\n return \"reward\";\n }\n return \"received\";\n }\n\n return \"sent\";\n}\n\n/**\n * Determines the role of a token balance change in the transaction context.\n *\n * @param change - Token balance change for an account\n * @param tx - Raw transaction for protocol context\n * @param feePayer - Fee payer address\n * @returns The role of this token balance change\n */\nfunction determineTokenRole(\n change: TokenBalanceChange,\n tx: RawTransaction,\n feePayer?: string\n): TxLegRole {\n const isFeePayer = feePayer\n ? change.owner?.toLowerCase() === feePayer\n : false;\n const isPositive = change.change.ui > 0;\n\n if (isFeePayer) {\n return isPositive ? \"received\" : \"sent\";\n }\n\n if (isDexProtocol(tx.protocol)) {\n return isPositive ? \"protocol_withdraw\" : \"protocol_deposit\";\n }\n\n return isPositive ? \"received\" : \"sent\";\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { detectFacilitator } from \"@tx-indexer/solana/constants/program-ids\";\n\nexport class TransferClassifier implements Classifier {\n name = \"transfer\";\n priority = 20;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const facilitator = tx.accountKeys\n ? detectFacilitator(tx.accountKeys)\n : null;\n\n const senderLeg = legs.find(\n (l) =>\n l.accountId.startsWith(\"external:\") &&\n l.side === \"debit\" &&\n l.role === \"sent\"\n );\n\n if (!senderLeg) return null;\n\n const sender = senderLeg.accountId.replace(\"external:\", \"\");\n\n const receiverLeg = legs.find(\n (l) =>\n l.accountId.startsWith(\"external:\") &&\n l.side === \"credit\" &&\n l.role === \"received\" &&\n l.amount.token.mint === senderLeg.amount.token.mint\n );\n\n if (!receiverLeg) return null;\n\n const receiver = receiverLeg.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"transfer\",\n primaryAmount: senderLeg.amount,\n secondaryAmount: null,\n sender,\n receiver,\n counterparty: {\n type: \"wallet\",\n address: receiver,\n name: `${receiver.slice(0, 8)}...`,\n },\n confidence: 0.95,\n isRelevant: true,\n metadata: {\n ...(facilitator && { facilitator, payment_type: \"facilitated\" }),\n },\n };\n }\n}\n","import type { ProtocolInfo } from \"@tx-indexer/core/actors/counterparty.types\";\nimport {\n JUPITER_V6_PROGRAM_ID,\n JUPITER_V4_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n SYSTEM_PROGRAM_ID,\n COMPUTE_BUDGET_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n METAPLEX_PROGRAM_ID,\n ORCA_WHIRLPOOL_PROGRAM_ID,\n RAYDIUM_PROGRAM_ID,\n CANDY_GUARD_PROGRAM_ID,\n CANDY_MACHINE_V3_PROGRAM_ID,\n BUBBLEGUM_PROGRAM_ID,\n MAGIC_EDEN_CANDY_MACHINE_ID,\n STAKE_POOL_PROGRAM_ID,\n STAKE_PROGRAM_ID,\n WORMHOLE_PROGRAM_ID,\n WORMHOLE_TOKEN_BRIDGE_ID,\n DEGODS_BRIDGE_PROGRAM_ID,\n DEBRIDGE_PROGRAM_ID,\n ALLBRIDGE_PROGRAM_ID,\n} from \"@tx-indexer/solana/constants/program-ids\";\n\nconst KNOWN_PROGRAMS: Record<string, ProtocolInfo> = {\n [JUPITER_V6_PROGRAM_ID]: {\n id: \"jupiter\",\n name: \"Jupiter\",\n },\n [JUPITER_V4_PROGRAM_ID]: {\n id: \"jupiter-v4\",\n name: \"Jupiter V4\",\n },\n [TOKEN_PROGRAM_ID]: {\n id: \"spl-token\",\n name: \"Token Program\",\n },\n [SYSTEM_PROGRAM_ID]: {\n id: \"system\",\n name: \"System Program\",\n },\n [COMPUTE_BUDGET_PROGRAM_ID]: {\n id: \"compute-budget\",\n name: \"Compute Budget\",\n },\n [ASSOCIATED_TOKEN_PROGRAM_ID]: {\n id: \"associated-token\",\n name: \"Associated Token Program\",\n },\n [METAPLEX_PROGRAM_ID]: {\n id: \"metaplex\",\n name: \"Metaplex\",\n },\n [ORCA_WHIRLPOOL_PROGRAM_ID]: {\n id: \"orca-whirlpool\",\n name: \"Orca Whirlpool\",\n },\n [RAYDIUM_PROGRAM_ID]: {\n id: \"raydium\",\n name: \"Raydium\",\n },\n [STAKE_PROGRAM_ID]: {\n id: \"stake\",\n name: \"Stake Program\",\n },\n [STAKE_POOL_PROGRAM_ID]: {\n id: \"stake-pool\",\n name: \"Stake Pool Program\",\n },\n [CANDY_GUARD_PROGRAM_ID]: {\n id: \"candy-guard\",\n name: \"Metaplex Candy Guard Program\",\n },\n [CANDY_MACHINE_V3_PROGRAM_ID]: {\n id: \"candy-machine-v3\",\n name: \"Metaplex Candy Machine Core Program\",\n },\n [BUBBLEGUM_PROGRAM_ID]: {\n id: \"bubblegum\",\n name: \"Bubblegum Program\",\n },\n [MAGIC_EDEN_CANDY_MACHINE_ID]: {\n id: \"magic-eden-candy-machine\",\n name: \"Nft Candy Machine Program (Magic Eden)\",\n },\n [WORMHOLE_PROGRAM_ID]: {\n id: \"wormhole\",\n name: \"Wormhole\",\n },\n [WORMHOLE_TOKEN_BRIDGE_ID]: {\n id: \"wormhole-token-bridge\",\n name: \"Wormhole Token Bridge\",\n },\n [DEGODS_BRIDGE_PROGRAM_ID]: {\n id: \"degods-bridge\",\n name: \"DeGods Bridge\",\n },\n [DEBRIDGE_PROGRAM_ID]: {\n id: \"debridge\",\n name: \"deBridge\",\n },\n [ALLBRIDGE_PROGRAM_ID]: {\n id: \"allbridge\",\n name: \"Allbridge\",\n },\n};\n\nconst PRIORITY_ORDER = [\n \"wormhole\",\n \"wormhole-token-bridge\",\n \"degods-bridge\",\n \"debridge\",\n \"allbridge\",\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n \"metaplex\",\n \"stake\",\n \"associated-token\",\n \"spl-token\",\n \"compute-budget\",\n \"system\",\n];\n\n/**\n * Protocol IDs that are DEX (decentralized exchange) protocols.\n * These protocols perform swaps and should have their legs tagged as \"protocol:\"\n * with deposit/withdraw roles.\n */\nconst DEX_PROTOCOL_IDS = new Set([\n \"jupiter\",\n \"jupiter-v4\",\n \"raydium\",\n \"orca-whirlpool\",\n]);\n\nconst NFT_MINT_PROTOCOL_IDS = new Set([\n \"metaplex\",\n \"candy-machine-v3\",\n \"candy-guard\",\n \"bubblegum\",\n \"magic-eden-candy-machine\",\n]);\n\nconst STAKE_PROTOCOL_IDS = new Set([\"stake\", \"stake-pool\"]);\n\nconst BRIDGE_PROTOCOL_IDS = new Set([\n \"wormhole\",\n \"wormhole-token-bridge\",\n \"degods-bridge\",\n \"debridge\",\n \"allbridge\",\n]);\n\n/**\n * Checks if a protocol is a DEX (decentralized exchange) that performs swaps.\n * DEX protocols should have their legs tagged as \"protocol:\" with deposit/withdraw roles.\n * Non-DEX protocols (like Associated Token Program) are infrastructure and should not\n * affect leg tagging.\n */\nexport function isDexProtocol(protocol: ProtocolInfo | null): boolean {\n return protocol !== null && DEX_PROTOCOL_IDS.has(protocol.id);\n}\n\n/**\n * Checks if a protocol ID string corresponds to a DEX protocol.\n * Useful when you only have the protocol ID string, not the full ProtocolInfo object.\n */\nexport function isDexProtocolById(protocolId: string | undefined): boolean {\n return protocolId !== undefined && DEX_PROTOCOL_IDS.has(protocolId);\n}\n\n/**\n * Checks if a protocol ID string corresponds to a NFT Mint\n */\nexport function isNftMintProtocolById(protocolId: string | undefined): boolean {\n return protocolId !== undefined && NFT_MINT_PROTOCOL_IDS.has(protocolId);\n}\n\n/**\n * Checks if a protocol ID string corresponds to a stake\n */\n\nexport function isStakeProtocolById(protocolId: string | undefined): boolean {\n return protocolId !== undefined && STAKE_PROTOCOL_IDS.has(protocolId);\n}\n\n/**\n * Checks if a protocol ID string corresponds to a bridge protocol\n */\nexport function isBridgeProtocolById(protocolId: string | undefined): boolean {\n return protocolId !== undefined && BRIDGE_PROTOCOL_IDS.has(protocolId);\n}\n\n/**\n * Detects the primary protocol used in a transaction based on its program IDs.\n *\n * When multiple protocols are detected, returns the highest priority protocol\n * according to the PRIORITY_ORDER (e.g., Jupiter > Raydium > Token Program).\n *\n * @param programIds - Array of program IDs involved in the transaction\n * @returns The detected protocol information, or null if no known protocol is found\n */\nexport function detectProtocol(programIds: string[]): ProtocolInfo | null {\n const detectedProtocols: ProtocolInfo[] = [];\n\n for (const programId of programIds) {\n const protocol = KNOWN_PROGRAMS[programId];\n if (protocol) {\n detectedProtocols.push(protocol);\n }\n }\n\n if (detectedProtocols.length === 0) {\n return null;\n }\n\n detectedProtocols.sort((a, b) => {\n const aPriority = PRIORITY_ORDER.indexOf(a.id);\n const bPriority = PRIORITY_ORDER.indexOf(b.id);\n return aPriority - bPriority;\n });\n\n return detectedProtocols[0] ?? null;\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isDexProtocolById } from \"../protocols/detector\";\n\nexport class SwapClassifier implements Classifier {\n name = \"swap\";\n priority = 80;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const hasDexProtocol = isDexProtocolById(tx.protocol?.id);\n if (!hasDexProtocol) {\n return null;\n }\n\n const feeLeg = legs.find(\n (leg) => leg.role === \"fee\" && leg.side === \"debit\"\n );\n const initiator = feeLeg?.accountId.replace(\"external:\", \"\") ?? null;\n\n const tokensOut = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n (leg.role === \"sent\" || leg.role === \"protocol_deposit\")\n );\n\n const tokensIn = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n (leg.role === \"received\" || leg.role === \"protocol_withdraw\")\n );\n\n if (tokensOut.length === 0 || tokensIn.length === 0) {\n return null;\n }\n\n const tokenOut = tokensOut[0]!;\n const tokenIn = tokensIn[0]!;\n\n if (tokenOut.amount.token.symbol === tokenIn.amount.token.symbol) {\n return null;\n }\n\n return {\n primaryType: \"swap\",\n primaryAmount: tokenOut.amount,\n secondaryAmount: tokenIn.amount,\n sender: initiator,\n receiver: initiator,\n counterparty: null,\n confidence: 0.9,\n isRelevant: true,\n metadata: {\n swap_type: \"token_to_token\",\n from_token: tokenOut.amount.token.symbol,\n to_token: tokenIn.amount.token.symbol,\n from_amount: tokenOut.amount.amountUi,\n to_amount: tokenIn.amount.amountUi,\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { detectFacilitator } from \"@tx-indexer/solana/constants/program-ids\";\n\nexport class AirdropClassifier implements Classifier {\n name = \"airdrop\";\n priority = 70;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const facilitator = tx.accountKeys\n ? detectFacilitator(tx.accountKeys)\n : null;\n\n const protocolLegs = legs.filter((leg) =>\n leg.accountId.startsWith(\"protocol:\")\n );\n\n if (protocolLegs.length === 0) {\n return null;\n }\n\n const tokenReceived = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n leg.role === \"received\" &&\n leg.amount.token.symbol !== \"SOL\"\n );\n\n if (tokenReceived.length === 0) {\n return null;\n }\n\n const tokenSent = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.role === \"sent\" &&\n leg.amount.token.symbol !== \"SOL\"\n );\n\n if (tokenSent.length > 0) {\n return null;\n }\n\n const mainToken = tokenReceived[0]!;\n const receiver = mainToken.accountId.replace(\"external:\", \"\");\n\n const senderLeg = legs.find(\n (leg) =>\n leg.side === \"debit\" &&\n leg.amount.token.mint === mainToken.amount.token.mint\n );\n\n const sender = senderLeg\n ? senderLeg.accountId.replace(/^(external:|protocol:)/, \"\")\n : null;\n\n return {\n primaryType: \"airdrop\",\n primaryAmount: mainToken.amount,\n secondaryAmount: null,\n sender,\n receiver,\n counterparty: sender\n ? {\n type: \"protocol\",\n address: sender,\n }\n : null,\n confidence: 0.85,\n isRelevant: true,\n metadata: {\n airdrop_type: \"token\",\n token: mainToken.amount.token.symbol,\n amount: mainToken.amount.amountUi,\n ...(facilitator && { facilitator }),\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\n\nexport class FeeOnlyClassifier implements Classifier {\n name = \"fee-only\";\n priority = 60;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs } = context;\n\n const externalLegs = legs.filter((leg) =>\n leg.accountId.startsWith(\"external:\")\n );\n const nonFeeLegs = externalLegs.filter((leg) => leg.role !== \"fee\");\n\n if (nonFeeLegs.length > 0) {\n return null;\n }\n\n const feeLegs = legs.filter((leg) => leg.role === \"fee\");\n\n if (feeLegs.length === 0) {\n return null;\n }\n\n const feePayerLeg = feeLegs.find(\n (leg) => leg.side === \"debit\" && leg.amount.token.symbol === \"SOL\"\n );\n\n const feePayer = feePayerLeg?.accountId.replace(\"external:\", \"\") ?? null;\n const totalFee = feeLegs.find((leg) => leg.amount.token.symbol === \"SOL\");\n\n return {\n primaryType: \"fee_only\",\n primaryAmount: totalFee?.amount ?? null,\n secondaryAmount: null,\n sender: feePayer,\n receiver: null,\n counterparty: null,\n confidence: 0.95,\n isRelevant: false,\n metadata: {\n fee_type: \"network\",\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport {\n isSolanaPayTransaction,\n parseSolanaPayMemo,\n} from \"@tx-indexer/solana/mappers/memo-parser\";\n\nexport class SolanaPayClassifier implements Classifier {\n name = \"solana-pay\";\n priority = 95;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { tx, legs } = context;\n\n if (!isSolanaPayTransaction(tx.programIds, tx.memo)) {\n return null;\n }\n\n const memo = parseSolanaPayMemo(tx.memo!);\n\n const senderLeg = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.role === \"sent\"\n );\n\n const receiverLeg = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n leg.role === \"received\"\n );\n\n const sender = senderLeg?.accountId.replace(\"external:\", \"\") ?? null;\n const receiver = receiverLeg?.accountId.replace(\"external:\", \"\") ?? null;\n const primaryAmount = senderLeg?.amount ?? receiverLeg?.amount ?? null;\n\n return {\n primaryType: \"transfer\",\n primaryAmount,\n secondaryAmount: null,\n sender,\n receiver,\n counterparty: receiver\n ? {\n address: receiver,\n name: memo.merchant ?? undefined,\n type: memo.merchant ? \"merchant\" : \"wallet\",\n }\n : null,\n confidence: 0.98,\n isRelevant: true,\n metadata: {\n payment_type: \"solana_pay\",\n memo: memo.raw,\n merchant: memo.merchant,\n item: memo.item,\n reference: memo.reference,\n label: memo.label,\n message: memo.message,\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isNftMintProtocolById } from \"../protocols/detector\";\n\nexport class NftMintClassifier implements Classifier {\n name = \"nft-mint\";\n priority = 85;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const hasNftMintProtocol = isNftMintProtocolById(tx.protocol?.id);\n if (!hasNftMintProtocol) {\n return null;\n }\n\n const nftCredits = legs.filter(\n (leg) =>\n leg.side === \"credit\" &&\n leg.amount.token.decimals === 0 &&\n leg.amount.amountUi >= 1 &&\n (leg.role === \"received\" || leg.role === \"protocol_withdraw\")\n );\n\n if (nftCredits.length === 0) {\n return null;\n }\n\n const primaryNft = nftCredits[0]!;\n const minter = primaryNft.accountId.replace(\"external:\", \"\");\n\n const paymentLeg = legs.find(\n (leg) =>\n leg.side === \"debit\" &&\n leg.role === \"sent\" &&\n leg.amount.token.symbol === \"SOL\"\n );\n\n const totalMinted = nftCredits.reduce(\n (sum, leg) => sum + leg.amount.amountUi,\n 0\n );\n\n return {\n primaryType: \"nft_mint\",\n primaryAmount: primaryNft.amount,\n secondaryAmount: paymentLeg?.amount ?? null,\n sender: null,\n receiver: minter,\n counterparty: null,\n confidence: 0.9,\n isRelevant: true,\n metadata: {\n nft_mint: primaryNft.amount.token.mint,\n nft_name: primaryNft.amount.token.name,\n quantity: totalMinted,\n mint_price: paymentLeg?.amount.amountUi,\n protocol: tx.protocol?.id,\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isStakeProtocolById } from \"../protocols/detector\";\n\nexport class StakeDepositClassifier implements Classifier {\n name = \"stake-deposit\";\n priority = 82;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const hasStakeProtocol = isStakeProtocolById(tx.protocol?.id);\n if (!hasStakeProtocol) {\n return null;\n }\n\n const solDebit = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.amount.token.symbol === \"SOL\" &&\n (leg.role === \"sent\" || leg.role === \"protocol_deposit\")\n );\n\n if (!solDebit) {\n return null;\n }\n\n const staker = solDebit.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"stake_deposit\",\n primaryAmount: solDebit.amount,\n secondaryAmount: null,\n sender: staker,\n receiver: null,\n counterparty: null,\n confidence: 0.9,\n isRelevant: true,\n metadata: {\n stake_amount: solDebit.amount.amountUi,\n protocol: tx.protocol?.id,\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isStakeProtocolById } from \"../protocols/detector\";\n\nexport class StakeWithdrawClassifier implements Classifier {\n name = \"stake-withdraw\";\n priority = 81;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const hasStakeProtocol = isStakeProtocolById(tx.protocol?.id);\n if (!hasStakeProtocol) {\n return null;\n }\n\n const solCredit = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n leg.amount.token.symbol === \"SOL\" &&\n (leg.role === \"received\" || leg.role === \"protocol_withdraw\")\n );\n\n if (!solCredit) {\n return null;\n }\n\n const solDebit = legs.find(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.amount.token.symbol === \"SOL\" &&\n (leg.role === \"sent\" || leg.role === \"protocol_deposit\")\n );\n\n if (solDebit) {\n return null;\n }\n\n const withdrawer = solCredit.accountId.replace(\"external:\", \"\");\n\n return {\n primaryType: \"stake_withdraw\",\n primaryAmount: solCredit.amount,\n secondaryAmount: null,\n sender: null,\n receiver: withdrawer,\n counterparty: null,\n confidence: 0.9,\n isRelevant: true,\n metadata: {\n withdraw_amount: solCredit.amount.amountUi,\n protocol: tx.protocol?.id,\n },\n };\n }\n}\n","import type {\n Classifier,\n ClassifierContext,\n} from \"../engine/classifier.interface\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport { isBridgeProtocolById } from \"../protocols/detector\";\n\nexport class BridgeClassifier implements Classifier {\n name = \"bridge\";\n priority = 88;\n\n classify(context: ClassifierContext): TransactionClassification | null {\n const { legs, tx } = context;\n\n const hasBridgeProtocol = isBridgeProtocolById(tx.protocol?.id);\n if (!hasBridgeProtocol) {\n return null;\n }\n\n const tokensOut = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"debit\" &&\n leg.role !== \"fee\" &&\n (leg.role === \"sent\" || leg.role === \"protocol_deposit\")\n );\n\n const tokensIn = legs.filter(\n (leg) =>\n leg.accountId.startsWith(\"external:\") &&\n leg.side === \"credit\" &&\n (leg.role === \"received\" || leg.role === \"protocol_withdraw\")\n );\n\n let primaryType: \"bridge_in\" | \"bridge_out\";\n let primaryAmount = null;\n let participant: string | null = null;\n\n if (tokensIn.length > 0 && tokensOut.length === 0) {\n primaryType = \"bridge_in\";\n const creditLeg = tokensIn[0]!;\n primaryAmount = creditLeg.amount;\n participant = creditLeg.accountId.replace(\"external:\", \"\");\n } else if (tokensOut.length > 0 && tokensIn.length === 0) {\n primaryType = \"bridge_out\";\n const debitLeg = tokensOut[0]!;\n primaryAmount = debitLeg.amount;\n participant = debitLeg.accountId.replace(\"external:\", \"\");\n } else if (tokensIn.length > 0 && tokensOut.length > 0) {\n primaryType = \"bridge_in\";\n const creditLeg = tokensIn[0]!;\n primaryAmount = creditLeg.amount;\n participant = creditLeg.accountId.replace(\"external:\", \"\");\n } else {\n return null;\n }\n\n return {\n primaryType,\n primaryAmount,\n secondaryAmount: null,\n sender: primaryType === \"bridge_out\" ? participant : null,\n receiver: primaryType === \"bridge_in\" ? participant : null,\n counterparty: null,\n confidence: 0.9,\n isRelevant: true,\n metadata: {\n bridge_protocol: tx.protocol?.id,\n bridge_name: tx.protocol?.name,\n },\n };\n }\n}\n","import type { TxLeg, RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\nimport type { Classifier, ClassifierContext } from \"./classifier.interface\";\nimport { TransferClassifier } from \"../classifiers/transfer-classifier\";\nimport { SwapClassifier } from \"../classifiers/swap-classifier\";\nimport { AirdropClassifier } from \"../classifiers/airdrop-classifier\";\nimport { FeeOnlyClassifier } from \"../classifiers/fee-only-classifier\";\nimport { SolanaPayClassifier } from \"../classifiers/solana-pay-classifier\";\nimport { NftMintClassifier } from \"../classifiers/nft-mint-classifier\";\nimport { StakeDepositClassifier } from \"../classifiers/stake-deposit-classifier\";\nimport { StakeWithdrawClassifier } from \"../classifiers/stake-withdraw-classifier\";\nimport { BridgeClassifier } from \"../classifiers/bridge-classifier\";\n\nexport class ClassificationService {\n private classifiers: Classifier[] = [];\n\n constructor() {\n this.registerClassifier(new SolanaPayClassifier());\n this.registerClassifier(new BridgeClassifier());\n this.registerClassifier(new NftMintClassifier());\n this.registerClassifier(new StakeDepositClassifier());\n this.registerClassifier(new StakeWithdrawClassifier());\n this.registerClassifier(new SwapClassifier());\n this.registerClassifier(new AirdropClassifier());\n this.registerClassifier(new TransferClassifier());\n this.registerClassifier(new FeeOnlyClassifier());\n }\n\n registerClassifier(classifier: Classifier): void {\n this.classifiers.push(classifier);\n this.classifiers.sort((a, b) => b.priority - a.priority);\n }\n\n classify(legs: TxLeg[], tx: RawTransaction): TransactionClassification {\n const context: ClassifierContext = { legs, tx };\n\n for (const classifier of this.classifiers) {\n const result = classifier.classify(context);\n if (result && result.isRelevant) {\n return result;\n }\n }\n\n return {\n primaryType: \"other\",\n primaryAmount: null,\n secondaryAmount: null,\n sender: null,\n receiver: null,\n counterparty: null,\n confidence: 0.0,\n isRelevant: false,\n metadata: {},\n };\n }\n}\n\nexport const classificationService = new ClassificationService();\n\n/**\n * Classifies a transaction based on its accounting legs and context.\n *\n * Uses a priority-ordered chain of classifiers (Solana Pay > Bridge > NFT Mint > Stake Deposit > Stake Withdraw > Swap > Airdrop > Transfer > Fee-only)\n * to determine the transaction type, direction, amounts, sender, and receiver.\n *\n * Direction is always from the initiator's (fee payer's) perspective.\n * Frontend should compare connected wallet to sender/receiver for user perspective.\n *\n * @param legs - Transaction legs representing all balance movements\n * @param tx - Raw transaction data for additional context (protocol, memo, etc.)\n * @returns Classification result with type, amounts, sender, receiver, and confidence\n */\nexport function classifyTransaction(\n legs: TxLeg[],\n tx: RawTransaction\n): TransactionClassification {\n return classificationService.classify(legs, tx);\n}\n","import type { TransactionClassification } from \"./classification.types\";\nimport type { RawTransaction } from \"./tx.types\";\n\nexport interface SpamFilterConfig {\n minSolAmount?: number;\n minTokenAmountUsd?: number;\n minConfidence?: number;\n allowFailed?: boolean;\n}\n\nconst DEFAULT_CONFIG: Required<SpamFilterConfig> = {\n minSolAmount: 0.001,\n minTokenAmountUsd: 0.01,\n minConfidence: 0.5,\n allowFailed: false,\n};\n\n/**\n * Determines if a transaction should be filtered as spam or dust.\n * \n * A transaction is considered spam if it:\n * - Failed (and allowFailed is false)\n * - Has low classification confidence\n * - Is not relevant to the wallet\n * - Involves dust amounts below configured thresholds\n * \n * @param tx - Raw transaction data\n * @param classification - Transaction classification result\n * @param config - Optional spam filter configuration (uses defaults if omitted)\n * @returns True if the transaction should be filtered as spam\n */\nexport function isSpamTransaction(\n tx: RawTransaction,\n classification: TransactionClassification,\n config: SpamFilterConfig = {}\n): boolean {\n const cfg = { ...DEFAULT_CONFIG, ...config };\n\n if (!cfg.allowFailed && tx.err) {\n return true;\n }\n\n if (classification.confidence < cfg.minConfidence) {\n return true;\n }\n\n if (!classification.isRelevant) {\n return true;\n }\n\n if (isDustTransaction(classification, cfg)) {\n return true;\n }\n\n return false;\n}\n\nfunction isDustTransaction(\n classification: TransactionClassification,\n config: Required<SpamFilterConfig>\n): boolean {\n const { primaryAmount } = classification;\n \n if (!primaryAmount) {\n return false;\n }\n\n const { token, amountUi } = primaryAmount;\n\n if (token.symbol === \"SOL\") {\n return Math.abs(amountUi) < config.minSolAmount;\n }\n\n if (token.symbol === \"USDC\") {\n return Math.abs(amountUi) < config.minTokenAmountUsd;\n }\n\n return Math.abs(amountUi) < config.minTokenAmountUsd;\n}\n\n/**\n * Filters an array of transactions to remove spam and dust transactions.\n * \n * Applies spam detection criteria to each transaction while preserving\n * additional properties in the returned array items.\n * \n * @param transactions - Array of transaction objects with tx and classification\n * @param config - Optional spam filter configuration\n * @returns Filtered array with spam transactions removed\n */\nexport function filterSpamTransactions<T extends {\n tx: RawTransaction;\n classification: TransactionClassification;\n}>(\n transactions: T[],\n config?: SpamFilterConfig\n): T[] {\n return transactions.filter(\n ({ tx, classification }) => !isSpamTransaction(tx, classification, config)\n );\n}\n\n","import type { Address, Signature } from \"@solana/kit\";\nimport {\n createSolanaClient,\n parseSignature,\n type SolanaClient,\n} from \"@tx-indexer/solana/rpc/client\";\nimport { fetchWalletBalance } from \"@tx-indexer/solana/fetcher/balances\";\nimport {\n fetchWalletSignatures,\n fetchTransaction,\n fetchTransactionsBatch,\n type FetchTransactionsConfig,\n} from \"@tx-indexer/solana/fetcher/transactions\";\n\nexport type { FetchTransactionsConfig } from \"@tx-indexer/solana/fetcher/transactions\";\nimport { transactionToLegs } from \"@tx-indexer/solana/mappers/transaction-to-legs\";\nimport { classifyTransaction } from \"@tx-indexer/classification/engine/classification-service\";\nimport { detectProtocol } from \"@tx-indexer/classification/protocols/detector\";\nimport { filterSpamTransactions, type SpamFilterConfig } from \"@tx-indexer/core/tx/spam-filter\";\nimport type { WalletBalance } from \"@tx-indexer/solana/fetcher/balances\";\nimport type { RawTransaction } from \"@tx-indexer/core/tx/tx.types\";\nimport type { TransactionClassification } from \"@tx-indexer/core/tx/classification.types\";\n\nexport type TxIndexerOptions =\n | { \n rpcUrl: string; \n wsUrl?: string;\n }\n | { \n client: SolanaClient;\n };\n\nexport interface GetTransactionsOptions {\n limit?: number;\n before?: Signature;\n until?: Signature;\n filterSpam?: boolean;\n spamConfig?: SpamFilterConfig;\n}\n\nexport interface ClassifiedTransaction {\n tx: RawTransaction;\n classification: TransactionClassification;\n legs: ReturnType<typeof transactionToLegs>;\n}\n\nexport interface TxIndexer {\n rpc: ReturnType<typeof createSolanaClient>[\"rpc\"];\n \n getBalance(\n walletAddress: Address,\n tokenMints?: readonly string[]\n ): Promise<WalletBalance>;\n \n getTransactions(\n walletAddress: Address,\n options?: GetTransactionsOptions\n ): Promise<ClassifiedTransaction[]>;\n \n getTransaction(signature: Signature): Promise<ClassifiedTransaction | null>;\n \n getRawTransaction(signature: Signature): Promise<RawTransaction | null>;\n}\n\nexport function createIndexer(options: TxIndexerOptions): TxIndexer {\n const client = \"client\" in options\n ? options.client\n : createSolanaClient(options.rpcUrl, options.wsUrl);\n\n return {\n rpc: client.rpc,\n\n async getBalance(\n walletAddress: Address,\n tokenMints?: readonly string[]\n ): Promise<WalletBalance> {\n return fetchWalletBalance(client.rpc, walletAddress, tokenMints);\n },\n\n async getTransactions(\n walletAddress: Address,\n options: GetTransactionsOptions = {}\n ): Promise<ClassifiedTransaction[]> {\n const { limit = 10, before, until, filterSpam = true, spamConfig } = options;\n\n if (!filterSpam) {\n const signatures = await fetchWalletSignatures(client.rpc, walletAddress, {\n limit,\n before,\n until,\n });\n\n if (signatures.length === 0) {\n return [];\n }\n\n const signatureObjects = signatures.map((sig) =>\n parseSignature(sig.signature)\n );\n const transactions = await fetchTransactionsBatch(\n client.rpc,\n signatureObjects\n );\n\n const classified = transactions.map((tx) => {\n tx.protocol = detectProtocol(tx.programIds);\n const legs = transactionToLegs(tx);\n const classification = classifyTransaction(legs, tx);\n return { tx, classification, legs };\n });\n\n return classified;\n }\n\n const accumulated: ClassifiedTransaction[] = [];\n let currentBefore = before;\n const MAX_ITERATIONS = 10;\n let iteration = 0;\n\n while (accumulated.length < limit && iteration < MAX_ITERATIONS) {\n iteration++;\n\n const batchSize = iteration === 1 ? limit : limit * 2;\n\n const signatures = await fetchWalletSignatures(client.rpc, walletAddress, {\n limit: batchSize,\n before: currentBefore,\n until,\n });\n\n if (signatures.length === 0) {\n break;\n }\n\n const signatureObjects = signatures.map((sig) =>\n parseSignature(sig.signature)\n );\n const transactions = await fetchTransactionsBatch(\n client.rpc,\n signatureObjects\n );\n\n const classified = transactions.map((tx) => {\n tx.protocol = detectProtocol(tx.programIds);\n const legs = transactionToLegs(tx);\n const classification = classifyTransaction(legs, tx);\n return { tx, classification, legs };\n });\n\n const nonSpam = filterSpamTransactions(classified, spamConfig);\n accumulated.push(...nonSpam);\n\n const lastSignature = signatures[signatures.length - 1];\n if (lastSignature) {\n currentBefore = parseSignature(lastSignature.signature);\n } else {\n break;\n }\n }\n\n return accumulated.slice(0, limit);\n },\n\n async getTransaction(signature: Signature): Promise<ClassifiedTransaction | null> {\n const tx = await fetchTransaction(client.rpc, signature);\n\n if (!tx) {\n return null;\n }\n\n tx.protocol = detectProtocol(tx.programIds);\n\n const legs = transactionToLegs(tx);\n const classification = classifyTransaction(legs, tx);\n\n return { tx, classification, legs };\n },\n\n async getRawTransaction(signature: Signature): Promise<RawTransaction | null> {\n return fetchTransaction(client.rpc, signature);\n },\n };\n}\n","import type { TxLeg } from \"./tx.types\";\n\nexport interface LegTokenBalance {\n debits: number;\n credits: number;\n diff: number;\n}\n\nexport interface LegBalanceResult {\n isBalanced: boolean;\n byToken: Record<string, LegTokenBalance>;\n}\n\n/**\n * Validates that transaction legs balance according to double-entry accounting.\n * \n * For each token, verifies that total debits equal total credits (within a small tolerance\n * for floating-point precision). This ensures the transaction legs accurately represent\n * all balance movements.\n * \n * @param legs - Array of transaction legs to validate\n * @returns Validation result with per-token balance information\n */\nexport function validateLegsBalance(legs: TxLeg[]): LegBalanceResult {\n const byToken: Record<string, { debits: number; credits: number }> = {};\n\n for (const leg of legs) {\n const token = leg.amount.token.symbol;\n if (!byToken[token]) {\n byToken[token] = { debits: 0, credits: 0 };\n }\n\n if (leg.side === \"debit\") {\n byToken[token].debits += leg.amount.amountUi;\n } else {\n byToken[token].credits += leg.amount.amountUi;\n }\n }\n\n const result: Record<string, LegTokenBalance> = {};\n let isBalanced = true;\n\n for (const [token, amounts] of Object.entries(byToken)) {\n const diff = Math.abs(amounts.debits - amounts.credits);\n result[token] = { ...amounts, diff };\n\n if (diff > 0.000001) {\n isBalanced = false;\n }\n }\n\n return { isBalanced, byToken: result };\n}\n\n/**\n * Groups transaction legs by account ID.\n * \n * Useful for analyzing all balance movements for a specific account or\n * understanding counterparty interactions in a transaction.\n * \n * @param legs - Array of transaction legs to group\n * @returns Map of account IDs to their associated legs\n */\nexport function groupLegsByAccount(legs: TxLeg[]): Record<string, TxLeg[]> {\n const grouped: Record<string, TxLeg[]> = {};\n\n for (const leg of legs) {\n if (!grouped[leg.accountId]) {\n grouped[leg.accountId] = [];\n }\n grouped[leg.accountId]!.push(leg);\n }\n\n return grouped;\n}\n\n/**\n * Groups transaction legs by token symbol.\n * \n * Useful for analyzing all movements of a specific token or calculating\n * total amounts exchanged for each asset in the transaction.\n * \n * @param legs - Array of transaction legs to group\n * @returns Map of token symbols to their associated legs\n */\nexport function groupLegsByToken(legs: TxLeg[]): Record<string, TxLeg[]> {\n const grouped: Record<string, TxLeg[]> = {};\n\n for (const leg of legs) {\n const token = leg.amount.token.symbol;\n if (!grouped[token]) {\n grouped[token] = [];\n }\n grouped[token]!.push(leg);\n }\n\n return grouped;\n}\n\n"]}
|