UNPKG

x0-react-sdk

Version:

React SDK for X0Pay Hyperlane token bridging with MetaMask and Safe wallet integration

497 lines (393 loc) 15.8 kB
# X0Pay React SDK A React SDK for integrating X0Pay functionality into web applications. This SDK provides a complete solution for handling cross-chain token transfers with server-side fee management. ## Features - **Cross-chain transfers**: Support for multiple blockchain networks - **Server-side fee management**: Automatic fee calculation based on transfer amount - **Custom fee support**: Override fees with validation against minimum requirements - **Order ID validation**: Real-time validation with X0-worker API - **Multi-wallet support**: MetaMask and WalletConnect integration - **Safe wallet support**: Gnosis Safe multisig wallet integration - **Exchange rate handling**: Automatic IDR to USD conversion - **Progress tracking**: Step-by-step transaction flow - **Error handling**: Comprehensive error management ## Installation ```bash npm install x0-react-sdk ``` ## Usage ### Basic Usage ```tsx import React from 'react'; import { X0PayComponent } from 'x0-react-sdk'; function App() { const transactionParams = { orderId: 'ORDER123456', // Required: Order ID for validation transferAmount: 150000, // 150,000 IDR exchangeRate: 15000, // Optional: USD/IDR exchange rate }; return ( <X0PayComponent transactionParams={transactionParams} workerApiUrl="http://localhost:3000" // X0-worker API URL for fee calculation and order validation onSuccess={(txHash) => console.log('Success!', txHash)} onError={(err) => console.error('Error:', err.message)} /> ); } ``` ## Order ID Validation The SDK includes real-time order ID validation to prevent duplicate transactions. Order IDs are validated against the X0-worker API before allowing transactions to proceed. ### Features - **Real-time validation**: Order IDs are validated as soon as they're entered - **Duplicate prevention**: Prevents transactions with existing order IDs - **Visual feedback**: Clear status indicators for order ID validation - **Error handling**: Comprehensive error messages for validation failures ### Usage ```tsx const transactionParams = { orderId: 'ORDER123456', // Required: Unique order identifier transferAmount: 150000, // 150,000 IDR exchangeRate: 15000, // Optional: USD/IDR exchange rate }; <X0PayComponent transactionParams={transactionParams} workerApiUrl="http://localhost:3000" // Required for order validation onSuccess={onSuccess} onError={onError} /> ``` ### Validation States - **Validating**: Order ID is being checked - **Available**: Order ID is available for use (green indicator) - **Exists**: Order ID already exists (red indicator, transaction blocked) - **Error**: Validation failed (red indicator with error message) ## Fee Management The SDK supports both automatic server-side fee calculation and custom fee amounts with validation: ### Automatic Fee Calculation (Default) The SDK uses server-side fee calculation with automatic tiering based on transfer amount: #### Fee Tiers - **Tier 1**: 10,000 - 4,999,999 IDR → 1% fee, minimum 2,000 IDR - **Tier 2**: 5,000,000 - 49,999,999 IDR → 0.75% fee, minimum 15,000 IDR - **Tier 3**: 50,000,000 - 200,000,000 IDR → 0.5% fee, minimum 50,000 IDR #### Fee Calculation - Fees are always calculated as **outer fees** (added to transfer amount) - Total amount = Transfer Amount + Calculated Fee - Fee calculation is handled automatically by the X0-worker API **Example:** - Transfer Amount: 150,000 IDR - Calculated Fee: 1,500 IDR (1% of 150,000 IDR) - Total Amount: 151,500 IDR ### Custom Fee Amount (New Feature) You can now provide a custom fee amount that will be validated against the API-calculated fee: ```tsx <X0PayComponent transactionParams={{ orderId: 'ORDER123456', transferAmount: 150000, // 150,000 IDR exchangeRate: 15000, feeAmount: 2000 // Custom fee amount in IDR (must be >= API fee) }} workerApiUrl="http://localhost:3000" onSuccess={onSuccess} onError={onError} /> ``` #### Custom Fee Features - **Validation**: Custom fee must be greater than or equal to the API-calculated fee - **Flexibility**: Allows for higher fees when needed (e.g., priority transactions) - **Safety**: Prevents underpayment by validating against minimum required fee - **Transparency**: Shows both custom fee and API fee for comparison #### Fee Validation Process 1. **API Fee Calculation**: SDK fetches the minimum required fee from X0-worker API 2. **Custom Fee Validation**: Compares your custom fee with the API fee 3. **Transaction Blocking**: If custom fee is too low, transaction buttons are disabled 4. **Clear Feedback**: Shows validation status with detailed error messages #### Example with Custom Fee ```tsx // This will work if API fee is 1,500 IDR or less <X0PayComponent transactionParams={{ orderId: 'ORDER123456', transferAmount: 150000, exchangeRate: 15000, feeAmount: 2000 // 2,000 IDR custom fee }} workerApiUrl="http://localhost:3000" onSuccess={onSuccess} onError={onError} /> // This will be blocked if API fee is higher than 1,000 IDR <X0PayComponent transactionParams={{ orderId: 'ORDER123456', transferAmount: 150000, exchangeRate: 15000, feeAmount: 1000 // 1,000 IDR custom fee (may be too low) }} workerApiUrl="http://localhost:3000" onSuccess={onSuccess} onError={onError} /> ``` #### Fee Display When using custom fees, the UI shows: - **Custom Fee**: Your custom fee amount in IDR and USD - **API Fee**: The minimum required fee from the API - **Validation Status**: ✓ Passed or ⚠️ Failed with error message - **Total Amount**: Transfer amount + your custom fee ## Transaction Parameters ```typescript interface X0PayTransactionParams { orderId: string; // Order identifier (required) - used for validation and tracking transferAmount: number; // Amount in IDR exchangeRate?: number; // Optional exchange rate (USD/IDR) feeAmount?: number; // Optional fee amount in IDR, API fee will be used for validation } interface X0PayComponentProps { config?: X0PayConfig; // Optional - if not provided, uses built-in chain/token configurations clientConfig?: X0PayClientConfig; // Optional - client-provided chain and token configurations transactionParams: X0PayTransactionParams; onSuccess?: (txHash: string) => void; onError?: (error: Error) => void; className?: string; style?: React.CSSProperties; walletConnectProjectId?: string; // WalletConnect project ID for mobile support enableWalletConnect?: boolean; // Enable WalletConnect mobile support enableSafe?: boolean; // Enable Safe wallet support workerApiUrl?: string; // X0-worker API URL for fee calculation } ``` ### Order ID Requirements - **Required**: Every transaction must have a unique order ID - **Validation**: Order IDs are validated against the X0-worker API - **Uniqueness**: Order IDs must not have been used in previous transactions - **Format**: Order IDs can be any string format (alphanumeric, UUID, etc.) ## Configuration The SDK supports both default configurations and client-provided configurations. Client configurations can override or extend the default configurations. ### Default Configuration The SDK comes with pre-configured chains and tokens. If no custom configuration is provided, the SDK will use these defaults. ### Client Configuration You can provide custom chain and token configurations that override or extend the defaults: ```tsx import { X0PayComponent, X0PayClientConfig } from 'x0-react-sdk'; const clientConfig: X0PayClientConfig = { chains: [ // Override existing chain { chainId: '0x89', // Polygon name: 'Polygon (Custom RPC)', rpcUrls: ['https://polygon-rpc.com/', 'https://rpc-mainnet.maticvigil.com/'], nativeCurrency: { name: 'Matic', symbol: 'MATIC', decimals: 18 }, blockExplorerUrls: ['https://polygonscan.com/'], }, // Add new chain { chainId: '0x1', // Ethereum mainnet name: 'Ethereum', rpcUrls: ['https://mainnet.infura.io/v3/YOUR-PROJECT-ID'], nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, blockExplorerUrls: ['https://etherscan.io/'], }, ], chainTokenConfigs: [ { chainId: '0x89', // Polygon chainName: 'Polygon (Custom RPC)', tokens: [ { symbol: 'USDT', name: 'Tether USD (Custom)', address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', decimals: 6, hypColAddress: '0x6316043b1EE191538A3903d95723506229B1e985', }, // Add new token { symbol: 'USDC', name: 'USD Coin', address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', decimals: 6, hypColAddress: '0x1234567890123456789012345678901234567890', }, ], hookAddress: '0x9B31d0eb6D852939Fe5A2BB8a66F3b5E6679A3a5', destinationDomain: 137, }, ], }; <X0PayComponent clientConfig={clientConfig} transactionParams={transactionParams} onSuccess={onSuccess} onError={onError} /> ``` ### Legacy Configuration (Still Supported) You can still provide custom configuration for specific transactions: ```tsx const config = { erc20TokenAddress: '0x...', hypColAddress: '0x...', recipient: '0x...', hookAddress: '0x...', }; <X0PayComponent config={config} transactionParams={transactionParams} onSuccess={onSuccess} onError={onError} /> ``` ### Configuration Manager For advanced usage, you can use the configuration manager directly: ```tsx import { globalConfigManager, X0ConfigManager } from 'x0-react-sdk'; // Update global configuration globalConfigManager.updateClientConfigs(clientChains, clientChainTokenConfigs); // Or create a new instance const configManager = new X0ConfigManager(clientChains, clientChainTokenConfigs); const chains = configManager.getChains(); const configs = configManager.getChainTokenConfigs(); ``` ### Recipient Address The recipient address is automatically retrieved from the hook contract's `vaultAddress()` function and converted to bytes32 format for Hyperlane message compatibility. This ensures that the recipient is always up-to-date and matches the vault address configured in the hook contract. - **Automatic Retrieval**: The SDK automatically calls the hook contract to get the current vault address - **Bytes Conversion**: The address is automatically converted to bytes32 format using `ethers.utils.hexZeroPad()` - **No Hardcoding**: No need to hardcode recipient addresses in configurations - **Dynamic Updates**: If the vault address changes in the hook contract, the SDK will automatically use the new address The recipient retrieval happens when: 1. A wallet is connected 2. The hook address is available in the configuration 3. The provider is ready to make contract calls **Note**: The recipient is stored in bytes32 format (e.g., `0x00000000000000000000000076ad6ab8e9d4b10b27d949a414e9aa18c665ef9f`) to ensure compatibility with Hyperlane message format. ## Wallet Options The SDK supports multiple wallet types with an intuitive UI for wallet selection. ### Basic Usage (Auto-detect) ```tsx <X0PayComponent transactionParams={transactionParams} onSuccess={onSuccess} onError={onError} /> ``` ### Enable WalletConnect with Project ID ```tsx <X0PayComponent transactionParams={transactionParams} onSuccess={onSuccess} onError={onError} walletConnectProjectId="YOUR_PROJECT_ID" enableWalletConnect={true} /> ``` ### Wallet Selection Features When `enableWalletConnect` is true, users can choose from: - **Auto**: Automatically selects the best wallet for the platform - **MetaMask Web Extension**: For desktop MetaMask users - **Mobile Wallet (WalletConnect)**: For mobile wallet users The SDK intelligently: - Shows only available wallet options - Handles chain switching for MetaMask - Provides QR codes for mobile wallets - Automatically detects the best wallet for the platform ## Safe Wallet Support The SDK includes comprehensive support for Gnosis Safe multisig wallets: ### Enable Safe Support ```tsx <X0PayComponent transactionParams={transactionParams} enableSafe={true} workerApiUrl="http://localhost:3000" onSuccess={onSuccess} onError={onError} /> ``` ### Safe Flow Features When Safe support is enabled, users can choose between: - **EOA (Externally Owned Account)**: Standard MetaMask/WalletConnect flow - **Safe (Gnosis Safe)**: Multisig wallet flow ### Safe Transaction Flow 1. **Connect Wallet**: Connect to Safe using MetaMask or WalletConnect 2. **Create/Join Proposal**: - **Create**: Create a new transaction proposal and sign it - **Join**: Join an existing proposal by signing it 3. **Execute Transaction**: Execute the transaction once enough signatures are collected ### Safe Proposal Management - **Proposal Creation**: Create transaction proposals with all necessary parameters - **Signature Collection**: Collect signatures from multiple Safe owners - **Threshold Validation**: Ensure minimum required signatures are collected - **Proposal Sharing**: Share proposal JSON with other Safe owners - **Transaction Execution**: Execute the transaction when threshold is met ### Safe UI Features - **Account Type Selection**: Choose between EOA and Safe flows - **Safe Address Input**: Enter the Safe address for proposal creation - **Proposal JSON**: Paste and validate existing proposals - **Signature Status**: Track collected signatures vs. required threshold - **Proposal Details**: Display human-readable transaction details - **Copy to Clipboard**: Easy sharing of proposal JSON ## Supported Networks The SDK supports multiple blockchain networks including: - Polygon - Mumbai (Polygon Testnet) - Arbitrum - Optimism - Base - And more... ## Exchange Rate The SDK automatically fetches the current USD/IDR exchange rate from a reliable API. You can also provide a custom exchange rate in the transaction parameters. ## Error Handling The SDK provides comprehensive error handling for: - Network connection issues - Insufficient balance - Transaction failures - Exchange rate errors - Fee calculation errors - Wallet connection problems ## Wallet Utilities The SDK provides utility functions for wallet management: ```tsx import { getAvailableWalletTypes, createDefaultWalletConnectConfig, getRecommendedWalletType } from 'x0-react-sdk'; // Get available wallet types const availableWallets = getAvailableWalletTypes(); // ['metamask', 'walletconnect'] // Get recommended wallet type for current platform const recommendedWallet = getRecommendedWalletType(); // 'metamask' or 'walletconnect' // Create default WalletConnect configuration const walletConnectConfig = createDefaultWalletConnectConfig('YOUR_PROJECT_ID'); ``` ## Styling The SDK includes default styling that can be customized using CSS classes: - `.x0pay-container` - `.x0pay-button` - `.x0pay-error` - `.x0pay-transaction-details` ## Development To run the SDK in development mode: ```bash cd X0-sdk npm install npm run dev ``` ## Testing The test app demonstrates the new fee calculation functionality: ```bash cd test-app npm install npm start ``` ## License MIT License ### Supported Token Addresses #### Arbitrum One - **USDC**: `0xaf88d065e77c8cC2239327C5EDb3A432268e5831` - Hyperlane Collateral: `0x922D6956C99E12DFeB3224DEA977D0939758A1Fe` - **USDT**: `0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` - Hyperlane Collateral: `0x1234567890123456789012345678901234567890` #### Polygon - **USDC**: `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` - Hyperlane Collateral: `0x922D6956C99E12DFeB3224DEA977D0939758A1Fe` - **USDT**: `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` - Hyperlane Collateral: `0xabcdef1234567890abcdef1234567890abcdef12`