For Developers
Connecting Wallet
description: Complete guide to connecting DropFi wallet to your DApp
Connecting Wallet
🚀 Quick Start
The simplest way to connect DropFi wallet to your DApp:
javascriptasync function connectWallet() { try { const address = await window.xrpl.connect(); console.log('Connected:', address); } catch (error) { console.error('Connection failed:', error); } }
🔍 Detection & Initialization
Detecting DropFi
Before attempting connection, check if DropFi is installed:
javascriptfunction isDropFiInstalled() { return window.xrpl && window.xrpl.isDropFi === true; } // Wait for page load window.addEventListener('load', () => { if (isDropFiInstalled()) { enableWalletFeatures(); } else { showInstallPrompt(); } });
Getting Initial State
Check if user is already connected:
javascriptasync function checkConnection() { if (!window.xrpl) return null; try { const state = await window.xrpl.initialize(); return { isConnected: !!state.selectedAddress, address: state.selectedAddress, network: state.network, accounts: state.connectedAccounts }; } catch (error) { console.error('Failed to get wallet state:', error); return null; } }
🔌 Connection Flow
Basic Connection
javascriptasync function connect() { try { // Request connection const address = await window.xrpl.connect(); // Connection successful console.log('Connected to address:', address); // Update UI updateUIForConnectedState(address); // Setup event listeners setupWalletEventListeners(); return address; } catch (error) { // Handle errors if (error.code === 4001) { // User rejected the request showMessage('Connection cancelled by user'); } else { // Other error showError('Failed to connect: ' + error.message); } throw error; } }
Connection with Options
javascriptasync function connectWithOptions() { try { // Optional: Pass connection data const connectionData = { // Future use: specific connection parameters appName: 'My DApp', appIcon: 'https://mydapp.com/icon.png' }; const address = await window.xrpl.connect(connectionData); return address; } catch (error) { handleConnectionError(error); } }
📡 Managing Connection State
Connection Manager Class
javascriptclass WalletConnectionManager { constructor() { this.address = null; this.network = null; this.isConnecting = false; this.listeners = new Map(); } async connect() { if (this.isConnecting) return; if (!window.xrpl) throw new Error('DropFi not installed'); this.isConnecting = true; try { // Check current state first const state = await window.xrpl.initialize(); if (state.selectedAddress) { // Already connected this.address = state.selectedAddress; this.network = state.network; this.setupEventListeners(); return this.address; } // Request new connection const address = await window.xrpl.connect(); this.address = address; this.setupEventListeners(); return address; } catch (error) { this.handleError(error); throw error; } finally { this.isConnecting = false; } } async disconnect() { if (!this.address) return; try { await window.xrpl.disconnect(this.address); this.cleanup(); } catch (error) { console.error('Disconnect error:', error); this.cleanup(); } } setupEventListeners() { // Address change const addressHandler = (address) => { this.address = address; this.emit('addressChanged', address); }; window.xrpl.on('xrpl_selectedAddress', addressHandler); this.listeners.set('xrpl_selectedAddress', addressHandler); // Network change const networkHandler = (network) => { this.network = network; this.emit('networkChanged', network); }; window.xrpl.on('xrpl_selectedNetwork', networkHandler); this.listeners.set('xrpl_selectedNetwork', networkHandler); // Disconnect const disconnectHandler = (address) => { this.cleanup(); this.emit('disconnected', address); }; window.xrpl.on('xrpl_disconnect', disconnectHandler); this.listeners.set('xrpl_disconnect', disconnectHandler); } cleanup() { // Remove all event listeners this.listeners.forEach((handler, event) => { window.xrpl.off(event, handler); }); this.listeners.clear(); this.address = null; this.network = null; } handleError(error) { const errorMessages = { 4001: 'User rejected the connection request', 4100: 'The requested account has not been authorized', 4200: 'The requested method is not supported', 4900: 'Wallet is disconnected', 5000: 'Internal wallet error' }; const message = errorMessages[error.code] || error.message; console.error('Wallet error:', message); this.emit('error', { code: error.code, message }); } // Event emitter methods on(event, callback) { // Implementation of event emitter } emit(event, data) { // Implementation of event emitter } }
🎨 UI Integration Examples
React Hook
javascriptimport { useState, useEffect, useCallback } from 'react'; function useDropFiWallet() { const [address, setAddress] = useState(null); const [network, setNetwork] = useState(null); const [isConnecting, setIsConnecting] = useState(false); const [error, setError] = useState(null); // Check initial connection useEffect(() => { const checkConnection = async () => { if (!window.xrpl) return; try { const state = await window.xrpl.initialize(); if (state.selectedAddress) { setAddress(state.selectedAddress); setNetwork(state.network); } } catch (err) { console.error('Failed to check connection:', err); } }; checkConnection(); }, []); // Setup event listeners useEffect(() => { if (!window.xrpl) return; const handleAddressChange = (newAddress) => { setAddress(newAddress); if (!newAddress) { setError({ code: 'DISCONNECTED', message: 'Wallet disconnected' }); } }; const handleNetworkChange = (newNetwork) => { setNetwork(newNetwork); }; window.xrpl.on('xrpl_selectedAddress', handleAddressChange); window.xrpl.on('xrpl_selectedNetwork', handleNetworkChange); return () => { window.xrpl.off('xrpl_selectedAddress', handleAddressChange); window.xrpl.off('xrpl_selectedNetwork', handleNetworkChange); }; }, []); const connect = useCallback(async () => { if (!window.xrpl) { setError({ code: 'NOT_INSTALLED', message: 'DropFi not installed' }); return; } setIsConnecting(true); setError(null); try { const addr = await window.xrpl.connect(); setAddress(addr); return addr; } catch (err) { setError(err); throw err; } finally { setIsConnecting(false); } }, []); const disconnect = useCallback(async () => { if (!window.xrpl || !address) return; try { await window.xrpl.disconnect(address); setAddress(null); } catch (err) { console.error('Disconnect error:', err); // Still clear local state setAddress(null); } }, [address]); return { address, network, isConnected: !!address, isConnecting, error, connect, disconnect }; } // Usage function WalletButton() { const { address, isConnected, isConnecting, connect, disconnect, error } = useDropFiWallet(); if (error?.code === 'NOT_INSTALLED') { return ( <button onClick={() => window.open('https://dropzero.io/download')}> Install DropFi </button> ); } if (isConnected) { return ( <button onClick={disconnect}> {address.slice(0, 6)}...{address.slice(-4)} </button> ); } return ( <button onClick={connect} disabled={isConnecting}> {isConnecting ? 'Connecting...' : 'Connect Wallet'} </button> ); }
Vue Composition API
javascriptimport { ref, computed, onMounted, onUnmounted } from 'vue'; export function useDropFiWallet() { const address = ref(null); const network = ref(null); const isConnecting = ref(false); const error = ref(null); const isConnected = computed(() => !!address.value); const isInstalled = computed(() => window.xrpl && window.xrpl.isDropFi); const checkConnection = async () => { if (!window.xrpl) return; try { const state = await window.xrpl.initialize(); address.value = state.selectedAddress; network.value = state.network; } catch (err) { console.error('Connection check failed:', err); } }; const connect = async () => { if (!isInstalled.value) { error.value = { code: 'NOT_INSTALLED', message: 'DropFi not installed' }; return; } isConnecting.value = true; error.value = null; try { const addr = await window.xrpl.connect(); address.value = addr; return addr; } catch (err) { error.value = err; throw err; } finally { isConnecting.value = false; } }; const disconnect = async () => { if (!address.value) return; try { await window.xrpl.disconnect(address.value); address.value = null; } catch (err) { console.error('Disconnect error:', err); address.value = null; } }; // Event handlers const handleAddressChange = (newAddress) => { address.value = newAddress; }; const handleNetworkChange = (newNetwork) => { network.value = newNetwork; }; onMounted(() => { checkConnection(); if (window.xrpl) { window.xrpl.on('xrpl_selectedAddress', handleAddressChange); window.xrpl.on('xrpl_selectedNetwork', handleNetworkChange); } }); onUnmounted(() => { if (window.xrpl) { window.xrpl.off('xrpl_selectedAddress', handleAddressChange); window.xrpl.off('xrpl_selectedNetwork', handleNetworkChange); } }); return { address, network, isConnected, isInstalled, isConnecting, error, connect, disconnect }; }
🔒 Security Considerations
Connection Best Practices
- Always check installation before attempting connection
- Handle errors gracefully - don't expose internal errors to users
- Verify addresses after connection to ensure expected format
- Monitor disconnection events to update UI accordingly
- Clear sensitive data when wallet disconnects
Address Validation
javascriptfunction isValidXRPLAddress(address) { // Basic XRPL address validation if (!address || typeof address !== 'string') return false; // XRPL addresses start with 'r' and are 25-34 characters const xrplAddressRegex = /^r[a-zA-Z0-9]{24,33}$/; return xrplAddressRegex.test(address); } // Use after connection const address = await window.xrpl.connect(); if (!isValidXRPLAddress(address)) { throw new Error('Invalid address received from wallet'); }
🛠️ Troubleshooting
Common Issues
Wallet not detected
javascriptif (!window.xrpl) { // Wait a bit for injection await new Promise(resolve => setTimeout(resolve, 100)); if (!window.xrpl) { // Still not available - wallet not installed } }
Connection timeout
javascriptconst connectWithTimeout = (timeout = 30000) => { return Promise.race([ window.xrpl.connect(), new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), timeout) ) ]); };
Multiple connection attempts
javascriptlet connectionPromise = null; async function ensureSingleConnection() { if (connectionPromise) return connectionPromise; connectionPromise = window.xrpl.connect(); try { const result = await connectionPromise; return result; } finally { connectionPromise = null; } }
💡 Pro Tip: Store connection state in localStorage to provide a smoother experience across page reloads, but always verify the connection is still active using
initialize()
.