From 4e34ea442adff2b50446eec47df8392a9f53a899 Mon Sep 17 00:00:00 2001 From: Nabarun Date: Mon, 21 Jul 2025 12:48:07 +0530 Subject: [PATCH] Move solana connection init inside functions --- deploy/README.md | 2 +- deploy/deploy.sh | 8 +++++--- src/app/api/registry/route.ts | 15 +++++++++++++-- src/components/PaymentModal.tsx | 16 ++++++++++++---- src/services/solana.ts | 5 +---- src/utils/solanaVerify.ts | 11 +++-------- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 1332428..04e6ccf 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -19,7 +19,7 @@ # Builds image cerc/laconic-registry-cli:latest ``` -* Configure `userKey` and `bondId` in the registry CLI config: +* Configure `userKey` and `bondId` in the [registry CLI config](./config.yml): ```bash nano config.yml diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 608deb0..2c9dcbf 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -11,11 +11,13 @@ echo "Using AUTHORITY: $AUTHORITY" # Repository URL REPO_URL="https://git.vdb.to/LaconicNetwork/gor-deploy" -# Get the latest commit hash from the repository -LATEST_HASH=$(git ls-remote $REPO_URL HEAD | awk '{print $1}') +# Get the latest commit hash for a branch +# TODO: Change to main before merging PR +BRANCH_NAME="sk-gor-deploy" +LATEST_HASH=$(git ls-remote $REPO_URL refs/heads/$BRANCH_NAME | awk '{print $1}') # TODO: Use a release -PACKAGE_VERSION=$(curl -s $REPO_URL/raw/branch/sk-gor-deploy/package.json | jq -r .version) +PACKAGE_VERSION=$(curl -s $REPO_URL/raw/branch/$BRANCH_NAME/package.json | jq -r .version) # TODO: Update app name APP_NAME=mtm-deploy diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 0eae0eb..25b6924 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -1,19 +1,24 @@ import BN from 'bn.js'; import { NextRequest, NextResponse } from 'next/server'; import axios from 'axios'; +import assert from 'assert'; import { GasPrice } from '@cosmjs/stargate'; +import { Connection } from '@solana/web3.js'; + import { verifyUnusedSolanaPayment } from '@/utils/solanaVerify'; import { transferLNTTokens } from '@/services/laconicTransfer'; import { getRegistry, getRegistryConfig } from '@/config'; +assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); +const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; + // Use CAIP convention for chain ID: namespace + reference const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet // Sleep helper function const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); - // Extract repo name from URL const extractRepoInfo = (url: string): { repoName: string, repoUrl: string, provider: string } => { try { @@ -124,8 +129,14 @@ export const registryTransactionWithRetry = async ( throw lastError; }; +let connection: Connection; + export async function POST(request: NextRequest) { try { + if (!connection) { + connection = new Connection(SOLANA_RPC_URL); + } + // First check if the request body is valid JSON let url, txHash, senderPublicKey; @@ -152,7 +163,7 @@ export async function POST(request: NextRequest) { console.log('Step 0: Verifying Solana token payment...'); const paymentAmount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000'); const tokenAmount = new BN(paymentAmount); - const solanaPaymentResult = await verifyUnusedSolanaPayment(txHash, tokenAmount); + const solanaPaymentResult = await verifyUnusedSolanaPayment(connection, txHash, tokenAmount); if (!solanaPaymentResult.valid) { console.error('Solana token payment verification failed:', solanaPaymentResult.reason); diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index f4ea945..ec40735 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -1,11 +1,17 @@ 'use client'; -import { useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import BN from 'bn.js'; +import assert from 'assert'; + +import { Connection } from '@solana/web3.js'; import { sendSolanaTokenPayment } from '@/services/solana'; import { PaymentModalProps } from '@/types'; +assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); +const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; + export default function PaymentModal({ isOpen, onClose, @@ -16,18 +22,20 @@ export default function PaymentModal({ const [loading, setLoading] = useState(false); const [error, setError] = useState(''); + const connection = useMemo(() => new Connection(SOLANA_RPC_URL), []) + // Get configuration from environment variables directly const amount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000'); const recipientAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS; - const handlePayment = async () => { + const handlePayment = useCallback(async () => { setLoading(true); setError(''); try { const tokenAmount = new BN(amount); - const result = await sendSolanaTokenPayment(walletState.publicKey!, tokenAmount, walletState.walletType!); + const result = await sendSolanaTokenPayment(connection, walletState.publicKey!, tokenAmount, walletState.walletType!); if (result.success && result.transactionSignature) { onPaymentComplete(result.transactionSignature); @@ -39,7 +47,7 @@ export default function PaymentModal({ } finally { setLoading(false); } - }; + }, [connection]); if (!isOpen) return null; diff --git a/src/services/solana.ts b/src/services/solana.ts index 5c0b8a4..00bcfd9 100644 --- a/src/services/solana.ts +++ b/src/services/solana.ts @@ -9,15 +9,11 @@ import { } from '@solana/spl-token'; import { SolanaPaymentResult, SolanaWalletType, SolanaWalletState } from '../types'; -assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); assert(process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS, 'SOLANA_TOKEN_MINT_ADDRESS is required'); assert(process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS, 'SOLANA_TOKEN_RECIPIENT_ADDRESS is required'); const TOKEN_MINT = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS; const PAYMENT_RECEIVER_ADDRESS = process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS; -const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; - -const connection = new Connection(SOLANA_RPC_URL); export const connectSolanaWallet = async (walletType: SolanaWalletType): Promise => { try { @@ -91,6 +87,7 @@ interface WalletAdapter { } export async function sendSolanaTokenPayment( + connection: Connection, walletPublicKey: string, tokenAmount: BN, walletType: SolanaWalletType diff --git a/src/utils/solanaVerify.ts b/src/utils/solanaVerify.ts index 3242204..5f8da42 100644 --- a/src/utils/solanaVerify.ts +++ b/src/utils/solanaVerify.ts @@ -4,14 +4,8 @@ import BN from 'bn.js'; import { Connection } from '@solana/web3.js'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); - -const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; - -const connection = new Connection(SOLANA_RPC_URL); - // Simplified transaction info extraction following reference implementation -const extractTxInfo = async (transactionSignature: string): Promise<{ authority: string; amount: string }> => { +const extractTxInfo = async (connection: Connection, transactionSignature: string): Promise<{ authority: string; amount: string }> => { const result = await connection.getParsedTransaction(transactionSignature, 'confirmed'); if (!result) { @@ -31,6 +25,7 @@ const extractTxInfo = async (transactionSignature: string): Promise<{ authority: }; export const verifyUnusedSolanaPayment = async ( + connection: Connection, transactionSignature: string, tokenAmount: BN ): Promise<{ @@ -81,7 +76,7 @@ export const verifyUnusedSolanaPayment = async ( } // Extract transaction info using simplified approach - const { amount, authority } = await extractTxInfo(transactionSignature); + const { amount, authority } = await extractTxInfo(connection, transactionSignature); // Verify amount using BN comparison like in reference const transactionAmount = new BN(amount);