Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 12x 8x 45x 45x 45x 16x 29x 6x 23x | import { ParsedInstruction, ParsedTransactionWithMeta } from "@solana/web3.js";
import { DEX_PROGRAMS } from "./constants";
import { DexInfo, TokenInfo, TradeInfo, TransferData } from "./types";
import { TokenInfoExtractor } from "./token-extractor";
import { isTransfer, processTransfer, isTransferCheck, processTransferCheck, processSwapData } from "./transfer-utils";
export class RaydiumParser {
private readonly splTokenMap: Map<string, TokenInfo>;
private readonly splDecimalsMap: Map<string, number>;
constructor(
private readonly txWithMeta: ParsedTransactionWithMeta,
private readonly dexInfo: DexInfo
) {
const tokenExtractor = new TokenInfoExtractor(txWithMeta);
this.splTokenMap = tokenExtractor.extractSPLTokenInfo();
this.splDecimalsMap = tokenExtractor.extractDecimals();
}
public processTrades(): TradeInfo[] {
return this.txWithMeta.transaction.message.instructions
.reduce((trades: TradeInfo[], instruction: any, index: number) => {
Iif (this.isRaydiumInstruction(instruction)) {
const instructionTrades = this.processInstructionTrades(index);
trades.push(...instructionTrades);
}
return trades;
}, []);
}
public processInstructionTrades(instructionIndex: number): TradeInfo[] {
try {
const transfers = this.processRaydiumSwaps(instructionIndex);
return transfers.length ? [processSwapData(this.txWithMeta, transfers, this.dexInfo)] : [];
} catch (error) {
console.error('Error processing Raydium trades:', error);
return [];
}
}
private isRaydiumInstruction(instruction: any): boolean {
const programId = instruction.programId.toBase58();
return [DEX_PROGRAMS.RAYDIUM_V4.id, DEX_PROGRAMS.RAYDIUM_AMM.id, DEX_PROGRAMS.RAYDIUM_CL.id, DEX_PROGRAMS.RAYDIUM_CPMM].includes(programId);
}
private processRaydiumSwaps(instructionIndex: number): TransferData[] {
const innerInstructions = this.txWithMeta.meta?.innerInstructions;
Iif (!innerInstructions) return [];
return innerInstructions
.filter(set => set.index === instructionIndex)
.flatMap(set => set.instructions
.map(instruction => this.processTransferInstruction(instruction as ParsedInstruction))
.filter((transfer): transfer is TransferData => transfer !== null)
);
}
private processTransferInstruction(instruction: ParsedInstruction): TransferData | null {
if (isTransfer(instruction)) {
return processTransfer(instruction, this.splTokenMap, this.splDecimalsMap);
}
if (isTransferCheck(instruction)) {
return processTransferCheck(instruction, this.splDecimalsMap);
}
return null;
}
} |