Download the App Download now →
SDK

React SDK

This is the official React SDK for the AhoraCrypto payment widget, allowing you to easily integrate cryptocurrency payments into your React applications, including those using Capacitor for mobile apps.

Installation

bash
"tok-key">npm install ahoracrypto-react-sdk

or

bash
"tok-key">yarn add ahoracrypto-react-sdk

Key Features

  • Optimized Performance: Improved initialization process eliminates double loading issues
  • Development Logging: Detailed logs only appear in development mode, not in production builds
  • Enhanced Iframe Attributes: Complete set of permissions for optimal integration
  • Responsive Themes: Automatic light/dark mode detection with manual overrides
  • Cross-Domain Communication: Reliable iframe messaging system
  • Auto Container ID: No need to provide a container ID when using the React component

Usage

The SDK provides two ways to integrate the AhoraCrypto widget:

  • React Component: Use the AhoraCryptoWidget component in your JSX/TSX.
  • Function API: Use the renderWebwidget function to render the widget programmatically (similar to the vanilla JavaScript SDK).

React Component Approach

jsx
import React, { useRef } from 'react';
import { AhoraCryptoWidget } from 'ahoracrypto-react-sdk';

function MyPaymentPage() {
  const controllerRef = useRef(null);

  return (
    <div className="payment-container">
      <h2>Complete Your Payment</h2>

      <div>
        <AhoraCryptoWidget
          config={{
            cryptoCurrency: 'BTC',
            fiatCurrency: 'EUR',
            borderWithShadow: true,
            theme: 'light'
          }}
          onReady={(controller) => {
            // Save controller reference to interact with the widget later
            controllerRef.current = controller;
            console.log('Widget is ready!');
          }}
        />
      </div>

      <div className="actions">
        <button onClick={() => controllerRef.current?.setWalletAddress('0x1234567890abcdef1234567890abcdef12345678')}>
          Set wallet address
        </button>
      </div>
    </div>
  );
}

Function API Approach

jsx
import React, { useEffect } from 'react';
import { renderWebwidget } from 'ahoracrypto-react-sdk';

function MyPaymentPage() {
  useEffect(() => {
    // Initialize widget
    const widget = renderWebwidget({
      containerId: 'widget-container', // Required for function API
      cryptoCurrency: 'ETH',
      fiatCurrency: 'USD',
      borderWithShadow: true
    });

    // Listen for widget ready event
    widget.onReady(() => {
      console.log('Widget is ready!');

      // You can interact with the widget using the controller
      // widget.setWalletAddress('0x1234...');
    });

    // Clean up on unmount (not strictly necessary)
    return () => {
      // Cleanup code if needed
    };
  }, []);

  return (
    <div className="payment-container">
      <h2>Complete Your Payment</h2>
      <div id="widget-container" style={{ maxWidth: '416px', margin: '0 auto' }}></div>
    </div>
  );
}

Capacitor Integration

The SDK works seamlessly with Capacitor for building mobile apps. Here's how to use it in a Capacitor-based project:

Setup in Capacitor

Install the SDK and Capacitor:

bash
"tok-key">npm install ahoracrypto-react-sdk @capacitor/core @capacitor/ios @capacitor/android

Initialize Capacitor (if not already done):

bash
"tok-key">npx cap init

Add platforms:

bash
"tok-key">npx cap add ios
"tok-key">npx cap add android

Example Usage in a Capacitor App

jsx
import React, { useEffect, useRef } from 'react';
import { AhoraCryptoWidget } from 'ahoracrypto-react-sdk';
import { Device } from '@capacitor/device';
import { App } from '@capacitor/app';

function CapacitorPaymentScreen() {
  const controllerRef = useRef(null);
  const [deviceTheme, setDeviceTheme] = useState('light');

  useEffect(() => {
    // Get device preferences for theming
    const getDevicePreferences = async () => {
      try {
        // Check if device is using dark mode
        const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
        setDeviceTheme(prefersDark ? 'dark' : 'light');
      } catch (error) {
        console.error('Error detecting theme:', error);
      }
    };

    getDevicePreferences();

    // Handle app state changes
    const handleAppStateChange = ({ isActive }) => {
      if (isActive && controllerRef.current) {
        // Refresh widget data when app comes back to foreground if needed
      }
    };

    App.addListener('appStateChange', handleAppStateChange);

    return () => {
      App.removeAllListeners();
    };
  }, []);

  return (
    <div className="capacitor-payment-container">
      <div>
        <AhoraCryptoWidget
          config={{
            cryptoCurrency: 'BTC',
            fiatCurrency: 'EUR',
            theme: deviceTheme,
            // Optimize for mobile screens
            iframeHeight: 550,
            borderRadius: 16
          }}
          onReady={(controller) => {
            controllerRef.current = controller;
            console.log('Widget ready in Capacitor app');
          }}
        />
      </div>
    </div>
  );
}

Building for iOS/Android

After integrating the widget into your React app, build and sync the project:

bash
"tok-key">npm run build
"tok-key">npx cap sync

Open the native projects:

bash
"tok-key">npx cap open ios
# or
"tok-key">npx cap open android

Configuration Options

The widget accepts the following configuration options:

OptionTypeDescription
containerIdstringRequired only for Function API. ID of the container element
languagestringOptional language code for the widget
cryptoCurrencystringCryptocurrency symbol to select by default
fiatCurrencystringFiat currency symbol to select by default
logoUrlstringCustom logo image URL
backgroundColorstringBackground color (HEX)
buttonColorstringButton color (HEX)
borderRadiusnumberBorder radius of components
borderWithShadowbooleanWhether to apply a styled border with shadow
theme'light' | 'dark'Force a specific theme
iframeWidthnumberCustom iframe width
iframeHeightnumberCustom iframe height
paymentIntentIdstringPayment intent ID
referralstringReferral identifier for traffic tracking

Controller Methods

The widget controller provides the following methods for interacting with the widget:

MethodDescription
setWalletAddress(address)Sets the wallet address
setPaymentIntentId(id)Sets the payment intent ID
sendSignedMessage(signature, address, messageHash?)Sends a signed message to the widget
requestMessageToSign()Requests a message for signing
connectWeb3Wallet(provider, address, chainId)Connects a Web3 wallet to the widget
setTheme(theme)Sets the widget theme ('light' or 'dark')
onReady(callback)Registers a callback for when the widget is ready
ready()Returns a promise that resolves when the widget is ready
isReady()Returns whether the widget is ready

Development and Debugging

Logging System

The SDK includes a smart logging system that only displays logs in development environments:

  • In development mode (NODE_ENV === 'development'), detailed logs appear to help with debugging
  • In production builds, logs are automatically suppressed to avoid cluttering the console

This helps developers debug during development while ensuring a clean console in production.

Performance Optimizations

Recent optimizations include:

  • Single Initialization: Widget now initializes only once, preventing duplication of events
  • Improved Loading: Enhanced initialization process with better handling of the "ready" state
  • No Message Queuing: Messages are only sent when the widget is ready, preventing potential timing issues
  • Memory Efficiency: Better state management to reduce memory usage and avoid leaks
  • Auto Container ID: When using the React component, a unique container ID is generated automatically

Troubleshooting

If you encounter issues with the widget:

  • Widget Not Displaying: Ensure the container has sufficient width and height
  • Communication Issues: Check the console for errors in development mode
  • Iframe Not Loading: Verify your internet connection and that the domain is accessible