UNPKG

solana-dex-parser

Version:

Solana Dex Transaction Parser

164 lines (143 loc) 5.5 kB
import { TOKENS, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from './constants'; import { TransactionAdapter } from './transaction-adapter'; import { TransferData, convertToUiAmount } from './types'; import { getTranferTokenMint } from './utils'; export const isTransferCheck = (instruction: any): boolean => { return ( (instruction.programId == TOKEN_PROGRAM_ID || instruction.programId == TOKEN_2022_PROGRAM_ID) && instruction.parsed.type.includes('transferChecked') ); }; export const isTransfer = (instruction: any): boolean => { return ( (instruction.program === 'spl-token' && instruction.programId == TOKEN_PROGRAM_ID && instruction.parsed.type === 'transfer') || (instruction.program === 'system' && instruction.programId == TOKENS.NATIVE && instruction.parsed.type === 'transfer') ); }; export const processTransfer = (instruction: any, idx: string, adapter: TransactionAdapter): TransferData | null => { const { info } = instruction.parsed; if (!info) return null; const [token1, token2] = [ adapter.splTokenMap.get(info.destination)?.mint, adapter.splTokenMap.get(info.source)?.mint, ]; if (!token1 && !token2) return null; let mint = getTranferTokenMint(token1, token2); if (!mint && instruction.programId == TOKENS.NATIVE) mint = TOKENS.SOL; if (!mint) return null; const decimals = adapter.splDecimalsMap.get(mint); if (typeof decimals === 'undefined') return null; const [sourceBalance, destinationBalance] = instruction.programId == TOKENS.NATIVE ? adapter.getAccountBalance([info.source, info.destination]) : adapter.getTokenAccountBalance([info.source, info.destination]); const [sourcePreBalance, destinationPreBalance] = instruction.programId == TOKENS.NATIVE ? adapter.getAccountPreBalance([info.source, info.destination]) : adapter.getTokenAccountPreBalance([info.source, info.destination]); return { type: 'transfer', programId: instruction.programId, info: { authority: info.authority, destination: info.destination || '', destinationOwner: adapter.getTokenAccountOwner(info.destination), mint, source: info.source || '', tokenAmount: { amount: info.amount || info.lamports, decimals, uiAmount: convertToUiAmount(info.amount || info.lamports, decimals), }, sourceBalance: sourceBalance, sourcePreBalance: sourcePreBalance, destinationBalance: destinationBalance, destinationPreBalance: destinationPreBalance, }, idx: idx, timestamp: adapter.blockTime, signature: adapter.signature, }; }; export const processTransferCheck = ( instruction: any, idx: string, adapter: TransactionAdapter ): TransferData | null => { const { info } = instruction.parsed; if (!info) return null; const decimals = adapter.splDecimalsMap.get(info.mint); if (typeof decimals === 'undefined') return null; const [sourceBalance, destinationBalance] = adapter.getTokenAccountBalance([info.source, info.destination]); const [sourcePreBalance, destinationPreBalance] = adapter.getTokenAccountPreBalance([info.source, info.destination]); return { type: 'transferChecked', programId: instruction.programId, info: { authority: info.authority, destination: info.destination || '', destinationOwner: adapter.getTokenAccountOwner(info.destination), mint: info.mint || '', source: info.source || '', tokenAmount: info.tokenAmount || { amount: info.amount, decimals, uiAmount: convertToUiAmount(info.amount, decimals), }, sourceBalance: sourceBalance, sourcePreBalance: sourcePreBalance, destinationBalance: destinationBalance, destinationPreBalance: destinationPreBalance, }, idx, timestamp: adapter.blockTime, signature: adapter.signature, }; }; export const isExtraAction = (instruction: any, type: string): boolean => { return ( instruction.program === 'spl-token' && instruction.programId == TOKEN_PROGRAM_ID && instruction.parsed.type === type ); }; export const processExtraAction = ( instruction: any, idx: string, adapter: TransactionAdapter, type: string ): TransferData | null => { const { info } = instruction.parsed; if (!info) return null; const mint = info.mint || adapter.splTokenMap.get(info.destination)?.mint; if (!mint) return null; const decimals = adapter.splDecimalsMap.get(mint); if (typeof decimals === 'undefined') return null; const [sourceBalance, destinationBalance] = adapter.getTokenAccountBalance([info.source, info.destination]); const [sourcePreBalance, destinationPreBalance] = adapter.getTokenAccountPreBalance([info.source, info.destination]); return { type: type, programId: instruction.programId, info: { authority: info.authority || info.mintAuthority || '', destination: info.destination || '', destinationOwner: adapter.getTokenAccountOwner(info.destination), mint, source: info.source || '', tokenAmount: { amount: info.amount, decimals, uiAmount: convertToUiAmount(info.amount, decimals), }, sourceBalance: sourceBalance, sourcePreBalance: sourcePreBalance, destinationBalance: destinationBalance, destinationPreBalance: destinationPreBalance, }, idx: idx, timestamp: adapter.blockTime, signature: adapter.signature, }; };