spl data fetch fixed
This commit is contained in:
parent
7f8a87cfa2
commit
3d31c1efaa
21
src/index.ts
21
src/index.ts
|
|
@ -3,13 +3,14 @@ import { config } from './config';
|
|||
import { logger } from './utils/logger';
|
||||
import transactionRoutes from './routes/transactionRoutes';
|
||||
import { getConnection } from './utils/database';
|
||||
import { getTransaction } from './utils/explorer';
|
||||
import { getTransaction, getTransactionRaw } from './utils/explorer';
|
||||
import { TransactionValidationService } from './services/transactionValidationService';
|
||||
import { CLUSTER_API } from './data';
|
||||
logger.info("Starting server...");
|
||||
const app = express();
|
||||
const PORT = config.port;
|
||||
logger.info(`port: ${PORT}`);
|
||||
logger.info(`nodeEnv: ${config.nodeEnv}`);
|
||||
logger.info(`nodeEnv: ${config.nodeEnv} : ${CLUSTER_API}`);
|
||||
logger.info(`logLevel: ${config.logLevel}`);
|
||||
|
||||
getConnection().then(() => {
|
||||
|
|
@ -42,9 +43,19 @@ app.get('/health', (_req: Request, res: Response) => {
|
|||
});
|
||||
|
||||
app.get('/solana/tx/:txHash', async (req: Request, res: Response) => {
|
||||
const txHash = req.params.txHash;
|
||||
const transaction = await getTransaction(txHash);
|
||||
res.json(transaction);
|
||||
|
||||
const {raw} = req.query;
|
||||
|
||||
if(raw=="true"){
|
||||
const tx = await getTransactionRaw(req.params.txHash);
|
||||
res.json(tx);
|
||||
}else{
|
||||
const txHash = req.params.txHash;
|
||||
const transaction = await getTransaction(txHash);
|
||||
res.json(transaction);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
// Validation service control endpoints
|
||||
|
|
|
|||
|
|
@ -1,15 +1,27 @@
|
|||
import { CLUSTER_API } from "../data";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { Connection, ParsedTransactionWithMeta, PublicKey } from "@solana/web3.js";
|
||||
import { TransferData } from "../types";
|
||||
import { logger } from "./logger";
|
||||
|
||||
export async function getTransaction(txHash: string) {
|
||||
const connection = new Connection(CLUSTER_API, { commitment: 'finalized' });
|
||||
export async function getTransactionRaw(txHash: string) {
|
||||
const connection = new Connection(CLUSTER_API, { commitment: 'confirmed' });
|
||||
|
||||
const transaction = await connection.getParsedTransaction(txHash, {
|
||||
maxSupportedTransactionVersion: 0,
|
||||
});
|
||||
|
||||
const transaction_formatted = extractTokenTransferData(transaction);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
export async function getTransaction(txHash: string) {
|
||||
const transaction = await getTransactionRaw(txHash);
|
||||
|
||||
if (!transaction) {
|
||||
logger.error(`Blockchain couldn't find transaction: ${txHash}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const transaction_formatted = await extractTokenTransferData(transaction);
|
||||
return transaction_formatted;
|
||||
}
|
||||
|
||||
|
|
@ -41,12 +53,38 @@ export function extractNativeSolTransferData(transaction: any): TransferData | n
|
|||
}
|
||||
}
|
||||
|
||||
export function extractSplTokenTransferData(transaction: any): TransferData | null {
|
||||
async function getAtaOwner(ataAddress: string): Promise<string> {
|
||||
try {
|
||||
const connection = new Connection(CLUSTER_API, { commitment: 'confirmed' });
|
||||
const ataPublicKey = new PublicKey(ataAddress);
|
||||
const accountInfo = await connection.getAccountInfo(ataPublicKey);
|
||||
|
||||
if (!accountInfo) {
|
||||
logger.warn(`Could not find account info for ATA: ${ataAddress}`);
|
||||
return ataAddress; // Fallback to ATA address if we can't get owner
|
||||
}
|
||||
|
||||
// The owner is stored in the account data at a specific offset
|
||||
// For token accounts, the owner is at offset 32
|
||||
const ownerBytes = accountInfo.data.slice(32, 64);
|
||||
const owner = new PublicKey(ownerBytes);
|
||||
|
||||
return owner.toString();
|
||||
} catch (error) {
|
||||
logger.error(`Error getting ATA owner: ${error}`);
|
||||
return ataAddress; // Fallback to ATA address if there's an error
|
||||
}
|
||||
}
|
||||
|
||||
export async function extractSplTokenTransferData(transaction: any): Promise<TransferData | null> {
|
||||
try {
|
||||
// Check if this is an SPL token transfer
|
||||
const instructions = transaction.transaction.message.instructions;
|
||||
|
||||
// Try to find either transferChecked or transfer instruction
|
||||
const tokenTransferInstruction = instructions.find((instruction: any) =>
|
||||
instruction.program === "spl-token" && instruction.parsed?.type === "transferChecked"
|
||||
instruction.program === "spl-token" &&
|
||||
(instruction.parsed?.type === "transferChecked" || instruction.parsed?.type === "transfer")
|
||||
);
|
||||
|
||||
if (!tokenTransferInstruction) {
|
||||
|
|
@ -55,11 +93,37 @@ export function extractSplTokenTransferData(transaction: any): TransferData | nu
|
|||
|
||||
const transferInfo = tokenTransferInstruction.parsed.info;
|
||||
|
||||
// For transferChecked type
|
||||
if (tokenTransferInstruction.parsed.type === "transferChecked") {
|
||||
const receiverOwner = await getAtaOwner(transferInfo.destination);
|
||||
|
||||
return {
|
||||
sender: transferInfo.authority,
|
||||
receiver: receiverOwner,
|
||||
amount: parseInt(transferInfo.tokenAmount.amount),
|
||||
mint: transferInfo.mint,
|
||||
time: transaction.blockTime,
|
||||
blockhash: transaction.transaction.message.recentBlockhash
|
||||
};
|
||||
}
|
||||
|
||||
logger.debug(`It's not a transferChecked`);
|
||||
|
||||
// For transfer type
|
||||
const tokenBalances = transaction.meta.preTokenBalances;
|
||||
const mint = tokenBalances[0]?.mint;
|
||||
|
||||
if (!mint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const receiverOwner = await getAtaOwner(transferInfo.destination);
|
||||
|
||||
return {
|
||||
sender: transferInfo.source,
|
||||
receiver: transferInfo.destination,
|
||||
amount: parseInt(transferInfo.tokenAmount.amount),
|
||||
mint: transferInfo.mint,
|
||||
sender: transferInfo.authority,
|
||||
receiver: receiverOwner,
|
||||
amount: parseInt(transferInfo.amount),
|
||||
mint: mint,
|
||||
time: transaction.blockTime,
|
||||
blockhash: transaction.transaction.message.recentBlockhash
|
||||
};
|
||||
|
|
@ -69,7 +133,7 @@ export function extractSplTokenTransferData(transaction: any): TransferData | nu
|
|||
}
|
||||
}
|
||||
|
||||
export function extractTokenTransferData(transaction: any): TransferData | null {
|
||||
export async function extractTokenTransferData(transaction: ParsedTransactionWithMeta): Promise<TransferData | null> {
|
||||
// Try to extract native SOL transfer first
|
||||
const nativeSolData = extractNativeSolTransferData(transaction);
|
||||
if (nativeSolData) {
|
||||
|
|
@ -77,10 +141,12 @@ export function extractTokenTransferData(transaction: any): TransferData | null
|
|||
}
|
||||
|
||||
// Try to extract SPL token transfer
|
||||
const splTokenData = extractSplTokenTransferData(transaction);
|
||||
const splTokenData = await extractSplTokenTransferData(transaction);
|
||||
if (splTokenData) {
|
||||
return splTokenData;
|
||||
}
|
||||
|
||||
logger.error(`Error extracting token transfer data: ${transaction}`);
|
||||
|
||||
return null; // Not a recognized token transfer
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user