From 5e405c03db4a6bc896ebad27ef465bf84ecfcac3 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 7 Aug 2025 14:49:48 +0530 Subject: [PATCH] Add gorbagana chain ID --- src/app/api/registry/route.ts | 16 ++++++++++++---- src/utils/solana-verify.ts | 26 +++++++++++--------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 4d0c429..174992a 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -3,7 +3,7 @@ import { NextRequest, NextResponse } from 'next/server'; import axios from 'axios'; import assert from 'assert'; -import { Connection } from '@solana/web3.js'; +import { Connection, ParsedTransactionWithMeta } from '@solana/web3.js'; import { verifyUnusedSolanaPayment } from '@/utils/solana-verify'; import { transferLNTTokens } from '@/services/laconic-transfer'; @@ -25,6 +25,7 @@ const ALLOWED_SLIPPAGE_FACTOR = 0.2 // Use CAIP convention for chain ID: namespace + reference const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet +const GORBAGANA_CHAIN_ID = 'gorbagana:533uBE9RRquhTBqEX58oV52FdTTsReMd' // Gorbagana chain (first 32 characters of gorbagana genesis hash. Following solana CAIP chain ID pattern) // Sleep helper function const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); @@ -167,6 +168,7 @@ export async function POST(request: NextRequest) { // First check if the request body is valid JSON let url, txHash, senderPublicKey, paymentMethod; let connection: Connection; + let parsedTx: ParsedTransactionWithMeta | null; try { const body = await request.json(); @@ -186,6 +188,8 @@ export async function POST(request: NextRequest) { }, { status: 400 }); } + parsedTx = tx; + const signerKeys = tx.transaction.message.accountKeys .filter(k => k.signer) .map(k => k.pubkey.toBase58()); @@ -243,9 +247,13 @@ export async function POST(request: NextRequest) { const requiredAmountInBaseUnits = requiredTokenInfo.requiredAmountInBaseUnits; const expectedTokenAmount = Math.round(requiredAmountInBaseUnits - ALLOWED_SLIPPAGE_FACTOR * requiredAmountInBaseUnits); + if (!parsedTx) { + throw new Error(`Unable to find the tx with hash: ${txHash}`) + } + const solanaPaymentResult = await verifyUnusedSolanaPayment( connection, - txHash, + parsedTx, new BN(expectedTokenAmount), paymentMethod, ); @@ -457,7 +465,7 @@ export async function POST(request: NextRequest) { repository_ref: fullHash, }, external_payment: { - chain_id: SOLANA_CHAIN_ID, + chain_id: paymentMethod === PaymentMethod.SPL_TOKEN ? SOLANA_CHAIN_ID : GORBAGANA_CHAIN_ID, tx_hash: txHash, pubkey: senderPublicKey }, @@ -516,4 +524,4 @@ export async function POST(request: NextRequest) { message: error instanceof Error ? error.message : 'Unknown error', }, { status: 500 }); } -} \ No newline at end of file +} diff --git a/src/utils/solana-verify.ts b/src/utils/solana-verify.ts index 0e627dd..a7d76c6 100644 --- a/src/utils/solana-verify.ts +++ b/src/utils/solana-verify.ts @@ -1,6 +1,6 @@ import BN from 'bn.js'; -import { Connection, ParsedInstruction, PartiallyDecodedInstruction } from '@solana/web3.js'; +import { Connection, ParsedInstruction, ParsedTransactionWithMeta, PartiallyDecodedInstruction } from '@solana/web3.js'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { getRecipientAddress } from '@/services/solana'; @@ -8,13 +8,11 @@ import { PaymentMethod } from '../types'; // Extract transaction info for native GOR transfers const extractTxInfo = async ( - connection: Connection, - transactionSignature: string, + parsedTx: ParsedTransactionWithMeta, paymentMethod: PaymentMethod ): Promise<{ authority: string; amount: string; destination: string }> => { - const result = await connection.getParsedTransaction(transactionSignature, 'confirmed'); - if (!result) { + if (!parsedTx) { throw new Error('Transaction not found'); } @@ -23,7 +21,7 @@ const extractTxInfo = async ( switch (paymentMethod) { case PaymentMethod.NAT_GOR: // Look for system program transfer instruction - transferInstruction = result.transaction.message.instructions.find( + transferInstruction = parsedTx.transaction.message.instructions.find( (instr) => 'parsed' in instr && instr.parsed.type === 'transfer' ); @@ -36,7 +34,7 @@ const extractTxInfo = async ( case PaymentMethod.SPL_TOKEN: // Look for token transfer instruction using TOKEN_PROGRAM_ID - transferInstruction = result.transaction.message.instructions.find( + transferInstruction = parsedTx.transaction.message.instructions.find( (instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID) ); @@ -68,7 +66,7 @@ const extractTxInfo = async ( export const verifyUnusedSolanaPayment = async ( connection: Connection, - transactionSignature: string, + parsedTx: ParsedTransactionWithMeta, expectedAmount: BN, paymentMethod: PaymentMethod, ): Promise<{ @@ -81,9 +79,7 @@ export const verifyUnusedSolanaPayment = async ( // TODO: Check if provided signature is already used // Fetch transaction details - const transactionResult = await connection.getParsedTransaction(transactionSignature, 'confirmed'); - - if (!transactionResult) { + if (!parsedTx) { return { valid: false, reason: 'Transaction not found on Solana blockchain' @@ -91,15 +87,15 @@ export const verifyUnusedSolanaPayment = async ( } // Check if transaction was successful - if (transactionResult.meta?.err) { + if (parsedTx.meta?.err) { return { valid: false, - reason: `Transaction failed: ${JSON.stringify(transactionResult.meta.err)}` + reason: `Transaction failed: ${JSON.stringify(parsedTx.meta.err)}` }; } // Check transaction timestamp (5-minute window) - const txTimestamp = transactionResult.blockTime ? new Date(transactionResult.blockTime * 1000) : null; + const txTimestamp = parsedTx.blockTime ? new Date(parsedTx.blockTime * 1000) : null; if (!txTimestamp) { return { valid: false, @@ -119,7 +115,7 @@ export const verifyUnusedSolanaPayment = async ( } // Extract transaction info based on payment method - const transferInfo = await extractTxInfo(connection, transactionSignature, paymentMethod); + const transferInfo = await extractTxInfo(parsedTx, paymentMethod); const amount = transferInfo.amount; const authority = transferInfo.authority; const destination = transferInfo.destination;