### Contributing and Setup Commands Source: https://github.com/hanslove/nowpayments-components/blob/main/README.md Steps for contributing to the project, including cloning, installing dependencies, and starting Storybook for development. ```bash 1. Clone the repository 2. Install dependencies: `npm install` 3. Start Storybook: `npm run storybook` 4. Make changes and test in Storybook 5. Run linting: `npm run lint` 6. Submit a pull request ``` -------------------------------- ### Install nowpayments-components Source: https://github.com/hanslove/nowpayments-components/blob/main/src/stories/Introduction.mdx Install the library using npm. ```bash npm install @taloon/nowpayments-components ``` -------------------------------- ### Start Storybook Command Source: https://github.com/hanslove/nowpayments-components/blob/main/src/stories/README.md Command to start the Storybook development server. ```bash npm run storybook ``` -------------------------------- ### Setup NowPaymentsProvider Source: https://github.com/hanslove/nowpayments-components/blob/main/README.md Wrap your application with NowPaymentsProvider and provide your API key. ```tsx import { NowPaymentsProvider } from '@taloon/nowpayments-components' function App() { return ( ) } ``` -------------------------------- ### Environment Variables Setup Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/basic-integration.mdx Define your backend API URL and webhook secret for IPN validation. ```env NEXT_PUBLIC_API_URL=https://your-api.com NOWPAYMENTS_WEBHOOK_SECRET=your-webhook-secret ``` -------------------------------- ### Basic NowPayments Component Setup Source: https://github.com/hanslove/nowpayments-components/blob/main/progress.md Initializes the NowPayments components by importing necessary modules and setting the API key globally. Ensure styles are imported. ```typescript import { DepositModal, useNowPaymentsStore } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' // Global setup useNowPaymentsStore().setApiKey('your-nowpayments-key') ``` -------------------------------- ### DepositModal onSuccess Mapping - Example 1 Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/deposit-modal.mdx Illustrates how to map a custom backend response structure to the `PaymentDetails` interface within the `onSuccess` callback. This example assumes a nested structure for address and reference. ```javascript // Backend response (any structure) { id: "dep_123", paymentData: { address: "1A2B3C4D5E", reference: "payment_123" }, amount: 0.001, currency: "btc", status: "waiting" } // onSuccess mapping onSuccess: (backendResponse) => { return { address: backendResponse.paymentData.address, paymentId: backendResponse.paymentData.reference } } ``` -------------------------------- ### Basic Usage of ContinueWithNowPayments Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/continue-with-nowpayments.mdx Demonstrates the basic integration of the ContinueWithNowPayments component, including necessary imports and an example click handler. ```tsx import { ContinueWithNowPayments } from '@taloon/nowpayments-components' function PaymentButton() { const handlePaymentClick = () => { // Open payment modal or navigate to payment page console.log('Payment initiated') } return ( ) } ``` -------------------------------- ### Handling Loading States with ContinueWithNowPayments Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/continue-with-nowpayments.mdx This example demonstrates how to manage the loading state of the payment process using the `isProcessing` state and disabling the button accordingly. ```tsx function SmartPaymentButton() { const [isProcessing, setIsProcessing] = useState(false) const handleClick = async () => { setIsProcessing(true) try { await initializePayment() } finally { setIsProcessing(false) } } return ( ) } ``` -------------------------------- ### Mock Currencies and Store Setup (Storybook) Source: https://github.com/hanslove/nowpayments-components/blob/main/progress.md Sets up mock currency data and configures the NowPayments store for use in Storybook. Ensure the `Currency` type is defined elsewhere. ```typescript // Mock currencies for Storybook const mockCurrencies: Currency[] = [ { id: 1, code: 'BTC', name: 'Bitcoin', cg_id: 'btc', ... }, { id: 2, code: 'ETH', name: 'Ethereum', cg_id: 'eth', ... }, ] // Setup in decorators const store = useNowPaymentsStore.getState() store.setCurrencies(mockCurrencies) store.setEnabledCurrencies(['btc', 'eth']) store.setApiKey('mock-api-key') ``` -------------------------------- ### Development and Build Commands Source: https://github.com/hanslove/nowpayments-components/blob/main/README.md Common npm scripts for installing dependencies, running Storybook for component development, building the library, and performing linting and type checking. ```bash # Install dependencies npm install # Start Storybook for component development npm run storybook # Build library npm run build # Run linting npm run lint # Type checking npm run type-check ``` -------------------------------- ### Minimal Theme Example Source: https://github.com/hanslove/nowpayments-components/blob/main/CSS_THEMING.md Applies a minimal grayscale theme with sharp corners by overriding primary, surface, text, border, and radius variables. ```css :root { /* Minimal grayscale */ --np-primary: #000000; --np-primary-hover: #1f2937; --np-surface: #ffffff; --np-on-surface: #000000; --np-border: #e5e7eb; /* Minimal spacing */ --np-spacing-md: 0.5rem; --np-spacing-lg: 0.75rem; --np-spacing-xl: 1rem; /* Sharp corners */ --np-radius: 0; --np-radius-lg: 0; } ``` -------------------------------- ### Custom Brand Theme Example Source: https://github.com/hanslove/nowpayments-components/blob/main/CSS_THEMING.md Demonstrates how to create a custom brand theme by overriding primary colors, accent color, radius, and font family. ```css :root { /* Purple brand theme */ --np-primary: #7c3aed; --np-primary-hover: #6d28d9; --np-primary-active: #5b21b6; --np-accent: #f59e0b; /* Custom radius */ --np-radius: 0.75rem; --np-radius-lg: 1rem; /* Custom font */ --np-font-family: 'Inter', sans-serif; } ``` -------------------------------- ### Custom Theme Example: Gaming Theme Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/theming/css-variables.mdx An example of a custom theme inspired by 'Caos Engines', demonstrating overrides for colors, surfaces, typography, shadows, and gradients, along with specific component styling. ```css :root { /* Primary colors */ --np-primary: #e53e3e; --np-primary-hover: #c53030; --np-primary-active: #9b2c2c; /* Dark surfaces */ --np-surface: #0a0e1a; --np-surface-variant: #1a1f2e; --np-surface-hover: #2d3447; /* Bright text */ --np-on-surface: #ffffff; --np-on-surface-variant: #a0aec0; --np-on-primary: #ffffff; /* Accent colors */ --np-accent: #00d4ff; --np-accent-hover: #0bc5ea; --np-secondary: #4fd1c7; /* Status colors */ --np-error: #ff6b6b; --np-error-hover: #ee5a52; --np-success: #06ffa5; --np-success-hover: #38d9a9; --np-warning: #ffd93d; /* Borders */ --np-border: #2d3447; --np-border-variant: #4a5568; /* Glows and effects */ --np-glow-primary: 0 0 20px rgba(229, 62, 62, 0.3); --np-glow-accent: 0 0 20px rgba(0, 212, 255, 0.3); --np-glow-success: 0 0 20px rgba(6, 255, 165, 0.3); /* Enhanced shadows */ --np-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.3); --np-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); --np-shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.5); --np-shadow-xl: 0 20px 40px rgba(0, 0, 0, 0.6); /* Gradients */ --np-gradient-primary: linear-gradient(135deg, #e53e3e 0%, #c53030 100%); --np-gradient-surface: linear-gradient(135deg, #0a0e1a 0%, #1a1f2e 100%); --np-gradient-accent: linear-gradient(135deg, #00d4ff 0%, #4fd1c7 100%); } /* Apply gaming theme styles */ .caos-theme .np-modal { background: var(--np-gradient-surface); border: 1px solid var(--np-border); box-shadow: var(--np-shadow-xl), var(--np-glow-primary); } .caos-theme .np-button--primary { background: var(--np-gradient-primary); box-shadow: var(--np-glow-primary); transition: all 0.3s ease; } .caos-theme .np-button--primary:hover { box-shadow: var(--np-glow-primary), 0 0 30px rgba(229, 62, 62, 0.5); transform: translateY(-1px); } .caos-theme .np-input { background: rgba(26, 31, 46, 0.8); border: 1px solid var(--np-border); color: var(--np-on-surface); transition: all 0.3s ease; } .caos-theme .np-input:focus { border-color: var(--np-accent); box-shadow: var(--np-glow-accent); } ``` -------------------------------- ### Custom CSS for ContinueWithNowPayments Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/continue-with-nowpayments.mdx Provides examples of overriding default styles and creating custom visual variants for the ContinueWithNowPayments component using CSS. ```css /* Override button colors */ .np-continue-btn { --np-primary: #your-brand-color; --np-primary-hover: #your-hover-color; } /* Custom variant */ .my-custom-payment-button { background: linear-gradient(45deg, #ff6b6b, #4ecdc4); border: none; transform: scale(1); transition: transform 0.2s ease; } .my-custom-payment-button:hover { transform: scale(1.02); } ``` -------------------------------- ### Client CSS Variable Usage Example Source: https://github.com/hanslove/nowpayments-components/blob/main/progress.md Demonstrates how a client can customize the NOWPayments component theme using CSS Custom Properties, including dark mode support. ```css :root { --np-primary: #7c3aed; --np-surface: #ffffff; } @media (prefers-color-scheme: dark) { :root { --np-surface: #1f2937; --np-on-surface: #ffffff; } } ``` -------------------------------- ### Integrate NOWPayments in a React App Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/basic-integration.mdx Set up the NowPaymentsProvider and use DepositModal, WithdrawModal, and ContinueWithNowPayments components. Remember to import styles manually. This example demonstrates handling form submissions and updating UI state. ```tsx import { useState } from 'react' import { NowPaymentsProvider, DepositModal, WithdrawModal, ContinueWithNowPayments } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' function App() { const [showDeposit, setShowDeposit] = useState(false) const [showWithdraw, setShowWithdraw] = useState(false) const [balance, setBalance] = useState(1000) const handleDepositSubmit = async (formData) => { // Simulate API call console.log('Creating deposit:', formData) const response = await fetch('/api/deposits', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }) return response.json() } const handleWithdrawSubmit = async (formData) => { // Simulate API call console.log('Creating withdrawal:', formData) const response = await fetch('/api/withdrawals', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }) return response.json() } const convertBalanceToUsdt = async (amount) => { // Simulate conversion rate return amount * 0.95 } return (

Crypto Wallet App

Balance: ${balance}

setShowDeposit(true)} size="large" fullWidth />
setShowDeposit(false)} onSubmit={handleDepositSubmit} onSuccess={(result) => { console.log('Deposit successful:', result) setShowDeposit(false) // Update balance setBalance(prev => prev + result.amount) // Return PaymentDetails for component return { address: result.depositAddress, paymentId: result.paymentId } }} onError={(error) => { console.error('Deposit failed:', error) }} /> setShowWithdraw(false)} availableBalance={balance} balanceToUsdtConverter={convertBalanceToUsdt} onSubmit={handleWithdrawSubmit} onSuccess={(result) => { console.log('Withdrawal successful:', result) setShowWithdraw(false) // Update balance setBalance(prev => prev - result.amount) }} onError={(error) => { console.error('Withdrawal failed:', error) }} />
) } export default App ``` -------------------------------- ### onSuccess Callback Examples Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Demonstrates various ways to map backend responses to the onSuccess callback, including simple ID mapping, nested data, async processing, and conditional logic. ```typescript // Example 1: Simple ID mapping onSuccess={(response) => ({ transactionId: response.id })} // Example 2: Nested data structure onSuccess={(response) => ({ transactionId: response.data.transactionId })} // Example 3: Async processing onSuccess={async (response) => { // Optionally do additional processing await logWithdrawal(response) return { transactionId: response.withdrawalId } }} // Example 4: Conditional mapping onSuccess={(response) => ({ transactionId: response.txId || response.id || 'PENDING' })} ``` -------------------------------- ### DepositModal onSuccess Mapping - Example 2 Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/deposit-modal.mdx Provides an alternative mapping for the `onSuccess` callback when the backend response directly contains `depositAddress` and `paymentId` properties. ```javascript // Minimal backend response { depositAddress: "1A2B3C4D5E", paymentId: "payment_123" } // Direct mapping onSuccess: (response) => ({ address: response.depositAddress, paymentId: response.paymentId }) ``` -------------------------------- ### Customize Theming with CSS Variables Source: https://github.com/hanslove/nowpayments-components/blob/main/src/stories/Introduction.mdx Customize the appearance of the components by overriding CSS variables. This example sets primary, secondary, surface, and border colors. ```css :root { --np-primary: #3b82f6; --np-secondary: #6b7280; --np-surface: #ffffff; --np-border: #e5e7eb; } ``` -------------------------------- ### Standard React Component Structure Source: https://github.com/hanslove/nowpayments-components/blob/main/CLAUDE.md Illustrates a typical React component setup including state, form, custom hooks, effects, event handlers, and rendering. Ensure all imports and types are correctly defined. ```tsx // ✅ Standard component structure import React, { useState, useEffect } from 'react' import { useForm } from 'react-hook-form' import type { ComponentProps } from '@/types' interface LocalState { // Component-specific local state } export function ComponentName({ prop1, prop2, onCallback, }: ComponentProps) { // 1. State hooks const [localState, setLocalState] = useState() // 2. Form hooks const { register, handleSubmit, formState: { errors } } = useForm() // 3. Custom hooks const { currencies, isLoading } = useCurrencies() // 4. Effects useEffect(() => { // Side effects }, [dependencies]) // 5. Event handlers const handleEvent = async () => { // Handle events } // 6. Render return (
{/* JSX content */}
) } export default ComponentName ``` -------------------------------- ### Configure Vite for SCSS Imports Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/styling-guide.mdx Ensure your build tool includes CSS from node_modules by configuring the SCSS preprocessor options. This example shows how to import component styles in Vite. ```javascript export default { css: { preprocessorOptions: { scss: { additionalData: `@import "@taloon/nowpayments-components/styles";` } } } } ``` -------------------------------- ### Multi-Step Payment Flow with Deposit Modal Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/advanced-patterns.mdx Implement a multi-step payment process using React state management. This example shows how to handle different payment stages, including a crypto deposit flow managed by a `DepositModal` component. ```tsx import { useState } from 'react' import { DepositModal } from '@taloon/nowpayments-components' type PaymentStep = 'amount' | 'method' | 'confirm' | 'complete' function MultiStepPayment() { const [currentStep, setCurrentStep] = useState('amount') const [paymentData, setPaymentData] = useState({ amount: 0, purpose: '', method: 'crypto' }) const [showDepositModal, setShowDepositModal] = useState(false) const handleAmountSubmit = (amount: number, purpose: string) => { setPaymentData(prev => ({ ...prev, amount, purpose })) setCurrentStep('method') } const handleMethodSelect = (method: string) => { setPaymentData(prev => ({ ...prev, method })) if (method === 'crypto') { setShowDepositModal(true) } else { setCurrentStep('confirm') } } const handleDepositSubmit = async (formData) => { const enrichedData = { ...formData, amount: paymentData.amount, purpose: paymentData.purpose, sessionId: Date.now().toString() } const response = await fetch('/api/payments/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(enrichedData) }) return response.json() } const handleDepositSuccess = (result) => { setShowDepositModal(false) setCurrentStep('complete') // Store payment result for confirmation page setPaymentData(prev => ({ ...prev, result })) } return (
Amount
Method
Confirm
Complete
{currentStep === 'amount' && ( )} {currentStep === 'method' && ( )} {currentStep === 'confirm' && ( setCurrentStep('complete')} /> )} {currentStep === 'complete' && ( )} setShowDepositModal(false)} onSubmit={handleDepositSubmit} onSuccess={handleDepositSuccess} onError={(error) => { console.error('Payment failed:', error) setShowDepositModal(false) }} />
) } ``` -------------------------------- ### Basic WithdrawModal Usage Example Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Demonstrates how to integrate the WithdrawModal component into a React application. It includes setting up state for modal visibility, defining a balance conversion function, and handling form submission with a mock API call. ```tsx import { useState } from 'react' import { WithdrawModal, type WithdrawFormData } from '@taloon/nowpayments-components' function WithdrawExample() { const [isOpen, setIsOpen] = useState(false) const userBalance = 1000 // User's available balance in your system // Convert your internal balance to USDT for display const convertToUsdt = async (amount: number) => { // Example: Your balance is in points, convert to USDT const rate = 0.95 // 1 point = 0.95 USDT return amount * rate } const handleSubmit = async (formData: WithdrawFormData) => { // Send to your backend API const response = await fetch('/api/withdrawals', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...formData, userId: 'user-123' }) }) if (!response.ok) { throw new Error('Failed to create withdrawal') } return response.json() } return ( <> setIsOpen(false)} availableBalance={userBalance} balanceToUsdtConverter={convertToUsdt} onSubmit={handleSubmit} onSuccess={(result) => { console.log('Withdrawal created:', result) // Map backend response to WithdrawalDetails return { transactionId: result.data.id // or result.withdrawalId, etc. } }} onError={(error) => { console.error('Error:', error.message) // Optionally return custom error message return 'Failed to process withdrawal. Please try again.' }} /> ) } ``` -------------------------------- ### Get All Currencies with Metadata Source: https://context7.com/hanslove/nowpayments-components/llms.txt Fetch all available currencies with their full metadata, including logos, wallet regex, and network information. Handles success and error responses. ```typescript // 1. Get all currencies with full metadata (logos, wallet regex, network, etc.) const allResult = await api.getAllCurrencies() if (allResult.success) { console.log('Total currencies:', allResult.data?.currencies.length) // allResult.data.currencies[0]: { id, code, name, logo_url, network, wallet_regex, … } } else { console.error('getAllCurrencies failed:', allResult.error) } ``` -------------------------------- ### Implement Robust Payment Flow with Retry Logic Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/advanced-patterns.mdx This example shows how to build a payment flow that automatically retries failed operations based on configurable error types and backoff strategies. It includes network error handling, timeouts, and exponential backoff. ```tsx import { useState, useCallback } from 'react' import { DepositModal } from '@taloon/nowpayments-components' interface RetryConfig { maxAttempts: number backoffMs: number retryableErrors: string[] } function RobustPaymentFlow() { const [showDeposit, setShowDeposit] = useState(false) const [retryCount, setRetryCount] = useState(0) const retryConfig: RetryConfig = { maxAttempts: 3, backoffMs: 1000, retryableErrors: ['network_error', 'timeout', 'temporary_unavailable'] } const withRetry = useCallback( async (operation: () => Promise, config: RetryConfig) => { let lastError: Error for (let attempt = 1; attempt <= config.maxAttempts; attempt++) { try { setRetryCount(attempt - 1) const result = await operation() setRetryCount(0) // Reset on success return result } catch (error) { lastError = error as Error const isRetryable = config.retryableErrors.some(errorType => lastError.message.toLowerCase().includes(errorType) ) if (!isRetryable || attempt === config.maxAttempts) { setRetryCount(0) throw lastError } // Exponential backoff const delay = config.backoffMs * Math.pow(2, attempt - 1) await new Promise(resolve => setTimeout(resolve, delay)) } } throw lastError! }, [] ) const handleDepositSubmit = useCallback( async (formData) => { return withRetry(async () => { const controller = new AbortController() const timeoutId = setTimeout(() => controller.abort(), 30000) // 30s timeout try { const response = await fetch('/api/deposits', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData), signal: controller.signal }) clearTimeout(timeoutId) if (!response.ok) { if (response.status >= 500) { throw new Error('temporary_unavailable') } throw new Error(`HTTP ${response.status}: ${response.statusText}`) } return response.json() } catch (error) { clearTimeout(timeoutId) if (error.name === 'AbortError') { throw new Error('timeout') } if (!navigator.onLine) { throw new Error('network_error') } throw error } }, retryConfig) }, [withRetry, retryConfig] ) return (
{retryCount > 0 && (
Retrying... (Attempt {retryCount + 1}/{retryConfig.maxAttempts})
)} setShowDeposit(false)} onSubmit={handleDepositSubmit} onSuccess={(result) => { console.log('Deposit successful after retries:', result) setShowDeposit(false) }} onError={(error) => { console.error('Deposit failed after all retries:', error) // Show user-friendly error message alert(`Payment failed: ${error.message}. Please try again later.`) }} />
) } ``` -------------------------------- ### WithdrawModal with Live Rates Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Shows how to dynamically update the USDT exchange rate for the `balanceToUsdtConverter` prop. It fetches rates periodically and uses `useEffect` for setup and cleanup of the interval. ```tsx function WithdrawWithLiveRates() { const [exchangeRate, setExchangeRate] = useState(0.95) // Fetch live exchange rates useEffect(() => { const fetchRate = async () => { try { const response = await fetch('/api/exchange-rates/usdt') const data = await response.json() setExchangeRate(data.rate) } catch (error) { console.error('Failed to fetch exchange rate:', error) } } fetchRate() const interval = setInterval(fetchRate, 30000) // Update every 30 seconds return () => clearInterval(interval) }, []) const convertToUsdt = async (amount: number) => { return amount * exchangeRate } return ( setIsOpen(false)} availableBalance={userBalance} balanceToUsdtConverter={convertToUsdt} onSubmit={handleSubmit} onSuccess={(result) => ({ transactionId: result.data.transactionId })} /> ) } ``` -------------------------------- ### Dynamic Currency Filtering with React Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/advanced-patterns.mdx Implement dynamic filtering of currencies based on user-defined criteria like minimum amount, preferred networks, and categories. This example uses React hooks and state management to provide a responsive and interactive filtering experience. ```tsx import { useState, useEffect } from 'react' import { DepositModal, useCurrencies } from '@taloon/nowpayments-components' interface CurrencyFilter { minAmount?: number maxAmount?: number networks?: string[] categories?: string[] } function SmartDepositModal() { const [showModal, setShowModal] = useState(false) const [filter, setFilter] = useState({ minAmount: 10, // Minimum $10 deposits networks: ['bitcoin', 'ethereum', 'tron'], // Preferred networks categories: ['stablecoin', 'defi'] // Preferred categories }) const { currencies, isLoading } = useCurrencies() // Filter currencies based on criteria const filteredCurrencies = currencies.filter(currency => { if (filter.minAmount && currency.min_amount > filter.minAmount) { return false } if (filter.networks && !filter.networks.includes(currency.network)) { return false } if (filter.categories) { const currencyCategory = getCurrencyCategory(currency.code) if (!filter.categories.includes(currencyCategory)) { return false } } return true }) const getCurrencyCategory = (code: string): string => { const stablecoins = ['usdt', 'usdc', 'dai', 'busd'] const defi = ['uni', 'aave', 'comp', 'mkr'] const gaming = ['axs', 'sand', 'mana', 'enj'] if (stablecoins.includes(code.toLowerCase())) return 'stablecoin' if (defi.includes(code.toLowerCase())) return 'defi' if (gaming.includes(code.toLowerCase())) return 'gaming' return 'other' } const handleDepositSubmit = async (formData) => { // Add filtering metadata const enrichedData = { ...formData, appliedFilters: filter, availableCurrencies: filteredCurrencies.length } const response = await fetch('/api/deposits/filtered', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(enrichedData) }) return response.json() } return (

Payment Preferences

setFilter(prev => ({ ...prev, minAmount: e.target.value ? Number(e.target.value) : undefined })) } />
{['bitcoin', 'ethereum', 'tron', 'bsc', 'polygon'].map(network => ( ))}

{isLoading ? 'Loading currencies...' : `${filteredCurrencies.length} currencies available`}

setShowModal(false)} onSubmit={handleDepositSubmit} onSuccess={() => setShowModal(false)} />
) } ``` -------------------------------- ### Environment Configuration for NOWPayments API Keys Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/examples/basic-integration.mdx Configures public and private API keys for NOWPayments using a .env.local file. NEXT_PUBLIC_NOWPAYMENTS_API_KEY is for public currency fetching, while NOWPAYMENTS_API_KEY is for private payment processing. ```bash # NOWPayments API Key (public - for currency fetching only) NEXT_PUBLIC_NOWPAYMENTS_API_KEY=your-public-api-key # NOWPayments API Key (private - for payment processing) NOWPAYMENTS_API_KEY=your-private-api-key ``` -------------------------------- ### Backend Withdrawal Request Data Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Example of the data structure expected by the backend for processing a withdrawal request. ```javascript { currency: "usdttrc20", amount: 100, destinationAddress: "TYour1WalletAddress2Here..." } ``` -------------------------------- ### Validate Withdrawal Amount Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Example of validating a withdrawal amount against available balance and minimum withdrawal limits before conversion. ```typescript const convertToUsdt = async (amount: number) => { if (amount > availableBalance) { throw new Error('Amount exceeds available balance') } if (amount < minimumWithdraw) { throw new Error(`Minimum withdrawal is ${minimumWithdraw}`) } return amount * exchangeRate } ``` -------------------------------- ### Initialize NowPaymentsProvider Source: https://context7.com/hanslove/nowpayments-components/llms.txt Wraps the application to provide the NOWPayments API key via React Context. Must be rendered as an ancestor of any modal or hook from this library. The apiKey is forwarded to NowPaymentsAPI for currency fetching. ```tsx import { NowPaymentsProvider } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' // Place at the root of your app or around the payment section only. // The apiKey is forwarded to NowPaymentsAPI for currency fetching. function App() { return ( ) } ``` -------------------------------- ### WithdrawFormData Currency Example Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Illustrates the possible values for the `currency` field within the `WithdrawFormData` interface. This determines the network for the withdrawal. ```tsx // The form data will contain the selected network const formData = { currency: 'usdttrc20', // or 'usdtmatic' amount: 100, destinationAddress: 'TXYZabc123...' } ``` -------------------------------- ### Troubleshooting: Styles Not Applied Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/styling-guide.mdx If components appear unstyled, ensure the base styles are imported correctly. Add `import '@taloon/nowpayments-components/styles'` to your entry point. ```tsx import '@taloon/nowpayments-components/styles' // ← Add this line ``` -------------------------------- ### Instantiate NowPaymentsAPI Client Source: https://context7.com/hanslove/nowpayments-components/llms.txt Instantiate the NowPaymentsAPI client with your API key for direct integration. Use this for custom solutions outside of the modal components. ```typescript import { NowPaymentsAPI } from '@taloon/nowpayments-components' const api = new NowPaymentsAPI('YOUR_NOWPAYMENTS_API_KEY') ``` -------------------------------- ### Configure NowPaymentsProvider Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/getting-started.mdx Wrap your application with NowPaymentsProvider to configure the API key globally. This is the simplest way to set up the library. ```tsx import { NowPaymentsProvider } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' function App() { return ( ) } ``` -------------------------------- ### Get Enabled Currencies for Merchant Source: https://context7.com/hanslove/nowpayments-components/llms.txt Retrieve a list of currency codes that are enabled for the current merchant account. Useful for displaying available payment options. ```typescript // 2. Get only the currencies enabled for this merchant account const enabledResult = await api.getEnabledCurrencies() if (enabledResult.success) { console.log('Enabled codes:', enabledResult.data?.selectedCurrencies) // e.g. ["btc", "eth", "usdttrc20", "sol"] } ``` -------------------------------- ### Vite Library Build Configuration Source: https://github.com/hanslove/nowpayments-components/blob/main/progress.md Configures Vite for building the library, specifying the entry point, library name, and formats. External dependencies like React are also listed. ```typescript build: { lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'NowpaymentsComponents', formats: ['es'], }, rollupOptions: { external: ['react', 'react-dom'], }, } ``` -------------------------------- ### Get Minimum Deposit Amount Source: https://context7.com/hanslove/nowpayments-components/llms.txt Fetch the minimum deposit amount for a specific currency, including its fiat equivalent. Handles potential errors during the API call. ```typescript // 3. Get minimum deposit amount for a specific currency const minResult = await api.getMinimumAmount('btc') if (minResult.success && minResult.data) { const { min_amount, fiat_equivalent } = minResult.data console.log(`Minimum BTC deposit: ${min_amount} BTC (~$${fiat_equivalent} USD)`) // min_amount: 0.0001, fiat_equivalent: "5.23" } else { console.error('getMinimumAmount failed:', minResult.error) } ``` -------------------------------- ### Basic Component Usage with Styles Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/styling-guide.mdx Integrate NOWPayments components by importing them and the necessary styles within your application's provider. ```tsx import { DepositModal, NowPaymentsProvider } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' function App() { return ( ) } ``` -------------------------------- ### Theme Integration for ContinueWithNowPayments Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/continue-with-nowpayments.mdx Shows how to integrate ContinueWithNowPayments styling with dark and light themes using CSS variables and attribute selectors. ```css /* Dark theme support */ [data-theme="dark"] .np-continue-btn--default { background: var(--np-surface-variant); color: var(--np-on-surface); } /* Light theme support */ [data-theme="light"] .np-continue-btn--default { background: #ffffff; color: #1a1a1a; border: 1px solid #e0e0e0; } ``` -------------------------------- ### Storybook Directory Structure Source: https://github.com/hanslove/nowpayments-components/blob/main/src/stories/README.md Overview of the file structure for Storybook stories within the project. ```bash src/stories/ ├── Introduction.mdx # Main introduction page ├── README.md # This file ├── caos-theme.css # Caos Engines inspired theme ├── CaosThemeDemo.stories.tsx # Theme demonstration stories ├── DepositModal/ │ ├── DepositModal.stories.tsx # All DepositModal variations │ └── mocks.ts # Deposit-specific mock data └── WithdrawModal/ ├── WithdrawModal.stories.tsx # All WithdrawModal variations └── mocks.ts # Withdraw-specific mock data ``` -------------------------------- ### Custom Styling for Withdrawal Component Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/withdraw-modal.mdx Provides CSS examples for customizing various elements of the withdrawal component, including network options, sliders, conversion displays, and payment status details. ```css /* Customize network selection */ .nowpayments-network-option { border: 1px solid var(--np-border); border-radius: var(--np-radius); } .nowpayments-network-option:has(input:checked) { border-color: var(--np-primary); background: var(--np-surface-variant); } /* Style the amount slider */ input[type="range"] { accent-color: var(--np-primary); } /* Customize USDT conversion display */ .conversion-display { background: var(--np-surface-variant); border-radius: var(--np-radius); padding: var(--np-spacing-md); } /* Customize withdrawal details step */ .nowpayments-payment-status { /* Status indicator styles */ } .nowpayments-payment-info--compact { /* Details display styles */ } ``` -------------------------------- ### Import Components and Styles Source: https://github.com/hanslove/nowpayments-components/blob/main/CSS_THEMING.md Import the necessary components and global styles for the NowPayments components library. ```tsx import { DepositModal } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' ``` -------------------------------- ### Direct Store Configuration with API Key Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/getting-started.mdx Configure the API key directly using the useNowPaymentsStore hook for more control. This is useful for setting the API key on app initialization. ```tsx import { useEffect } from 'react' import { useNowPaymentsStore } from '@taloon/nowpayments-components' import '@taloon/nowpayments-components/styles' function App() { const store = useNowPaymentsStore() // Configure on app initialization useEffect(() => { store.setApiKey('your-nowpayments-api-key') }, []) return } ``` -------------------------------- ### Use CSS Variables and Classes for Styling Source: https://github.com/hanslove/nowpayments-components/blob/main/CLAUDE.md Presents the recommended approach for styling components using CSS variables and BEM-based classes. This promotes consistency and maintainability. ```jsx // Correct
``` -------------------------------- ### WithdrawModal Integration Example Source: https://context7.com/hanslove/nowpayments-components/llms.txt Integrates the WithdrawModal component into a React application. It fetches user balance and exchange rates, and defines handlers for submission, success, and error states. Ensure API endpoints for balance and withdrawals are correctly configured. ```tsx import { useState, useEffect } from 'react' import { WithdrawModal, USDTNetwork, type WithdrawFormData, type WithdrawalDetails, } from '@taloon/nowpayments-components' function WithdrawButton({ userId }: { userId: string }) { const [open, setOpen] = useState(false) const [balance, setBalance] = useState(0) const [rate, setRate] = useState(1) // points-to-USDT exchange rate useEffect(() => { fetch(`/api/users/${userId}/balance`) .then(r => r.json()) .then(data => setBalance(data.balance)) // Refresh rate every 30 s const refreshRate = async () => { const r = await fetch('/api/exchange-rates/usdt') const d = await r.json() setRate(d.rate) } refreshRate() const interval = setInterval(refreshRate, 30_000) return () => clearInterval(interval) }, [userId]) const handleSubmit = async (formData: WithdrawFormData): Promise => { // formData: { currency: string, amount: number, destinationAddress: string } const response = await fetch('/api/withdrawals', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...formData, userId }), }) if (!response.ok) throw new Error(`HTTP ${response.status}`) return response.json() // Expected backend response (example): // { data: { id: "txn_def456", status: "pending", estimatedTime: "5-10 min" } } } const handleSuccess = (res: any): WithdrawalDetails => ({ transactionId: res.data?.id ?? res.withdrawalId ?? 'PENDING', }) const handleError = (error: Error): string => { if (error.message.includes('limit')) return 'Daily withdrawal limit reached.' if (error.message.includes('insufficient')) return 'Insufficient balance.' return 'Withdrawal failed. Please contact support.' } return ( <> setOpen(false)} availableBalance={balance} balanceToUsdtConverter={async (amount) => amount * rate} // Restrict to two networks; defaults are [USDTTRC20, USDTMATIC] supportedNetworks={[ USDTNetwork.USDTTRC20, USDTNetwork.USDTMATIC, USDTNetwork.USDTBSC, ]} showPoweredByNowpayments={false} onSubmit={handleSubmit} onSuccess={handleSuccess} onError={handleError} /> ) } ``` -------------------------------- ### Integrate ContinueWithNowPayments with Deposit Modal Source: https://github.com/hanslove/nowpayments-components/blob/main/docs/components/continue-with-nowpayments.mdx Shows how to use the ContinueWithNowPayments component to trigger a deposit modal, managing its visibility state. ```tsx import { useState } from 'react' import { ContinueWithNowPayments, DepositModal } from '@taloon/nowpayments-components' function PaymentFlow() { const [showDeposit, setShowDeposit] = useState(false) return (

Make a Deposit

Fund your account with cryptocurrency

setShowDeposit(true)} size="large" fullWidth /> setShowDeposit(false)} onSubmit={handleDepositSubmit} onSuccess={() => setShowDeposit(false)} />
) } ```