Skip to content

zbdpay/ramp-react

Repository files navigation

@zbdpay/ramp-react

React wrapper for ZBD Ramp widget that enables Bitcoin Lightning Network payments in React applications.

TL;DR

npm install @zbdpay/ramp-react
import { ZBDRamp } from '@zbdpay/ramp-react';

<ZBDRamp
  sessionToken="your-session-token"
  onSuccess={(data) => console.log('Success:', data)}
  onError={(error) => console.error('Error:', error)}
/>

Features

  • React Optimized: Built specifically for React with hooks and components
  • TypeScript Support: Full type safety with comprehensive TypeScript definitions
  • Ref API: Access to underlying ramp instance methods via React refs
  • Hook Support: useZBDRamp hook for programmatic usage
  • Session Token Based: Uses secure session tokens for authentication

Installation

npm install @zbdpay/ramp-react
# or
yarn add @zbdpay/ramp-react
# or
pnpm add @zbdpay/ramp-react

Quick Start

1. Create Session Token

First, create a session token using the built-in initRampSession function:

import { initRampSession, QuoteCurrencyEnum, BaseCurrencyEnum } from '@zbdpay/ramp-react';

// Using email authentication
const response = await initRampSession({
  apikey: 'your-zbd-api-key',
  email: '[email protected]',
  destination: 'lightning-address-or-username',
  quote_currency: QuoteCurrencyEnum.USD,
  base_currency: BaseCurrencyEnum.BTC,
  webhook_url: 'https://your-webhook-url.com',
});

// Or using access token authentication
const response = await initRampSession({
  apikey: 'your-zbd-api-key',
  access_token: 'user-access-token',
  destination: 'lightning-address-or-username',
  quote_currency: QuoteCurrencyEnum.USD,
  base_currency: BaseCurrencyEnum.BTC,
  webhook_url: 'https://your-webhook-url.com',
});

const sessionToken = response.data.session_token;

2. Use ZBDRamp Component

import { ZBDRamp } from '@zbdpay/ramp-react';

function App() {
  const handleSuccess = (data) => {
    console.log('Payment successful:', data);
  };

  const handleError = (error) => {
    console.error('Payment error:', error);
  };

  return (
    <ZBDRamp
      sessionToken="your-session-token"
      onSuccess={handleSuccess}
      onError={handleError}
      style={{ width: '100%', height: '600px' }}
    />
  );
}

Complete Example

Check out the example app for a full implementation with session token creation:

cd example
npm install
npm run dev

The example includes:

  • Session token creation form
  • Complete ZBD Ramp integration
  • Error handling and callbacks

API Reference

ZBDRamp Component

React component that renders the ZBD Ramp widget.

Props

interface ZBDRampProps {
  sessionToken: string;                      // Required: Session token from ZBD API
  width?: string | number;                   // Default: '100%'
  height?: string | number;                  // Default: '600px'
  className?: string;                        // CSS class for container
  style?: React.CSSProperties;              // Inline styles for container
  
  // Callbacks
  onSuccess?: (data: any) => void;           // Payment successful
  onError?: (error: RampError) => void;      // Error occurred
  onStepChange?: (step: string) => void;     // User navigated to different step
  onLog?: (log: RampLog) => void;           // Debug/info logging
  onReady?: () => void;                      // Widget fully loaded
  onClose?: () => void;                      // User closed widget
}

Ref API

interface ZBDRampRef {
  mount: (container?: HTMLElement | string) => void;
  unmount: () => void;
  destroy: () => void;
}

useZBDRamp Hook

Hook for creating and managing ZBD Ramp instances programmatically.

const { createInstance, destroyInstance, instance } = useZBDRamp(options);

Examples

Basic Component

import React from 'react';
import { ZBDRamp } from '@zbdpay/ramp-react';

function PaymentWidget({ sessionToken }) {
  const handleSuccess = (data: any) => {
    console.log('Payment successful:', data);
    // Handle successful payment
  };

  const handleError = (error: any) => {
    console.error('Payment error:', error);
    // Handle error
  };

  return (
    <div className="payment-container">
      <h1>Make a Payment</h1>
      <ZBDRamp
        sessionToken={sessionToken}
        onSuccess={handleSuccess}
        onError={handleError}
        style={{ 
          width: '100%', 
          height: '600px',
          border: '1px solid #ddd', 
          borderRadius: '8px' 
        }}
      />
    </div>
  );
}

With Ref for Control

import React, { useRef } from 'react';
import { ZBDRamp, type ZBDRampRef } from '@zbdpay/ramp-react';

function ControlledPayment({ sessionToken }) {
  const rampRef = useRef<ZBDRampRef>(null);

  const closeWidget = () => {
    rampRef.current?.unmount();
  };

  return (
    <div>
      <button onClick={closeWidget}>Close Widget</button>
      
      <ZBDRamp
        ref={rampRef}
        sessionToken={sessionToken}
        onSuccess={(data) => console.log('Success:', data)}
        onError={(error) => console.error('Error:', error)}
      />
    </div>
  );
}

Using the Hook

import React, { useState } from 'react';
import { useZBDRamp } from '@zbdpay/ramp-react';

function HookExample({ sessionToken }) {
  const [isOpen, setIsOpen] = useState(false);
  
  const { createInstance, destroyInstance } = useZBDRamp({
    sessionToken,
    container: '#ramp-container',
    onSuccess: (data) => {
      console.log('Payment successful:', data);
      setIsOpen(false);
    },
    onClose: () => {
      setIsOpen(false);
    },
  });

  const openRamp = () => {
    setIsOpen(true);
    createInstance();
  };

  const closeRamp = () => {
    setIsOpen(false);
    destroyInstance();
  };

  return (
    <div>
      <button onClick={openRamp}>Open Payment</button>
      {isOpen && (
        <div>
          <button onClick={closeRamp}>Close</button>
          <div id="ramp-container" style={{ width: '100%', height: '600px' }} />
        </div>
      )}
    </div>
  );
}

Error Handling

import React, { useState } from 'react';
import { ZBDRamp, type RampError } from '@zbdpay/ramp-react';

function PaymentWithErrorHandling({ sessionToken }) {
  const [error, setError] = useState<string | null>(null);

  const handleError = (error: RampError) => {
    switch (error.code) {
      case 'INVALID_CONFIG':
        setError('Configuration error. Please check your settings.');
        break;
      case 'NETWORK_ERROR':
        setError('Network error. Please check your connection.');
        break;
      case 'PAYMENT_FAILED':
        setError('Payment failed. Please try again.');
        break;
      default:
        setError('An unexpected error occurred.');
    }
  };

  const clearError = () => setError(null);

  return (
    <div>
      {error && (
        <div style={{ color: 'red', marginBottom: '10px' }}>
          Error: {error}
          <button onClick={clearError}>×</button>
        </div>
      )}
      
      <ZBDRamp
        sessionToken={sessionToken}
        onSuccess={() => setError(null)}
        onError={handleError}
      />
    </div>
  );
}

Session Token Creation Example

import React, { useState } from 'react';
import { ZBDRamp, initRampSession, QuoteCurrencyEnum, BaseCurrencyEnum } from '@zbdpay/ramp-react';

function SessionTokenExample() {
  const [sessionToken, setSessionToken] = useState('');
  const [isLoading, setIsLoading] = useState(false);

  const createSession = async () => {
    setIsLoading(true);
    try {
      // Using email authentication
      const response = await initRampSession({
        apikey: 'your-zbd-api-key',
        email: '[email protected]',
        destination: 'lightning-address',
        quote_currency: QuoteCurrencyEnum.USD,
        base_currency: BaseCurrencyEnum.BTC,
        webhook_url: 'https://your-webhook.com',
      });

      if (response.success) {
        setSessionToken(response.data.session_token);
      } else {
        console.error('Failed to create session:', response.error);
      }
    } catch (error) {
      console.error('Error creating session:', error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div>
      {!sessionToken ? (
        <button onClick={createSession} disabled={isLoading}>
          {isLoading ? 'Creating Session...' : 'Create Session'}
        </button>
      ) : (
        <ZBDRamp
          sessionToken={sessionToken}
          onSuccess={(data) => console.log('Success:', data)}
        />
      )}
    </div>
  );
}

Access Token Refresh Example

import React, { useState } from 'react';
import { refreshAccessToken } from '@zbdpay/ramp-react';

function TokenRefreshExample() {
  const [isRefreshing, setIsRefreshing] = useState(false);
  
  const handleRefreshToken = async () => {
    setIsRefreshing(true);
    try {
      const response = await refreshAccessToken({
        apikey: 'your-zbd-api-key',
        access_token_id: 'user-access-token-id',
        refresh_token: 'user-refresh-token',
      });

      if (response.success) {
        const newAccessToken = response.data.access_token;
        const newRefreshToken = response.data.refresh_token;
        // Store the new tokens securely
      } else {
        console.error('Failed to refresh token:', response.error);
      }
    } catch (error) {
      console.error('Token refresh error:', error);
    } finally {
      setIsRefreshing(false);
    }
  };

  return (
    <button onClick={handleRefreshToken} disabled={isRefreshing}>
      {isRefreshing ? 'Refreshing...' : 'Refresh Access Token'}
    </button>
  );
}

TypeScript Support

The package includes comprehensive TypeScript definitions:

import type {
  ZBDRampProps,
  ZBDRampRef,
  RampConfig,
  RampCallbacks,
  RampOptions,
  RampError,
  RampLog,
  RampInstance,
  PostMessageData,

  InitRampSessionConfig,
  InitRampSessionData,
  InitRampSessionResponse,
  RefreshAccessTokenConfig,
  RefreshAccessTokenData,
  RefreshAccessTokenResponse,
  QuoteCurrencyEnum,
  BaseCurrencyEnum,
} from '@zbdpay/ramp-react';

Related Packages

License

MIT License - see the LICENSE file for details.

Support

For support, email [email protected] or create an issue on GitHub.

About

React wrapper for ZBD Ramp widget

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published