@xepeng/react-sdk
v0.0.4
Published
React SDK for XepengPay Hyperlane token bridging with MetaMask and Safe wallet integration
Maintainers
Readme
@xepeng/react-sdk
React SDK for integrating XepengPay cross-chain token transfers into web applications. Provides a complete solution with server-side fee management, multi-wallet support, and Safe multisig integration.
Features
- Dual-path payments: same-chain fast path (direct
XepengPayGateway.pay) when the user is already on the destination chain; HyperlanetransferRemotebridge path otherwise. The SDK auto-selects — callers do not choose. - Runtime-configurable chains: destination and sources are served by the worker's
/api/config; adding a new chain needs no SDK code change - Automatic network switching: detects and switches networks when wallet is on wrong chain
- Server-side fee management: Automatic tiered fee calculation via Xepeng Worker API
- Custom fee support: Override fees with validation against minimum requirements
- Order ID validation: Real-time validation to prevent duplicate transactions
- Multi-wallet support: MetaMask (web + mobile) and WalletConnect
- Safe wallet support: Gnosis Safe multisig proposal, signing, and execution
- Exchange rate handling: Automatic IDR to USD conversion
- Mobile-friendly: Full MetaMask Mobile and WalletConnect support
Installation
# From the monorepo root
pnpm install
# Or install standalone
pnpm add @xepeng/react-sdkQuick Start
import { XepengPayComponent } from '@xepeng/react-sdk';
function App() {
return (
<XepengPayComponent
transactionParams={{
orderId: 'ORDER123456',
transferAmount: 150000, // 150,000 IDR
exchangeRate: 15000, // USD/IDR rate
}}
workerApiUrl="http://localhost:3000"
apiKey="your_api_key_here"
onSuccess={(txHash) => console.log('Success!', txHash)}
onError={(err) => console.error('Error:', err.message)}
/>
);
}Fast path vs. bridge path
The SDK picks one of two paths at call time based on the user's connected chain:
| User's chain | Path taken | What the SDK calls |
| ---------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------- |
| The chain marked isDestinationChain: true in the served config | Fast path | USDT.approve(gateway) → XepengPayGateway.pay(token, amount, metadata) |
| Any other configured chain | Bridge path | USDT.approve(hypCol) → HypERC20Collateral.transferRemote(destDomain, vault, amount, metadata, hook) |
Both paths emit the same XepengPayTransfer event; the worker indexes it uniformly. The SDK reads the isDestinationChain and gatewayAddress fields off the config (see packages/worker/env.example → SDK_CONFIG for the shape). To route all users to the fast path in a given environment, mark exactly one chain as the destination.
Safe wallets currently support the bridge path only. If a Safe-enabled caller is on the destination chain,
prepareSafeProposalthrows with a descriptive error — fall back to an EOA for fast-path payments until Safe + fast-path is implemented.
Transaction Parameters
interface XepengPayTransactionParams {
orderId: string; // Unique order identifier (required)
transferAmount: number; // Amount in IDR
exchangeRate?: number; // Optional USD/IDR exchange rate
feeAmount?: number; // Optional custom fee in IDR (must be >= API fee)
}
interface XepengPayComponentProps {
transactionParams: XepengPayTransactionParams;
config?: XepengPayConfig; // Override chain/token configuration
clientConfig?: XepengPayClientConfig; // Client-provided chain/token configs
workerApiUrl?: string; // Xepeng Worker API URL
apiKey?: string; // Worker API authentication key
onSuccess?: (txHash: string) => void;
onError?: (error: Error) => void;
className?: string;
style?: React.CSSProperties;
walletConnectProjectId?: string;
enableWalletConnect?: boolean;
enableSafe?: boolean;
}Wallet Options
MetaMask (Default)
<XepengPayComponent transactionParams={transactionParams} onSuccess={onSuccess} onError={onError} />WalletConnect
<XepengPayComponent
transactionParams={transactionParams}
walletConnectProjectId="YOUR_PROJECT_ID"
enableWalletConnect={true}
onSuccess={onSuccess}
onError={onError}
/>Safe Multisig
<XepengPayComponent
transactionParams={transactionParams}
enableSafe={true}
workerApiUrl="http://localhost:3000"
onSuccess={onSuccess}
onError={onError}
/>Safe flow: Connect wallet -> Create/Join proposal -> Collect signatures -> Execute when threshold met.
Fee Management
Automatic (Default)
Fees are calculated server-side based on transfer amount tiers:
| Tier | Amount (IDR) | Rate | Minimum | | ---- | ------------ | ----- | ---------- | | 1 | 10K - 5M | 1% | 2,000 IDR | | 2 | 5M - 50M | 0.75% | 15,000 IDR | | 3 | 50M - 200M | 0.5% | 50,000 IDR |
Custom Fee
<XepengPayComponent
transactionParams={{
orderId: 'ORDER123456',
transferAmount: 150000,
exchangeRate: 15000,
feeAmount: 2000, // Must be >= API-calculated fee
}}
workerApiUrl="http://localhost:3000"
onSuccess={onSuccess}
onError={onError}
/>Client Configuration
Override default chain and token configurations:
import { XepengPayComponent, XepengPayClientConfig } from '@xepeng/react-sdk';
const clientConfig: XepengPayClientConfig = {
chains: [
{
chainId: '0x89',
name: 'Polygon (Custom RPC)',
rpcUrls: ['https://polygon-rpc.com/'],
nativeCurrency: { name: 'Matic', symbol: 'MATIC', decimals: 18 },
blockExplorerUrls: ['https://polygonscan.com/'],
},
],
chainTokenConfigs: [
{
chainId: '0x89',
chainName: 'Polygon (Custom RPC)',
tokens: [
{
symbol: 'USDT',
name: 'Tether USD',
address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
decimals: 6,
hypColAddress: '0x6316043b1EE191538A3903d95723506229B1e985',
},
],
hookAddress: '0x9B31d0eb6D852939Fe5A2BB8a66F3b5E6679A3a5',
destinationDomain: 137,
},
],
};
<XepengPayComponent
clientConfig={clientConfig}
transactionParams={transactionParams}
onSuccess={onSuccess}
onError={onError}
/>;Configuration Manager
import { globalConfigManager, XepengConfigManager } from '@xepeng/react-sdk';
// Update global config
globalConfigManager.updateClientConfigs(clientChains, clientChainTokenConfigs);
// Or create a standalone instance
const configManager = new XepengConfigManager(clientChains, clientChainTokenConfigs);Wallet Utilities
import {
getAvailableWalletTypes,
createDefaultWalletConnectConfig,
getRecommendedWalletType,
} from '@xepeng/react-sdk';
const availableWallets = getAvailableWalletTypes();
const recommended = getRecommendedWalletType();
const wcConfig = createDefaultWalletConnectConfig('YOUR_PROJECT_ID');Styling
Default styles can be customized via CSS classes:
.xepengpay-container.xepengpay-button.xepengpay-error.xepengpay-transaction-details
Supported Token Addresses
Arbitrum One
- USDC:
0xaf88d065e77c8cC2239327C5EDb3A432268e5831(HypCol:0x922D6956C99E12DFeB3224DEA977D0939758A1Fe) - USDT:
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
Polygon
- USDC:
0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174(HypCol:0x922D6956C99E12DFeB3224DEA977D0939758A1Fe) - USDT:
0xc2132D05D31c914a87C6611C10748AEb04B58e8F
Development
# From monorepo root
pnpm --filter @xepeng/react-sdk dev # Watch mode
pnpm --filter @xepeng/react-sdk build # Build
pnpm --filter @xepeng/react-sdk test # Run tests
pnpm --filter @xepeng/react-sdk lint # LintLicense
MIT
