Move solana connection init inside functions
This commit is contained in:
parent
e57c4b24ad
commit
4e34ea442a
@ -19,7 +19,7 @@
|
|||||||
# Builds image cerc/laconic-registry-cli:latest
|
# 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
|
```bash
|
||||||
nano config.yml
|
nano config.yml
|
||||||
|
|||||||
@ -11,11 +11,13 @@ echo "Using AUTHORITY: $AUTHORITY"
|
|||||||
# Repository URL
|
# Repository URL
|
||||||
REPO_URL="https://git.vdb.to/LaconicNetwork/gor-deploy"
|
REPO_URL="https://git.vdb.to/LaconicNetwork/gor-deploy"
|
||||||
|
|
||||||
# Get the latest commit hash from the repository
|
# Get the latest commit hash for a branch
|
||||||
LATEST_HASH=$(git ls-remote $REPO_URL HEAD | awk '{print $1}')
|
# 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
|
# 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
|
# TODO: Update app name
|
||||||
APP_NAME=mtm-deploy
|
APP_NAME=mtm-deploy
|
||||||
|
|||||||
@ -1,19 +1,24 @@
|
|||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { NextRequest, NextResponse } from 'next/server';
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import assert from 'assert';
|
||||||
|
|
||||||
import { GasPrice } from '@cosmjs/stargate';
|
import { GasPrice } from '@cosmjs/stargate';
|
||||||
|
import { Connection } from '@solana/web3.js';
|
||||||
|
|
||||||
import { verifyUnusedSolanaPayment } from '@/utils/solanaVerify';
|
import { verifyUnusedSolanaPayment } from '@/utils/solanaVerify';
|
||||||
import { transferLNTTokens } from '@/services/laconicTransfer';
|
import { transferLNTTokens } from '@/services/laconicTransfer';
|
||||||
import { getRegistry, getRegistryConfig } from '@/config';
|
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
|
// Use CAIP convention for chain ID: namespace + reference
|
||||||
const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet
|
const SOLANA_CHAIN_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; // Solana mainnet
|
||||||
|
|
||||||
// Sleep helper function
|
// Sleep helper function
|
||||||
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
|
|
||||||
// Extract repo name from URL
|
// Extract repo name from URL
|
||||||
const extractRepoInfo = (url: string): { repoName: string, repoUrl: string, provider: string } => {
|
const extractRepoInfo = (url: string): { repoName: string, repoUrl: string, provider: string } => {
|
||||||
try {
|
try {
|
||||||
@ -124,8 +129,14 @@ export const registryTransactionWithRetry = async (
|
|||||||
throw lastError;
|
throw lastError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let connection: Connection;
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
|
if (!connection) {
|
||||||
|
connection = new Connection(SOLANA_RPC_URL);
|
||||||
|
}
|
||||||
|
|
||||||
// First check if the request body is valid JSON
|
// First check if the request body is valid JSON
|
||||||
let url, txHash, senderPublicKey;
|
let url, txHash, senderPublicKey;
|
||||||
|
|
||||||
@ -152,7 +163,7 @@ export async function POST(request: NextRequest) {
|
|||||||
console.log('Step 0: Verifying Solana token payment...');
|
console.log('Step 0: Verifying Solana token payment...');
|
||||||
const paymentAmount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000');
|
const paymentAmount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000');
|
||||||
const tokenAmount = new BN(paymentAmount);
|
const tokenAmount = new BN(paymentAmount);
|
||||||
const solanaPaymentResult = await verifyUnusedSolanaPayment(txHash, tokenAmount);
|
const solanaPaymentResult = await verifyUnusedSolanaPayment(connection, txHash, tokenAmount);
|
||||||
|
|
||||||
if (!solanaPaymentResult.valid) {
|
if (!solanaPaymentResult.valid) {
|
||||||
console.error('Solana token payment verification failed:', solanaPaymentResult.reason);
|
console.error('Solana token payment verification failed:', solanaPaymentResult.reason);
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
|
import assert from 'assert';
|
||||||
|
|
||||||
|
import { Connection } from '@solana/web3.js';
|
||||||
|
|
||||||
import { sendSolanaTokenPayment } from '@/services/solana';
|
import { sendSolanaTokenPayment } from '@/services/solana';
|
||||||
import { PaymentModalProps } from '@/types';
|
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({
|
export default function PaymentModal({
|
||||||
isOpen,
|
isOpen,
|
||||||
onClose,
|
onClose,
|
||||||
@ -16,18 +22,20 @@ export default function PaymentModal({
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
|
const connection = useMemo(() => new Connection(SOLANA_RPC_URL), [])
|
||||||
|
|
||||||
// Get configuration from environment variables directly
|
// Get configuration from environment variables directly
|
||||||
const amount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000');
|
const amount = parseInt(process.env.NEXT_PUBLIC_MIN_SOLANA_PAYMENT_AMOUNT || '400000000');
|
||||||
|
|
||||||
const recipientAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS;
|
const recipientAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS;
|
||||||
|
|
||||||
const handlePayment = async () => {
|
const handlePayment = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError('');
|
setError('');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const tokenAmount = new BN(amount);
|
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) {
|
if (result.success && result.transactionSignature) {
|
||||||
onPaymentComplete(result.transactionSignature);
|
onPaymentComplete(result.transactionSignature);
|
||||||
@ -39,7 +47,7 @@ export default function PaymentModal({
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, [connection]);
|
||||||
|
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
|
|||||||
@ -9,15 +9,11 @@ import {
|
|||||||
} from '@solana/spl-token';
|
} from '@solana/spl-token';
|
||||||
import { SolanaPaymentResult, SolanaWalletType, SolanaWalletState } from '../types';
|
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_MINT_ADDRESS, 'SOLANA_TOKEN_MINT_ADDRESS is required');
|
||||||
assert(process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS, 'SOLANA_TOKEN_RECIPIENT_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 TOKEN_MINT = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS;
|
||||||
const PAYMENT_RECEIVER_ADDRESS = process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_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<SolanaWalletState> => {
|
export const connectSolanaWallet = async (walletType: SolanaWalletType): Promise<SolanaWalletState> => {
|
||||||
try {
|
try {
|
||||||
@ -91,6 +87,7 @@ interface WalletAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function sendSolanaTokenPayment(
|
export async function sendSolanaTokenPayment(
|
||||||
|
connection: Connection,
|
||||||
walletPublicKey: string,
|
walletPublicKey: string,
|
||||||
tokenAmount: BN,
|
tokenAmount: BN,
|
||||||
walletType: SolanaWalletType
|
walletType: SolanaWalletType
|
||||||
|
|||||||
@ -4,14 +4,8 @@ import BN from 'bn.js';
|
|||||||
import { Connection } from '@solana/web3.js';
|
import { Connection } from '@solana/web3.js';
|
||||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
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
|
// 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');
|
const result = await connection.getParsedTransaction(transactionSignature, 'confirmed');
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -31,6 +25,7 @@ const extractTxInfo = async (transactionSignature: string): Promise<{ authority:
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const verifyUnusedSolanaPayment = async (
|
export const verifyUnusedSolanaPayment = async (
|
||||||
|
connection: Connection,
|
||||||
transactionSignature: string,
|
transactionSignature: string,
|
||||||
tokenAmount: BN
|
tokenAmount: BN
|
||||||
): Promise<{
|
): Promise<{
|
||||||
@ -81,7 +76,7 @@ export const verifyUnusedSolanaPayment = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract transaction info using simplified approach
|
// 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
|
// Verify amount using BN comparison like in reference
|
||||||
const transactionAmount = new BN(amount);
|
const transactionAmount = new BN(amount);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user