Process Transaction

Endpoint: POST /api/v1/coin/tx

Description

This endpoint processes buy/sell transactions for tokens, updates OHLC (candlestick) data, records transaction details, and updates market cap. It also broadcasts updates through WebSocket for real-time price tracking.

Authentication

Required: Yes

Type: Bearer Token (JWT)

Request

Headers

Content-Type: application/json

Authorization: Bearer <your_jwt_token>

Body Parameters

Parameter
Type
Required
Description

token

string

Yes

The mint address of the token

txHash

string

Yes

The transaction hash/signature

type

string

Yes

Transaction type ('buy' or 'sell')

isInitial

boolean

No

Flag for initial token creation transaction

Example Request:

{

"token": "TokenMintAddress123...",

"txHash": "TransactionHash456...",

"type": "buy",

"isInitial": false

}

Response

Success Response

Status Code: 200 OK

Content-Type: application/json

interface TransactionResponse {

success: true;

txDetails: {

price: string;

tokenAmount: string;

solAmount: string;

blockTime: number;

metadata: any;

};

message: string;

}

Error Response

Status Code: 500 Internal Server Error

{

"error": "An internal error occurred. Please try again later."

}

Implementation Notes

OHLC Data Processing

interface OHLCData {

coinId: string;

timestamp: Date;

unixTimestamp: string;

open: string;

high: string;

low: string;

close: string;

volume: string;

numberOfTrades: number;

}

// Helper function to get 1-minute bucket timestamp

function get1MinBucketTimestamp(date: Date): Date {

const roundedDate = new Date(date);

roundedDate.setSeconds(0);

roundedDate.setMilliseconds(0);

return roundedDate;

}

// Process OHLC data for a transaction

async function processOHLCData(

coinId: string,

price: number,

quantity: number,

timestamp: Date

): Promise<void> {

const bucketTimestamp = get1MinBucketTimestamp(timestamp);

// Update or create candle logic

// ... implementation details in the code ...

}

Transaction Processing

// Example transaction processor

class TransactionProcessor {

constructor(

private readonly token: string,

private readonly txHash: string,

private readonly type: 'buy' | 'sell'

) {}

async process(): Promise<TransactionResponse> {

// Get current reserves

const reserveDetails = await this.getReserves();

const newPrice = this.calculatePrice(reserveDetails);

// Get transaction details

const txDetails = await this.getTransactionDetails();

// Process OHLC data

await this.updateOHLCData(txDetails, newPrice);

// Record transaction

await this.recordTransaction(txDetails);

// Update market cap

await this.updateMarketCap(newPrice);

return {

success: true,

txDetails,

message: "Transaction processed successfully"

};

}

private async getReserves() {

return await reserves(this.token);

}

private calculatePrice(reserveDetails: any) {

return reserveDetails.reserveTwo / reserveDetails.reserveOne;

}

private async getTransactionDetails() {

return this.type === 'buy'

? await getBuyTokenDetails(this.txHash)

: await getSellTokenDetails(this.txHash);

}

// ... additional helper methods ...

}

WebSocket Updates

// Example WebSocket notification handler

class TransactionNotifier {

private static instance: TransactionNotifier;

private connections: Map<string, Set<WebSocket>> = new Map();

static getInstance(): TransactionNotifier {

if (!TransactionNotifier.instance) {

TransactionNotifier.instance = new TransactionNotifier();

}

return TransactionNotifier.instance;

}

addConnection(tokenId: string, ws: WebSocket) {

if (!this.connections.has(tokenId)) {

this.connections.set(tokenId, new Set());

}

this.connections.get(tokenId)?.add(ws);

}

notifyUpdate(tokenId: string, data: OHLCData) {

const connections = this.connections.get(tokenId);

if (connections) {

connections.forEach(ws => {

if (ws.readyState === WebSocket.OPEN) {

ws.send(JSON.stringify({

type: 'OHLC_UPDATE',

data

}));

}

});

}

}

}

Best Practices

1. Transaction Validation

class TransactionValidator {

static validateBuyTransaction(txDetails: any): boolean {

return !!(

txDetails.price &&

txDetails.tokenAmount &&

txDetails.solAmount &&

txDetails.blockTime

);

}

static validateSellTransaction(txDetails: any): boolean {

return !!(

txDetails.price &&

txDetails.tokenAmount &&

txDetails.blockTime

);

}

static async validateReserves(

token: string,

expectedPrice: number

): Promise<boolean> {

const reserveDetails = await reserves(token);

const currentPrice =

reserveDetails.reserveTwo / reserveDetails.reserveOne;

// Allow for 1% price deviation

const deviation = Math.abs(currentPrice - expectedPrice) / expectedPrice;

return deviation <= 0.01;

}

}

Market Cap Updates

async function updateMarketCap(

token: string,

price: number

): Promise<void> {

const marketCap = price * config.constants.tokenSupply;

await db.update(coinsTable)

.set({ marketCap: String(marketCap) })

.where(eq(coinsTable.mintAddress, token));

// Notify subscribers of market cap update

publishMarketCapUpdate(token, marketCap);

}

Error Handling

class TransactionError extends Error {

constructor(

message: string,

public readonly code: string,

public readonly details?: any

) {

super(message);

this.name = 'TransactionError';

}

}

function handleTransactionError(error: any) {

if (error instanceof TransactionError) {

// Handle known error types

console.error(`Transaction Error (${error.code}):`, error.message);

return {

error: error.message,

code: error.code,

details: error.details

};

}

// Handle unknown errors

console.error('Unknown Transaction Error:', error);

return {

error: 'An internal error occurred. Please try again later.',

code: 'UNKNOWN_ERROR'

};

}

Last updated