Refactor paymentModal code
This commit is contained in:
parent
161a333642
commit
32b583a637
@ -3,13 +3,15 @@
|
||||
# Solana Payment Configuration
|
||||
# TODO: Use different RPC URL or use browser wallet
|
||||
NEXT_PUBLIC_SOLANA_RPC_URL=https://skilled-prettiest-seed.solana-mainnet.quiknode.pro/eeecfebd04e345f69f1900cc3483cbbfea02a158
|
||||
NEXT_PUBLIC_GORBAGANA_RPC_URL=https://rpc.gorbagana.wtf
|
||||
NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS=71Jvq4Epe2FCJ7JFSF7jLXdNk1Wy4Bhqd9iL6bEFELvg
|
||||
NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL=GOR
|
||||
NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD=5 # Payment amount in USD
|
||||
NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD=5
|
||||
|
||||
# Gorbagana Chain Configuration
|
||||
NEXT_PUBLIC_GORBAGANA_RPC_URL=https://rpc.gorbagana.wtf
|
||||
NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER=true
|
||||
|
||||
# Multisig address
|
||||
# Multisig Address
|
||||
NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS=FFDx3SdAEeXrp6BTmStB4BDHpctGsaasZq4FFcowRobY
|
||||
|
||||
# UI Configuration
|
||||
|
@ -11,11 +11,11 @@ import { verifyUnusedSolanaPayment } from '@/utils/solana-verify';
|
||||
import { transferLNTTokens } from '@/services/laconic-transfer';
|
||||
import { getRegistry, getRegistryConfig } from '@/config';
|
||||
import { getRequiredTokenInfo } from '@/services/jupiter-price';
|
||||
import { WRAPPED_SOL_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, WRAPPED_SOL_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { PaymentMethod } from '@/types';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
|
||||
assert(process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required');
|
||||
assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled');
|
||||
|
||||
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
|
||||
const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL;
|
||||
|
@ -10,7 +10,7 @@ import { BackpackWalletName } from '@solana/wallet-adapter-backpack';
|
||||
import URLForm from '@/components/URLForm';
|
||||
import StatusDisplay from '@/components/StatusDisplay';
|
||||
import { createApplicationDeploymentRequest } from '@/services/registry';
|
||||
import { PAYMENT_METHOD_LABELS } from '@/constants/payments';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, PAYMENT_METHOD_LABELS } from '@/constants/payments';
|
||||
import { usePaymentMethod } from '@/contexts/PaymentMethodContext';
|
||||
import { PaymentMethod } from '@/types';
|
||||
|
||||
@ -36,16 +36,14 @@ export default function Home() {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [incorrectChainWarining, setIncorrectChainWarining] = useState<string | null>(null);
|
||||
|
||||
const isNatGorEnabled = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true";
|
||||
|
||||
useEffect(() => {
|
||||
if (!isNatGorEnabled) {
|
||||
if (!IS_NAT_GOR_TRANSFER_ENABLED) {
|
||||
setSelectedPaymentMethod(PaymentMethod.SPL_TOKEN);
|
||||
}
|
||||
}, [isNatGorEnabled, setSelectedPaymentMethod]);
|
||||
}, [setSelectedPaymentMethod]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!wallet || wallet.adapter.name !== BackpackWalletName) {
|
||||
if (!wallet || wallet.adapter.name !== BackpackWalletName || selectedPaymentMethod !== PaymentMethod.NAT_GOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -58,7 +56,7 @@ export default function Home() {
|
||||
}
|
||||
|
||||
warnOnIncorrectChain();
|
||||
}, [wallet]);
|
||||
}, [wallet, selectedPaymentMethod]);
|
||||
|
||||
// Track previous payment method to detect switches
|
||||
const previousPaymentMethodRef = useRef<PaymentMethod | null>(null);
|
||||
@ -151,7 +149,7 @@ export default function Home() {
|
||||
</h1>
|
||||
|
||||
{/* Step 1: Payment Method Selection */}
|
||||
{ isNatGorEnabled &&
|
||||
{ IS_NAT_GOR_TRANSFER_ENABLED &&
|
||||
<div className="mb-10 p-6 rounded-lg" style={{ background: 'var(--muted-light)', borderLeft: '4px solid var(--primary)' }}>
|
||||
<h2 className="text-lg font-semibold mb-4 flex items-center">
|
||||
Choose Payment Method
|
||||
|
@ -1,18 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useMemo, useState, useEffect } from 'react';
|
||||
import { useCallback, useState, useEffect } from 'react';
|
||||
import assert from 'assert';
|
||||
|
||||
import { Connection, LAMPORTS_PER_SOL } from '@solana/web3.js';
|
||||
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
|
||||
|
||||
import { sendSolanaPayment, getRecipientAddress } from '@/services/solana';
|
||||
import { sendSolanaPayment } from '@/services/solana';
|
||||
import { getRequiredTokenInfo, RequiredTokenInfo } from '@/services/jupiter-price';
|
||||
import { PaymentMethod, PaymentModalProps, PaymentRequest } from '@/types';
|
||||
import { PAYMENT_METHOD_LABELS, WRAPPED_SOL_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { IS_NAT_GOR_TRANSFER_ENABLED, PAYMENT_METHOD_LABELS, WRAPPED_SOL_MINT_ADDRESS } from '@/constants/payments';
|
||||
import { usePaymentMethod } from '@/contexts/PaymentMethodContext';
|
||||
|
||||
assert(process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required');
|
||||
assert(!IS_NAT_GOR_TRANSFER_ENABLED || process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL, 'GORBAGANA_RPC_URL is required when NAT GOR transfer is enabled');
|
||||
|
||||
const GORBAGANA_RPC_URL = process.env.NEXT_PUBLIC_GORBAGANA_RPC_URL;
|
||||
|
||||
@ -24,7 +24,7 @@ export default function PaymentModal({
|
||||
}: PaymentModalProps) {
|
||||
const { selectedPaymentMethod: paymentMethod } = usePaymentMethod();
|
||||
|
||||
const { connection } = useConnection();
|
||||
const { connection: solanaConnection } = useConnection();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
@ -34,17 +34,10 @@ export default function PaymentModal({
|
||||
|
||||
const { wallet, publicKey } = useWallet();
|
||||
|
||||
const solanaConnection = connection;
|
||||
|
||||
const gorbaganaConnection = useMemo(() =>
|
||||
GORBAGANA_RPC_URL ? new Connection(GORBAGANA_RPC_URL) : solanaConnection,
|
||||
[solanaConnection]
|
||||
);
|
||||
|
||||
// Get configuration from environment variables
|
||||
const targetUsdAmount = parseFloat(process.env.NEXT_PUBLIC_SOLANA_PAYMENT_AMOUNT_USD!);
|
||||
const mintAddress = process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS!;
|
||||
const tokenSymbol = process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL || 'TOKEN';
|
||||
const tokenSymbol = process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL;
|
||||
|
||||
// Fetch payment amount based on USD price for both payment methods
|
||||
useEffect(() => {
|
||||
@ -113,11 +106,10 @@ export default function PaymentModal({
|
||||
const paymentRequest: PaymentRequest = {
|
||||
paymentMethod: paymentMethod,
|
||||
amount: tokenAmount,
|
||||
recipientAddress: getRecipientAddress(paymentMethod)
|
||||
};
|
||||
|
||||
// Use different RPC connection based on payment method
|
||||
const connectionToUse = paymentMethod === PaymentMethod.NAT_GOR ? gorbaganaConnection : solanaConnection;
|
||||
const connectionToUse = paymentMethod === PaymentMethod.NAT_GOR ? new Connection(GORBAGANA_RPC_URL!) : solanaConnection;
|
||||
|
||||
const result = await sendSolanaPayment(
|
||||
wallet.adapter,
|
||||
@ -136,7 +128,7 @@ export default function PaymentModal({
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [paymentMethod, tokenAmount, loadingPrice, wallet, solanaConnection, gorbaganaConnection, publicKey, onPaymentComplete]);
|
||||
}, [paymentMethod, tokenAmount, loadingPrice, wallet, solanaConnection, publicKey, onPaymentComplete]);
|
||||
|
||||
const getPaymentAmountDisplay = () => {
|
||||
if (loadingPrice) return 'Loading...';
|
||||
@ -187,7 +179,7 @@ export default function PaymentModal({
|
||||
<div>
|
||||
<p className="text-sm mb-2 font-medium" style={{ color: 'var(--muted)' }}>Recipient Address:</p>
|
||||
<div className="p-3 rounded-md overflow-hidden" style={{ background: 'var(--muted-light)', color: 'var(--foreground)' }}>
|
||||
<code className="text-sm font-mono break-all block">{getRecipientAddress(paymentMethod)}</code>
|
||||
<code className="text-sm font-mono break-all block">{process.env.NEXT_PUBLIC_SOLANA_TOKEN_RECIPIENT_ADDRESS}</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -3,10 +3,9 @@ import { PaymentMethod } from "@/types";
|
||||
// Payment method labels for UI
|
||||
export const PAYMENT_METHOD_LABELS: Record<PaymentMethod, string> = {
|
||||
[PaymentMethod.NAT_GOR]: 'GOR (native)',
|
||||
[PaymentMethod.SPL_TOKEN]: process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL || 'SPL Token'
|
||||
[PaymentMethod.SPL_TOKEN]: process.env.NEXT_PUBLIC_SOLANA_TOKEN_SYMBOL!
|
||||
};
|
||||
|
||||
// Default payment method (none selected initially)
|
||||
export const DEFAULT_PAYMENT_METHOD: PaymentMethod | null = null;
|
||||
|
||||
export const WRAPPED_SOL_MINT_ADDRESS = 'So11111111111111111111111111111111111111112';
|
||||
|
||||
export const IS_NAT_GOR_TRANSFER_ENABLED = process.env.NEXT_PUBLIC_ENABLE_NATIVE_GOR_TRANSFER === "true";
|
||||
|
@ -46,7 +46,6 @@ export interface PaymentModalProps {
|
||||
export interface PaymentRequest {
|
||||
paymentMethod: PaymentMethod;
|
||||
amount: number; // in base units (lamports for native GOR, token base units for SPL)
|
||||
recipientAddress: string;
|
||||
}
|
||||
|
||||
export interface LaconicTransferResult {
|
||||
|
@ -35,31 +35,31 @@ const extractTxInfo = async (
|
||||
return { authority: source, amount: lamports.toString(), destination };
|
||||
|
||||
case PaymentMethod.SPL_TOKEN:
|
||||
// Look for token transfer instruction using TOKEN_PROGRAM_ID
|
||||
transferInstruction = result.transaction.message.instructions.find(
|
||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||
);
|
||||
// Look for token transfer instruction using TOKEN_PROGRAM_ID
|
||||
transferInstruction = result.transaction.message.instructions.find(
|
||||
(instr) => 'parsed' in instr && instr.programId.equals(TOKEN_PROGRAM_ID)
|
||||
);
|
||||
|
||||
if (!transferInstruction || !('parsed' in transferInstruction)) {
|
||||
throw new Error('SPL token transfer instruction not found');
|
||||
}
|
||||
if (!transferInstruction || !('parsed' in transferInstruction)) {
|
||||
throw new Error('SPL token transfer instruction not found');
|
||||
}
|
||||
|
||||
const parsed = transferInstruction.parsed;
|
||||
const parsed = transferInstruction.parsed;
|
||||
|
||||
// Handle both transferChecked and transfer types
|
||||
if (parsed.type === 'transferChecked') {
|
||||
const { info: { tokenAmount, authority, destination } } = parsed;
|
||||
return {
|
||||
authority,
|
||||
amount: tokenAmount.amount,
|
||||
destination
|
||||
};
|
||||
} else if (parsed.type === 'transfer') {
|
||||
const { info: { amount, authority, destination } } = parsed;
|
||||
return { authority, amount, destination };
|
||||
}
|
||||
// Handle both transferChecked and transfer types
|
||||
if (parsed.type === 'transferChecked') {
|
||||
const { info: { tokenAmount, authority, destination } } = parsed;
|
||||
return {
|
||||
authority,
|
||||
amount: tokenAmount.amount,
|
||||
destination
|
||||
};
|
||||
} else if (parsed.type === 'transfer') {
|
||||
const { info: { amount, authority, destination } } = parsed;
|
||||
return { authority, amount, destination };
|
||||
}
|
||||
|
||||
throw new Error('Unsupported token transfer type');
|
||||
throw new Error('Unsupported token transfer type');
|
||||
|
||||
default:
|
||||
throw new Error('Invalid payment method');
|
||||
@ -119,10 +119,10 @@ export const verifyUnusedSolanaPayment = async (
|
||||
}
|
||||
|
||||
// Extract transaction info based on payment method
|
||||
const transferInfo = await extractTxInfo(connection, transactionSignature, paymentMethod);
|
||||
const amount = transferInfo.amount;
|
||||
const authority = transferInfo.authority;
|
||||
const destination = transferInfo.destination;
|
||||
const transferInfo = await extractTxInfo(connection, transactionSignature, paymentMethod);
|
||||
const amount = transferInfo.amount;
|
||||
const authority = transferInfo.authority;
|
||||
const destination = transferInfo.destination;
|
||||
|
||||
// Verify amount using BN comparison
|
||||
const transactionAmount = new BN(amount);
|
||||
|
Loading…
Reference in New Issue
Block a user