Avail Nexus SDK Tutorial | Part 1: Setup and Balances

In this tutorial, you'll set up the Nexus SDK and build your first unified Web3 experience by viewing balances across multiple chains.

By Christine Perry 15 min read
Avail Nexus SDK Tutorial | Part 1: Setup and Balances

Navigating Web3 networks today can feel like asking users to become blockchain experts just to use an app! They need to manage gas on different chains, bridge assets manually and constantly switch networks. What if your users could interact with multiple blockchain networks from within your app instead?

The Avail Nexus SDK makes this a reality. Think of it like the internet, you don't think about which servers host websites, you just browse different websites and pages seamlessly. The Nexus SDK does the same for blockchains, handling all the complex multi-chain operations behind the scenes.

In Part 1, we're going to setup the foundation, a clean Web3 application that displays unified token balances across multiple chains. This might seem simple, but it's an important foundation for your users to see all their assets in one place, regardless of which blockchain they're on.


Tutorial Series Overview

This is Part 1 of 4 in our comprehensive Nexus SDK tutorials:

✅ Part 1: Getting Started (You are here)

  • Set up the Nexus SDK from scratch
  • Build unified balance display
  • Handle wallet connections and basic errors

🔜 Part 2: Cross-Chain Operations (Coming next)

  • Implement cross-chain bridging
  • Move assets between networks seamlessly
  • Handle token transfer confirmations and status

🔜 Part 3: Direct Transfers (Coming soon)

  • Send tokens directly across chains
  • Build cross-chain payment flows
  • Advanced transaction handling

🔜 Part 4: Production Ready (Final part)

  • Deploy to mainnet with confidence
  • Advanced error monitoring and analytics
  • Performance optimization and scaling

💡 Just want the code?

You can skip the tutorial and run the complete Part 1 application here!


What We're Building in Part 1

We'll create a Unified Balance View that showcases the core power of Avail Nexus.

What You'll Learn:

  • How to set up the Nexus SDK from scratch
  • Building unified balance displays across multiple chains
  • Implementing wallet connection flows
  • Handling basic error scenarios gracefully

What You'll Build:

  • A clean, responsive Web3 application
  • Real-time unified balance tracking across chains
  • Professional wallet connection interface
  • Solid foundation for Parts 2-4

Prerequisites

Before we begin, ensure you have:

  • Node.js (v16 or higher) - Download here
  • A package manager (npm, yarn, or pnpm)
  • Basic knowledge of React/Next.js - hooks, components, state management
  • A wallet extension like MetaMask installed and set up
  • Some testnet tokens for testing (we'll show you how to get them)

Important Considerations

Before we dive into the code, there are a few key things to understand about the Nexus SDK.

Browser-Only Environment

The Nexus SDK is designed specifically for browser environments and cannot be used in server-side contexts.

This means:

  • All SDK operations must happen on the client side
  • Use 'use client' directive in Next.js App Router
  • No SDK calls in API routes or server components

Wallet Provider Requirement

The SDK requires an injected wallet provider to function:

  • MetaMask, WalletConnect, or similar wallet extensions
  • The wallet must be unlocked and connected
  • Users need to approve the initial connection

Initialization is Critical

The SDK must be properly initialized before any other methods are called:

  • Wait for wallet connection before initializing
  • Handle initialization errors gracefully
  • Provide clear feedback during setup

Step 1: Create a New Project

Let's start with a fresh Next.js project that we'll enhance throughout this tutorial series.

npx create-next-app@latest nexus-sdk-tutorial
cd nexus-sdk-tutorial

When prompted, select these options for the best development experience:

✔ Would you like to use TypeScript? › Yes
✔ Would you like to use ESLint? › Yes
✔ Would you like to use Tailwind CSS? › Yes (optional, for styling)
✔ Would you like to use `src/` directory? › No
✔ Would you like to use App Router? › Yes
✔ Would you like to customize the default import alias? › No

Why these choices?

  • TypeScript: Provides better development experience and catches errors early
  • ESLint: Helps maintain code quality and consistency
  • Tailwind CSS: Makes styling fast and consistent (optional but recommended)
  • App Router: The modern Next.js routing system with better performance

Step 2: Install Dependencies

Install the Nexus SDK and required wallet connection libraries:

npm install avail-nexus-sdk connectkit wagmi viem @tanstack/react-query lucide-react

If you encounter dependency conflicts with React 19:

npm install avail-nexus-sdk connectkit wagmi viem @tanstack/react-query lucide-react --legacy-peer-deps

Understanding the Dependencies

  • avail-nexus-sdk: The core Nexus SDK for chain abstraction
  • connectkit: Beautiful, user-friendly wallet connection UI
  • wagmi: React hooks for Ethereum, provides wallet connection logic
  • viem: TypeScript interface for Ethereum, modern alternative to ethers.js
  • @tanstack/react-query: State management library required by wagmi for caching and data fetching

Step 3: Set Up ConnectKit Provider

ConnectKit provides a seamless wallet connection experience that works great with the Nexus SDK.

Create components/Web3Provider.tsx:

'use client';

import { WagmiProvider, createConfig, http } from 'wagmi';
import { sepolia, baseSepolia, polygonAmoy, arbitrumSepolia, optimismSepolia } from 'wagmi/chains';
import { ConnectKitProvider, getDefaultConfig } from 'connectkit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactNode, useState } from 'react';

// Configure wagmi with ConnectKit - testnets only for development
const config = createConfig(
  getDefaultConfig({
    // Your dApp info
    appName: 'Nexus SDK Tutorial - Part 1',
    appDescription: 'Learning chain abstraction with unified balance viewing',
    appUrl: 'https://localhost:3000',
    appIcon: '/avail-logo.svg', // Add Avail logo to your public folder

    // WalletConnect Project ID (get from https://cloud.walletconnect.com)
    walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID || 'your-wallet-connect-project-id',

    // Supported chains - testnets only for safe development
    chains: [
      sepolia,        // Ethereum testnet
      baseSepolia,    // Base testnet
      polygonAmoy,    // Polygon testnet
      arbitrumSepolia, // Arbitrum testnet
      optimismSepolia  // Optimism testnet
    ],
    transports: {
      [sepolia.id]: http(),
      [baseSepolia.id]: http(),
      [polygonAmoy.id]: http(),
      [arbitrumSepolia.id]: http(),
      [optimismSepolia.id]: http(),
    },
  })
);

interface Web3ProviderProps {
  children: ReactNode;
}

export function Web3Provider({ children }: Web3ProviderProps) {
  // Create a client for TanStack Query (required by wagmi)
  const [queryClient] = useState(() => new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 1000 * 60 * 5, // 5 minutes
        retry: false,
      },
    },
  }));

  return (
    <QueryClientProvider client={queryClient}>
      <WagmiProvider config={config}>
        <ConnectKitProvider
          theme="auto"
          mode="light"
          customTheme={{
            "--ck-border-radius": "8px",
            "--ck-primary-button-background": "#2563eb",
            "--ck-primary-button-hover-background": "#1d4ed8",
          }}
          options={{
            enforceSupportedChains: false,
            walletConnectName: "Nexus Tutorial",
          }}
        >
          {children}
        </ConnectKitProvider>
      </WagmiProvider>
    </QueryClientProvider>
  );
}

Configuration Explained

WalletConnect Project ID: Get this free from WalletConnect Cloud. It's required for mobile wallet connections.

Supported Tetnet Chains: The tutorial supports these testnet networks:

  • Sepolia (11155111) - Ethereum testnet
  • Base Sepolia (84532) - Base testnet
  • Polygon Amoy (80002) - Polygon testnet
  • Arbitrum Sepolia (421614) - Arbitrum testnet
  • Optimism Sepolia (11155420) - Optimism testnet

Transport Configuration: Uses default RPC endpoints. In Part 4, we'll upgrade to dedicated RPC providers for production.


Step 4: Create Nexus Provider

This is where the magic happens! We'll create a provider that initializes and manages the Nexus SDK.

Create components/NexusProvider.tsx:

'use client';

import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { useAccount } from 'wagmi';

// Global window extension for wallet provider
declare global {
  interface Window {
    ethereum?: any;
  }
}

interface NexusContextType {
  sdk: any; // Replace with actual SDK type when available
  isInitialized: boolean;
  balances: any[];
  isLoading: boolean;
  error: string | null;
  refreshBalances: () => Promise<void>;
}

const NexusContext = createContext<NexusContextType | undefined>(undefined);

interface NexusProviderProps {
  children: ReactNode;
}

export function NexusProvider({ children }: NexusProviderProps) {
  const { isConnected, address } = useAccount();
  const [sdk, setSdk] = useState<any>(null);
  const [isInitialized, setIsInitialized] = useState(false);
  const [balances, setBalances] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Initialize SDK when wallet connects
  useEffect(() => {
    if (isConnected && window.ethereum && !isInitialized && !isLoading) {
      initializeSDK();
    }
  }, [isConnected, isInitialized, isLoading]);

  // Fetch balances after SDK is initialized
  useEffect(() => {
    if (isInitialized && sdk) {
      fetchBalances(sdk);
    }
  }, [isInitialized, sdk]);

  const initializeSDK = async () => {
    try {
      setIsLoading(true);
      setError(null);
      
      // Dynamic import to ensure client-side only loading
      const { NexusSDK } = await import('avail-nexus-sdk');
      const nexusSDK = new NexusSDK({ network: 'testnet' });
      
      // Initialize with the wallet provider
      await nexusSDK.initialize(window.ethereum);
      
      // Set up allowance hook for token approvals
      nexusSDK.setOnAllowanceHook(async ({ allow, sources }: { allow: (allowances: string[]) => void; sources: any[] }) => {
        console.log('Allowance required for sources:', sources);
        
        // For Part 1, we'll auto-approve with minimum allowances
        // In Part 2, we'll build proper approval modals
        const allowances = sources.map(() => 'min');
        allow(allowances);
      });
      
      // Set up intent hook for transaction previews
      nexusSDK.setOnIntentHook(({ intent, allow }: { intent: any; allow: () => void }) => {
        console.log('Transaction intent:', intent);
        
        // For Part 1, we'll auto-approve
        // In Part 3, we'll build transaction preview modals
        allow();
      });
      
      setSdk(nexusSDK);
      setIsInitialized(true);
      
      // Fetch initial balances
      await fetchBalances(nexusSDK);
      
    } catch (error) {
      console.error('Failed to initialize Nexus SDK:', error);
      setError(error instanceof Error ? error.message : 'Failed to initialize SDK');
    } finally {
      setIsLoading(false);
    }
  };

  const fetchBalances = async (sdkInstance = sdk) => {
    if (!sdkInstance || !isInitialized) return;
    
    try {
      setIsLoading(true);
      setError(null);
      
      const unifiedBalances = await sdkInstance.getUnifiedBalances();
      setBalances(unifiedBalances);
      console.log('Unified balances fetched:', unifiedBalances);
      
    } catch (error) {
      console.error('Failed to fetch balances:', error);
      setError(error instanceof Error ? error.message : 'Failed to fetch balances');
    } finally {
      setIsLoading(false);
    }
  };

  const refreshBalances = async () => {
    await fetchBalances();
  };

  // Reset state when wallet disconnects
  useEffect(() => {
    if (!isConnected) {
      setSdk(null);
      setIsInitialized(false);
      setBalances([]);
      setError(null);
    }
  }, [isConnected]);

  return (
    <NexusContext.Provider 
      value={{ 
        sdk, 
        isInitialized, 
        balances, 
        isLoading, 
        error,
        refreshBalances 
      }}
    >
      {children}
    </NexusContext.Provider>
  );
}

export function useNexus() {
  const context = useContext(NexusContext);
  if (context === undefined) {
    throw new Error('useNexus must be used within a NexusProvider');
  }
  return context;
}

Key Features Explained

Dynamic Import: We use dynamic imports to ensure the SDK only loads on the client side, preventing server-side rendering issues.

Automatic Initialization: The SDK initializes automatically when a wallet connects, providing a seamless user experience.

Error Handling: Comprehensive error handling with user-friendly error messages and proper cleanup.

Hook Architecture: The SDK uses hooks for allowances and intents. We'll explore these more in Parts 2 and 3.


Step 5: Create Wallet Connection Component

A clean, user-friendly wallet connection interface.

Create components/WalletConnection.tsx:

'use client';

import { ConnectKitButton } from 'connectkit';
import { useAccount } from 'wagmi';
import { Wallet, CheckCircle, AlertCircle } from 'lucide-react';

export function WalletConnection() {
  const { isConnected } = useAccount();

  return (
    <ConnectKitButton.Custom>
      {({ isConnected, show, truncatedAddress, ensName, chain }) => {
        return (
          <button
            onClick={show}
            className={`
              flex items-center space-x-2 px-4 py-2 rounded-lg font-medium transition-all duration-200
              ${isConnected 
                ? 'bg-green-50 text-green-700 border border-green-200 hover:bg-green-100' 
                : 'bg-blue-600 text-white hover:bg-blue-700 shadow-lg hover:shadow-xl'
              }
            `}
          >
            {isConnected ? (
              <CheckCircle className="w-4 h-4" />
            ) : (
              <Wallet className="w-4 h-4" />
            )}
            <span>
              {isConnected ? (ensName ?? truncatedAddress) : 'Connect Wallet'}
            </span>
            {chain && (
              <span className="text-xs bg-white/20 px-2 py-1 rounded">
                {chain.name}
              </span>
            )}
          </button>
        );
      }}
    </ConnectKitButton.Custom>
  );
}

// Alternative: Simple default ConnectKit button for minimal setup
export function SimpleWalletConnection() {
  return <ConnectKitButton />;
}

Design Choices

Visual Feedback: The button changes appearance based on connection status, providing immediate visual feedback.

Chain Display: Shows the currently connected chain for user awareness.

Responsive Design: Works well on both desktop and mobile devices.


Step 6: Create Unified Balance Display

This component showcases the power of the Nexus SDK by displaying unified balances across all chains.

Create components/UnifiedBalances.tsx:

'use client';

import { useNexus } from './NexusProvider';
import { RefreshCw, Coins, TrendingUp, AlertCircle, ArrowRight } from 'lucide-react';

export function UnifiedBalances() {
  const { balances, isLoading, sdk, isInitialized, error, refreshBalances } = useNexus();

  if (!isInitialized) {
    return (
      <div className="text-center py-8">
        <div className="inline-flex items-center space-x-2 text-slate-500">
          <Coins className="w-5 h-5" />
          <span>Connect your wallet to view unified balances</span>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="text-center py-8">
        <div className="inline-flex items-center space-x-2 text-red-500 bg-red-50 px-4 py-2 rounded-lg">
          <AlertCircle className="w-5 h-5" />
          <span>Error: {error}</span>
        </div>
        <button
          onClick={refreshBalances}
          className="mt-4 text-blue-600 hover:text-blue-700 underline"
        >
          Try Again
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex justify-between items-center">
        <div>
          <h2 className="text-2xl font-bold text-slate-900">Unified Balances</h2>
          <p className="text-slate-600">Your assets across all connected chains</p>
        </div>
        <button
          onClick={refreshBalances}
          disabled={isLoading}
          className="flex items-center space-x-2 bg-slate-100 hover:bg-slate-200 disabled:opacity-50 text-slate-700 font-medium py-2 px-4 rounded-lg transition-colors"
        >
          <RefreshCw className={`w-4 h-4 ${isLoading ? 'animate-spin' : ''}`} />
          <span>{isLoading ? 'Loading...' : 'Refresh'}</span>
        </button>
      </div>
      
      {/* Balance Cards */}
      {balances.length === 0 ? (
        <div className="text-center py-12">
          <div className="inline-flex items-center space-x-2 text-slate-500">
            <TrendingUp className="w-5 h-5" />
            <span>No balances found across connected chains</span>
          </div>
          <p className="text-sm text-slate-400 mt-2">
            Make sure you have assets on supported networks
          </p>
        </div>
      ) : (
        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
          {balances.map((balance, index) => (
            <div 
              key={index} 
              className="p-6 bg-white rounded-xl border border-slate-200 shadow-sm hover:shadow-md transition-shadow"
            >
              <div className="flex justify-between items-start mb-4">
                <div className="flex items-center gap-2">
                  {balance.icon && (
                    <img src={balance.icon} alt={balance.symbol} className="w-6 h-6 rounded-full" />
                  )}
                  <h3 className="font-semibold text-lg text-slate-900">
                    {balance.symbol}
                  </h3>
                </div>
                <div className="text-right">
                  <p className="text-xl font-mono font-bold text-slate-900">
                    {parseFloat(balance.balance).toFixed(4)}
                  </p>
                  {balance.balanceInFiat > 0 && (
                    <p className="text-sm text-slate-500">
                      ${balance.balanceInFiat.toFixed(2)}
                    </p>
                  )}
                </div>
              </div>
              {/* Per-chain breakdown */}
              {balance.breakdown && balance.breakdown.length > 0 && (
                <div className="mt-2 space-y-1">
                  {balance.breakdown.map((item: any, idx: number) => (
                    <div
                      key={idx}
                      className={`text-sm flex justify-between ${item.balance === '0' ? 'text-gray-400' : 'text-gray-600'}`}
                    >
                      <span className="flex items-center gap-1">
                        {item.chain.name}
                      </span>
                      <span className="font-mono">{item.balance}</span>
                    </div>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      {/* Summary Stats */}
      {balances.length > 0 && (
        <div className="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl p-6 border border-blue-100">
          <h3 className="font-semibold text-slate-900 mb-3">Portfolio Summary</h3>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div>
              <p className="text-sm text-slate-500">Total Assets</p>
              <p className="text-lg font-semibold text-slate-900">{balances.length}</p>
            </div>
            <div>
              <p className="text-sm text-slate-500">Chains</p>
              <p className="text-lg font-semibold text-slate-900">
                {new Set(balances.map(b => b.chainId)).size}
              </p>
            </div>
            <div>
              <p className="text-sm text-slate-500">Last Updated</p>
              <p className="text-sm text-slate-700">Just now</p>
            </div>
            <div>
              <p className="text-sm text-slate-500">Status</p>
              <p className="text-sm text-green-600 font-medium">Active</p>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Component Features

Unified Display: Shows balances from all chains in a single, coherent interface, a core value of Nexus!

Real-time Updates: Refresh button allows users to get the latest balance information.

Error Handling: Gracefully handles and displays error states with recovery options.

Portfolio Summary: Provides useful insights about the user's multi-chain portfolio.


Step 7: Update Root Layout

Connect all the providers and components together.

Update app/layout.tsx:

import { Web3Provider } from '@/components/Web3Provider';
import { NexusProvider } from '@/components/NexusProvider';
import { Inter } from 'next/font/google';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata = {
  title: 'Nexus SDK Tutorial - Part 1: Getting Started',
  description: 'Learn chain abstraction by building unified balance viewing with the Avail Nexus SDK',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Web3Provider>
          <NexusProvider>
            {children}
          </NexusProvider>
        </Web3Provider>
      </body>
    </html>
  );
}

Step 8: Create Main App Page

Bring everything together in a cohesive user interface.

Update app/page.tsx:

'use client';

import { WalletConnection } from '@/components/WalletConnection';
import { UnifiedBalances } from '@/components/UnifiedBalances';
import { useAccount } from 'wagmi';
import { useNexus } from '@/components/NexusProvider';
import { Globe, Zap, Shield, ArrowRight } from 'lucide-react';

export default function Home() {
  const { isConnected } = useAccount();
  const { isInitialized, isLoading } = useNexus();

  return (
    <main className="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50">
      <div className="container mx-auto px-4 py-8">
        
        {/* Header */}
        <div className="text-center mb-12">
          <div className="inline-flex items-center space-x-2 mb-4">
            <Globe className="w-8 h-8 text-blue-600" />
            <h1 className="text-4xl font-bold text-slate-900">
              Nexus SDK Tutorial
            </h1>
          </div>
          <div className="mb-4">
            <span className="bg-blue-100 text-blue-800 text-sm font-medium px-3 py-1 rounded-full">
              Part 1: Getting Started
            </span>
          </div>
          <p className="text-xl text-slate-600 max-w-2xl mx-auto">
            Experience unified Web3 interactions by viewing your balances across 
            multiple blockchains in one place
          </p>
        </div>

        {/* Wallet Connection */}
        <div className="flex justify-center mb-8">
          <WalletConnection />
        </div>

        {/* Main Content */}
        {isConnected ? (
          <div className="max-w-4xl mx-auto">
            <UnifiedBalances />
          </div>
        ) : (
          <div className="text-center py-12">
            <div className="max-w-md mx-auto">
              <h2 className="text-2xl font-bold text-slate-900 mb-4">
                Ready to Experience Chain Abstraction?
              </h2>
              <p className="text-slate-600 mb-8">
                Connect your wallet to see how the Nexus SDK unifies your multi-chain portfolio
              </p>
              <div className="bg-white/60 backdrop-blur-sm rounded-xl p-8 border border-slate-200">
                <p className="text-sm text-slate-500">
                  This demo will show you how the Nexus SDK aggregates balances 
                  across multiple chains in real-time
                </p>
              </div>
            </div>
          </div>
        )}

        {/* Loading State */}
        {isConnected && isLoading && !isInitialized && (
          <div className="fixed inset-0 bg-black/20 backdrop-blur-sm flex items-center justify-center z-50">
            <div className="bg-white rounded-xl p-6 shadow-xl">
              <div className="flex items-center space-x-3">
                <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
                <span className="text-slate-700">Initializing Nexus SDK...</span>
              </div>
            </div>
          </div>
        )}
      </div>
    </main>
  );
}

Step 9: Environment Configuration

Set up your environment variables for proper wallet connectivity.

Create .env.local:

# WalletConnect Project ID (required for mobile wallet support)
# Get this free from https://cloud.walletconnect.com
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id

# Optional: App metadata
NEXT_PUBLIC_APP_NAME="Nexus SDK Tutorial - Part 1"
NEXT_PUBLIC_APP_DESCRIPTION="Learning chain abstraction with unified balance viewing"

Getting Your WalletConnect Project ID

  1. Visit WalletConnect Cloud
  2. Sign up for a free account
  3. Create a new project
  4. Copy your Project ID
  5. Paste it in your .env.local file

Note: This is required for mobile wallet connections but the app will work with browser wallets like MetaMask even without it.


Step 10: Testing Your Integration

Now let's test everything to make sure it works perfectly.

1. Start the Development Server

npm run dev

2. Testing Checklist

Visit http://localhost:3000 and verify:

✅ Basic Functionality:

  • [ ] App loads without errors
  • [ ] Part 1 badge displays correctly
  • [ ] Wallet connection button appears
  • [ ] Can connect MetaMask successfully
  • [ ] Connection status updates correctly

✅ Nexus SDK Integration:

  • [ ] SDK initializes after wallet connection
  • [ ] Loading states display properly
  • [ ] Unified balances appear (if you have assets)
  • [ ] Refresh functionality works

✅ Error Handling:

  • [ ] Graceful handling when no balances found
  • [ ] Error messages display clearly
  • [ ] Recovery options work (try again button)

✅ User Experience:

  • [ ] Responsive design on mobile
  • [ ] Smooth transitions and animations
  • [ ] Clear visual feedback for all actions

Step 11: Understanding What You Built

Congratulations! You've just built something awesome. Let's understand what makes this demo special:

The Magic of Unified Balances

Before users had to:

  1. Switch networks manually in their wallet
  2. Check each chain separately for their assets
  3. Remember which assets are on which chains
  4. Manage multiple gas tokens for different networks

With your Nexus SDK integration, users can now:

  1. Connect once and see everything
  2. View all assets unified in one interface
  3. Get real-time updates across all chains
  4. Experience seamless multi-chain interactions

Technical Achievements

Smart SDK Management: Your app automatically initializes the SDK when a wallet connects and cleans up when it disconnects.

Error Recovery: Comprehensive error handling ensures users always have a path forward when something goes wrong.

Performance Optimized: Loading states and proper state management create a smooth user experience.

Future-Ready: The foundation you've built will support the advanced features in Parts 2-4.


Troubleshooting

Common Issues and Quick Fixes

🔧 SDK Won't Initialize

  • Ensure MetaMask is unlocked and connected
  • Check browser console for specific error messages
  • Try refreshing the page after wallet connection
  • Verify you're not running in server-side context

🔧 No Balances Showing

  • Make sure you have assets on supported networks (Ethereum, Polygon, Arbitrum, Base, Optimism)
  • Try the refresh button to fetch latest data
  • Check that your wallet has permissions for the connected networks

🔧 WalletConnect Issues

  • Verify your WALLETCONNECT_PROJECT_ID in .env.local
  • The app works with MetaMask even without WalletConnect
  • Clear browser cache if experiencing connection issues

🔧 TypeScript Errors

  • Run npm install @types/node if needed
  • Ensure all import paths use @/ prefix correctly
  • Check that all dependencies are compatible versions

🔧 Styling Issues

  • Verify Tailwind CSS is properly configured
  • Check that globals.css imports Tailwind directives
  • Ensure Lucide React icons are imported correctly

Part 1 Complete! 🎉

Amazing work! You've successfully built the foundation of an Avail Nexus application. Here's what you've accomplished:

✅ What You Built:

  • Unified Balance View - See assets across all chains in one place
  • Smart Wallet Integration - Seamless connection with visual feedback
  • Real-time Updates - Fresh balance data with refresh capabilities
  • Error Resilient - Graceful handling of network issues and edge cases
  • Professional UI - Clean, responsive design with loading states

✅ What You Learned:

  • How to set up the Nexus SDK from scratch
  • Building unified Web3 experiences with Avail Nexus
  • Proper error handling and user feedback patterns
  • Creating production-ready wallet connection flows

Ready for Part 2?

In Part 2: Cross-Chain Operations, we'll unlock the real power of the Nexus SDK by adding:

Cross-Chain Transfers

  • Move assets between chains with one click
  • Real-time token transfer status tracking
  • Automatic fee calculation and optimization

Smart Transaction Flows

  • Intent-based transaction system
  • Automatic route optimization
  • Built-in slippage protection

Enhanced User Experience

  • Transaction preview modals
  • Progress tracking across multiple chains
  • Advanced error recovery patterns

Get Ready for Part 2:

  • Keep your Part 1 project - we'll build on top of it
  • Make sure you have some testnet tokens on different chains
  • Get testnet ETH from faucets for testing

Community & Resources

Share Your Progress

Built Part 1? We'd love to see it!

  • Discord - Join our developer community
  • Twitter - Share your progress with Avail Nexus
  • GitHub - Explore Avail

Keep Learning


Next up: Part 2 where we'll add the game-changing cross-chain bridging capabilities that make the Nexus SDK truly revolutionary!