Blockchain8 min read

Designing Web3 UX: Wallets, Transaction Feedback, Gasless Flows

Best practices for creating user-friendly Web3 applications that hide complexity while maintaining transparency.

Web3 UX design best practices

The Web3 UX Challenge

Web3 applications face a unique challenge: they must handle complex blockchain interactions while providing familiar, intuitive user experiences. Users shouldn't need to understand gas fees, private keys, or transaction confirmation times to use your dApp effectively.

Common Web3 UX Problems

  • • 67% of users abandon dApps due to confusing wallet connection
  • • Transaction failures with no clear explanation
  • • Unclear loading states during blockchain confirmations
  • • Overwhelming technical jargon and error messages
  • • Inconsistent behavior across different wallets

1. Wallet Connection: The First Impression

Progressive Wallet Discovery

Don't overwhelm users with every possible wallet option. Use a progressive disclosure approach that prioritizes the most popular wallets while still supporting others.

// Progressive wallet connection UI
const WalletConnector = () => {
  const [showAllWallets, setShowAllWallets] = useState(false);
  
  const popularWallets = ['MetaMask', 'WalletConnect', 'Coinbase Wallet'];
  const otherWallets = ['Rainbow', 'Trust Wallet', 'Phantom'];

  return (
    <div className="wallet-connector">
      <h3>Connect Your Wallet</h3>
      
      {/* Popular wallets always visible */}
      {popularWallets.map(wallet => (
        <WalletOption 
          key={wallet} 
          name={wallet} 
          onConnect={() => connectWallet(wallet)}
          isInstalled={checkWalletInstalled(wallet)}
        />
      ))}
      
      {/* Progressive disclosure for other wallets */}
      {showAllWallets && (
        <div className="other-wallets">
          {otherWallets.map(wallet => (
            <WalletOption key={wallet} name={wallet} />
          ))}
        </div>
      )}
      
      <button 
        onClick={() => setShowAllWallets(!showAllWallets)}
        className="show-more-wallets"
      >
        {showAllWallets ? 'Show Less' : 'More Wallets'}
      </button>
    </div>
  );
};

Onboarding for New Users

Wallet Setup Flow

1
Detect Wallet Status

Check if user has a wallet installed

2
Guided Installation

Provide clear installation instructions with screenshots

3
Connection Tutorial

Show users what to expect during wallet connection

2. Transaction Feedback: Keeping Users Informed

Multi-Stage Loading States

Blockchain transactions go through multiple stages. Each stage should have clear visual feedback with estimated time remaining.

// Transaction status component
const TransactionProgress = ({ txHash, status }) => {
  const stages = [
    { 
      key: 'signing', 
      label: 'Sign Transaction', 
      description: 'Approve in your wallet' 
    },
    { 
      key: 'pending', 
      label: 'Processing', 
      description: 'Transaction submitted to blockchain' 
    },
    { 
      key: 'confirming', 
      label: 'Confirming', 
      description: 'Waiting for network confirmations' 
    },
    { 
      key: 'success', 
      label: 'Complete', 
      description: 'Transaction successful' 
    }
  ];

  const currentStageIndex = stages.findIndex(s => s.key === status);

  return (
    <div className="transaction-progress">
      <div className="progress-bar">
        <div 
          className="progress-fill"
          style={{ width: `${(currentStageIndex + 1) / stages.length * 100}%` }}
        />
      </div>
      
      {stages.map((stage, index) => (
        <div 
          key={stage.key}
          className={`stage ${index <= currentStageIndex ? 'active' : ''}`}
        >
          <div className="stage-icon">
            {index < currentStageIndex ? '✓' : 
             index === currentStageIndex ? '⟳' : '○'}
          </div>
          <div className="stage-content">
            <h4>{stage.label}</h4>
            <p>{stage.description}</p>
          </div>
        </div>
      ))}
      
      {txHash && (
        <a 
          href={`https://etherscan.io/tx/${txHash}`}
          target="_blank"
          rel="noopener noreferrer"
          className="view-transaction"
        >
          View on Etherscan →
        </a>
      )}
    </div>
  );
};

Error Handling with Action Steps

❌ Bad Error Message

"Error: execution reverted: ERC20: transfer amount exceeds balance"

✅ Good Error Message

Insufficient Balance

You don't have enough tokens to complete this transaction.

3. Gas Fee UX: Making the Complex Simple

Gas Fee Estimation & Options

// Gas fee selector component
const GasFeeSelector = ({ onGasChange }) => {
  const [selectedSpeed, setSelectedSpeed] = useState('standard');
  
  const gasOptions = {
    slow: { 
      price: '$2.50', 
      time: '5-10 min', 
      gwei: '25',
      description: 'Lowest cost, slower confirmation'
    },
    standard: { 
      price: '$5.00', 
      time: '2-5 min', 
      gwei: '50',
      description: 'Balanced speed and cost'
    },
    fast: { 
      price: '$8.50', 
      time: '< 2 min', 
      gwei: '75',
      description: 'Fastest confirmation'
    }
  };

  return (
    <div className="gas-fee-selector">
      <h4>Transaction Speed</h4>
      
      {Object.entries(gasOptions).map(([speed, details]) => (
        <label key={speed} className="gas-option">
          <input
            type="radio"
            name="gasSpeed"
            value={speed}
            checked={selectedSpeed === speed}
            onChange={(e) => {
              setSelectedSpeed(e.target.value);
              onGasChange(details.gwei);
            }}
          />
          <div className="option-content">
            <div className="option-header">
              <span className="speed-name">
                {speed.charAt(0).toUpperCase() + speed.slice(1)}
              </span>
              <span className="price">{details.price}</span>
            </div>
            <div className="option-details">
              <span className="time">~{details.time}</span>
              <span className="description">{details.description}</span>
            </div>
          </div>
        </label>
      ))}
      
      <div className="advanced-options">
        <button onClick={() => setShowAdvanced(!showAdvanced)}>
          Advanced Options
        </button>
      </div>
    </div>
  );
};

Gasless Transactions (Meta-transactions)

For improved UX, consider implementing gasless transactions where your application pays gas fees on behalf of users.

Traditional Flow

  • 1. User initiates transaction
  • 2. User pays gas fee
  • 3. Transaction executes
  • 4. User receives confirmation

Gasless Flow

  • 1. User signs message (free)
  • 2. Relayer pays gas fee
  • 3. Transaction executes
  • 4. User receives confirmation

4. Progressive Web3 Features

Graceful Degradation

Design your application to work for both Web3 and traditional users, with enhanced features for those who connect wallets.

FeatureNo WalletWallet Connected
Browse NFTs✅ Full access✅ + Ownership indicators
View Profiles✅ Public info only✅ + Private collections
Make Offers❌ Sign up required✅ Direct blockchain offers
Purchase❌ Requires wallet✅ Instant purchase

5. Trust & Security Indicators

Transaction Transparency

Users need to understand exactly what they're signing and the potential consequences of their actions.

// Transaction preview component
const TransactionPreview = ({ transaction }) => {
  return (
    <div className="transaction-preview">
      <h3>Review Transaction</h3>
      
      {/* Clear action summary */}
      <div className="action-summary">
        <div className="action-type">
          You are about to <strong>mint 1 NFT</strong>
        </div>
        <div className="action-result">
          This will add the NFT to your wallet
        </div>
      </div>
      
      {/* Cost breakdown */}
      <div className="cost-breakdown">
        <h4>Cost Breakdown</h4>
        <div className="cost-item">
          <span>NFT Price</span>
          <span>0.05 ETH ($95.50)</span>
        </div>
        <div className="cost-item">
          <span>Gas Fee</span>
          <span>0.003 ETH ($5.73)</span>
        </div>
        <div className="cost-total">
          <span>Total</span>
          <span>0.053 ETH ($101.23)</span>
        </div>
      </div>
      
      {/* Security checks */}
      <div className="security-indicators">
        <div className="indicator verified">
          ✅ Contract verified on Etherscan
        </div>
        <div className="indicator">
          ✅ Creator has 2.1K followers
        </div>
        <div className="indicator warning">
          ⚠️ New collection (created 2 days ago)
        </div>
      </div>
      
      {/* Risk warnings */}
      <div className="risk-warnings">
        <h5>Important Information</h5>
        <ul>
          <li>This transaction cannot be reversed</li>
          <li>NFT floor price: 0.02 ETH</li>
          <li>You are paying above floor price</li>
        </ul>
      </div>
    </div>
  );
};

6. Mobile Web3 Considerations

Mobile Wallet Integration

Mobile-First Design Patterns

  • Deep Linking: Allow users to open transactions directly in their mobile wallet app
  • WalletConnect: Use QR codes for desktop-to-mobile wallet connections
  • Progressive Web App: Install prompts for better mobile experience
  • Touch-Friendly UI: Large buttons and touch targets for transaction confirmations

7. Testing Your Web3 UX

User Testing Framework

Test with New Users

  • • Complete beginners to Web3
  • • No wallet installed initially
  • • Test setup-to-first-transaction flow
  • • Measure task completion rates

Test with Power Users

  • • Experienced DeFi/NFT users
  • • Multiple wallets connected
  • • Advanced features and edge cases
  • • Performance and efficiency focus

Key Metrics to Track

  • Wallet Connection Rate: % of visitors who successfully connect
  • Transaction Success Rate: % of initiated transactions completed
  • Time to First Transaction: From landing to first successful tx
  • Error Recovery Rate: % of users who retry after errors
  • Mobile vs Desktop Performance: Platform-specific conversion rates

Real-World Examples

OpenSea: Progressive Enhancement

OpenSea allows browsing without a wallet but progressively reveals features like bidding and purchasing as users connect wallets.

UX Win: 73% of users browse before connecting wallets

Uniswap: Clear Transaction Preview

Uniswap shows clear swap previews with price impact warnings, slippage tolerance, and detailed gas fee breakdowns.

UX Win: 89% transaction success rate with preview system

Polygon: Gasless Transactions

Many Polygon dApps offer gasless transactions through meta-transactions, removing barriers for new users.

UX Win: 340% increase in user engagement with gasless flows

Design System for Web3

Essential Components

  • Wallet Connection Modal: Progressive wallet discovery
  • Transaction Status: Multi-stage progress indicators
  • Balance Display: Clear token amounts and USD values
  • Network Switcher: Easy blockchain network switching
  • Error Notifications: Actionable error messages
  • Security Badges: Trust indicators and verifications

Accessibility in Web3

Web3 applications must be accessible to users with disabilities, following WCAG guidelines while handling blockchain-specific interactions.

Accessibility Checklist

  • ✅ Screen reader support for transaction states
  • ✅ High contrast mode for wallet addresses
  • ✅ Keyboard navigation for all wallet interactions
  • ✅ Clear focus indicators on interactive elements
  • ✅ Alternative text for QR codes and graphics
  • ✅ Voice descriptions for complex visualizations

Future of Web3 UX

Emerging Patterns

  • Account Abstraction: Smart wallets with better UX
  • Social Recovery: Wallet recovery through trusted contacts
  • Embedded Wallets: Wallets built into applications
  • Batched Transactions: Multiple operations in single transaction
  • Intent-Based UX: Users specify goals, not technical steps

Key Takeaways

  1. Hide complexity, don't eliminate it: Abstract technical details while maintaining transparency
  2. Progressive enhancement: Design for non-Web3 users first
  3. Clear feedback: Every blockchain interaction needs status updates
  4. Error recovery: Provide actionable solutions, not just error messages
  5. Test with real users: Web3 UX assumptions often don't match reality

Building user-friendly Web3 experiences?

Our team has designed and built Web3 applications for DeFi protocols, NFT marketplaces, and blockchain games. We can help you create Web3 experiences that users actually want to use.

Discuss Your Web3 Project