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:

javascript
async 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:

javascript
function 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:

javascript
async 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

javascript
async 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

javascript
async 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

javascript
class 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

javascript
import { 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

javascript
import { 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

  1. Always check installation before attempting connection
  2. Handle errors gracefully - don't expose internal errors to users
  3. Verify addresses after connection to ensure expected format
  4. Monitor disconnection events to update UI accordingly
  5. Clear sensitive data when wallet disconnects

Address Validation

javascript
function 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

  1. Wallet not detected

    javascript
    if (!window.xrpl) { // Wait a bit for injection await new Promise(resolve => setTimeout(resolve, 100)); if (!window.xrpl) { // Still not available - wallet not installed } }
  2. Connection timeout

    javascript
    const connectWithTimeout = (timeout = 30000) => { return Promise.race([ window.xrpl.connect(), new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), timeout) ) ]); };
  3. Multiple connection attempts

    javascript
    let 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().