本文是关于 Avail Nexus SDK 的系列教程的第一部分,主要介绍了如何使用 Nexus SDK 构建一个 Web3 应用程序,该程序可以跨多个区块链网络显示统一的token余额。
今天浏览 Web3 网络可能会让用户感觉像是在成为区块链专家后才能使用应用!他们需要在不同的链上管理 gas,手动桥接资产,并且不断切换网络。如果你的用户可以在你的应用程序内与多个区块链网络进行交互呢?
Avail Nexus SDK 让这一切成为现实。可以把它想象成互联网,你不会考虑哪个服务器托管网站,你只是无缝地浏览不同的网站和页面。Nexus SDK 对区块链也做了同样的事情,在后台处理所有复杂的多链操作。
在第 1 部分中,我们将建立基础,一个干净的 Web3 应用程序,可以跨多个链显示统一的 token 余额。这可能看起来很简单,但对于你的用户来说,这是一个重要的基础,他们可以在一个地方看到他们所有的资产,而不用管它们在哪个区块链上。
这是我们全面的 Nexus SDK 教程的 第 1 部分,共 4 部分:
✅ 第 1 部分:入门 (你在这里)
🔜 第 2 部分:跨链操作 (即将推出)
🔜 第 3 部分:直接转移 (即将推出)
🔜 第 4 部分:生产就绪 (最后一部分)
充满信心地部署到主网
高级错误监控和分析
性能优化和扩展
你可以跳过教程并运行 完整的第 1 部分应用程序 !
我们将创建一个 统一余额视图,展示 Avail Nexus 的核心能力。
一个干净、响应式的 Web3 应用程序
跨链的实时统一余额跟踪
专业的钱包连接界面
第 2-4 部分的坚实基础
在我们开始之前,请确保你拥有:
Node.js (v16 或更高版本) - 在此下载
一个包管理器 (npm, yarn, 或 pnpm)
React/Next.js 的基本知识 - hooks,组件,状态管理
一个钱包扩展,例如 MetaMask,已安装并设置好
用于测试的一些测试网 token (我们将向你展示如何获得它们)
在我们深入研究代码之前,有几个关于 Nexus SDK 的关键事项需要理解。
Nexus SDK 专门为浏览器环境设计,不能在服务器端上下文中使用。
这意味着:
'use client' 指令SDK 需要一个注入的钱包 provider 才能运行:
必须在调用任何其他方法之前正确初始化 SDK:
在初始化之前等待钱包连接
优雅地处理初始化错误
在设置过程中提供清晰的反馈
让我们从一个新的 Next.js 项目开始,我们将在整个教程系列中对其进行增强。
npx create-next-app@latest nexus-sdk-tutorial
cd nexus-sdk-tutorial
当出现提示时,选择这些选项以获得最佳开发体验:
✔ 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
为什么选择这些?
TypeScript: 提供更好的开发体验并尽早发现错误
ESLint: 帮助维护代码质量和一致性
Tailwind CSS: 使样式设置快速且一致 (可选但推荐)
App Router: 具有更好性能的现代 Next.js 路由系统
安装 Nexus SDK 和所需的钱包连接库:
npm install @avail-project/nexus connectkit wagmi viem @tanstack/react-query lucide-react
如果遇到与 React 19 的依赖冲突:
npm install @avail-project/nexus connectkit wagmi viem @tanstack/react-query lucide-react --legacy-peer-deps
@avail-project/nexus: 用于链抽象的核心 Nexus SDK
connectkit: 美观、用户友好的钱包连接 UI
wagmi: 用于 Ethereum 的 React hooks,提供钱包连接逻辑
viem: Ethereum 的 TypeScript 接口,是 ethers.js 的现代替代品
@tanstack/react-query: wagmi 所需的状态管理库,用于缓存和数据获取
ConnectKit 提供无缝的钱包连接体验,与 Nexus SDK 配合良好。
创建 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
// 使用 ConnectKit 配置 wagmi - 仅测试网用于开发
const config = createConfig(
getDefaultConfig({
// Your dApp info
// 你的 dApp 信息
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
// 将 Avail 徽标添加到你的公共文件夹
// WalletConnect Project ID (get from https://cloud.walletconnect.com)
// WalletConnect 项目 ID (从 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
// Ethereum 测试网
baseSepolia, // Base testnet
// Base 测试网
polygonAmoy, // Polygon testnet
// Polygon 测试网
arbitrumSepolia, // Arbitrum testnet
// Arbitrum 测试网
optimismSepolia // Optimism testnet
// Optimism 测试网
],
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)
// 为 TanStack Query 创建一个客户端 (wagmi 需要)
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
// 5 分钟
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>
);
}
WalletConnect Project ID: 从 WalletConnect Cloud 免费获取。 这是移动钱包连接所必需的。
支持的测试网链: 本教程支持以下测试网网络:
传输配置: 使用默认的 RPC 端点。 在第 4 部分中,我们将升级到专用的 RPC provider 以进行生产。
这就是奇迹发生的地方!我们将创建一个 provider,用于初始化和管理 Nexus SDK。
创建 components/NexusProvider.tsx:
'use client';
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { useAccount } from 'wagmi';
// Global window extension for wallet provider
// 钱包 provider 的全局窗口扩展
declare global {
interface Window {
ethereum?: any;
}
}
interface NexusContextType {
sdk: any; // Replace with actual SDK type when available
// 可用时替换为实际的 SDK 类型
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
// 当钱包连接时初始化 SDK
useEffect(() => {
if (isConnected && window.ethereum && !isInitialized && !isLoading) {
initializeSDK();
}
}, [isConnected, isInitialized, isLoading]);
// Fetch balances after SDK is initialized
// 在 SDK 初始化后获取余额
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-project/nexus');
const nexusSDK = new NexusSDK({ network: 'testnet' });
// Initialize with the wallet provider
// 使用钱包 provider 初始化
await nexusSDK.initialize(window.ethereum);
// Set up allowance hook for token approvals
// 设置 token 批准的 allowance hook
nexusSDK.setOnAllowanceHook(async ({ allow, sources }: { allow: (allowances: string[]) => void; sources: any[] }) => {
console.log('Allowance required for sources:', sources);
// 允许需要源:, sources
// For Part 1, we'll auto-approve with minimum allowances
// 对于第 1 部分,我们将使用最小 allowance 自动批准
// In Part 2, we'll build proper approval modals
// 在第 2 部分中,我们将构建适当的批准弹窗
const allowances = sources.map(() => 'min');
allow(allowances);
});
// Set up intent hook for transaction previews
// 设置交易预览的 intent hook
nexusSDK.setOnIntentHook(({ intent, allow }: { intent: any; allow: () => void }) => {
console.log('Transaction intent:', intent);
// 交易意图:, intent
// For Part 1, we'll auto-approve
// 对于第 1 部分,我们将自动批准
// In Part 3, we'll build transaction preview modals
// 在第 3 部分中,我们将构建交易预览弹窗
allow();
});
setSdk(nexusSDK);
setIsInitialized(true);
// Fetch initial balances
// 获取初始余额
await fetchBalances(nexusSDK);
} catch (error) {
console.error('Failed to initialize Nexus SDK:', error);
// 无法初始化 Nexus SDK:, error
setError(error instanceof Error ? error.message : 'Failed to initialize SDK');
// 无法初始化 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);
// 统一的余额已获取:, unifiedBalances
} catch (error) {
console.error('Failed to fetch balances:', error);
// 无法获取余额:, 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');
// useNexus 必须在 NexusProvider 中使用
}
return context;
}
动态导入: 我们使用动态导入来确保 SDK 仅在客户端加载,从而防止服务器端渲染问题。
自动初始化: 当钱包连接时,SDK 会自动初始化,从而提供无缝的用户体验。
错误处理: 全面的错误处理,具有用户友好的错误消息和适当的清理。
Hook 架构: 该 SDK 使用 hooks 进行 allowance 和 intent。 我们将在第 2 部分和第 3 部分中对此进行更多探讨。
一个干净、用户友好的钱包连接界面。
创建 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'}
// {isConnected ? (ensName ?? truncatedAddress) : '连接钱包'}
</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
// 替代方案:用于最小化设置的简单默认 ConnectKit 按钮
export function SimpleWalletConnection() {
return <ConnectKitButton />;
}
视觉反馈: 该按钮根据连接状态更改外观,从而提供即时视觉反馈。
链显示: 显示当前连接的链,以提高用户意识。
响应式设计: 在桌面设备和移动设备上都能很好地工作。
该组件通过显示所有链上的统一余额来展示 Nexus SDK 的强大功能。
创建 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>
// <span>连接你的钱包以查看统一的余额</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>
// <span>错误:{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>
{/* <span>{isLoading ? '正在加载...' : '刷新'}</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>
{/* <span>在已连接的链上未找到余额</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>
);
}
统一显示: 在一个连贯的界面中显示来自所有链的余额,这是 Nexus 的核心价值!
实时更新: 刷新按钮允许用户获取最新的余额信息。
错误处理: 优雅地处理和显示错误状态以及恢复选项。
投资组合摘要: 提供有关用户多链投资组合的有用见解。
将所有 provider 和组件连接在一起。
更新 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>
);
}
将所有内容整合到一个有凝聚力的用户界面中。
更新 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>
{/* 通过在一个地方查看你在多个区块链上的余额来体验统一的 Web3 交互 */}
</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>
{/* 连接你的钱包以了解 Nexus SDK 如何统一你的多链投资组合 */}
<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>
{/* 此演示将向你展示 Nexus SDK 如何实时聚合多个链上的余额 */}
</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>
{/* 正在初始化 Nexus SDK... */}
</div>
</div>
</div>
)}
</div>
</main>
);
}
设置你的环境变量以实现正确的钱包连接。
创建 .env.local:
## WalletConnect Project ID (required for mobile wallet support)
## 从 https://cloud.walletconnect.com 免费获取
## 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"
.env.local 文件中注意: 这是移动钱包连接所必需的,但即使没有它,该应用程序也可以与 MetaMask 等浏览器钱包一起使用。
现在让我们测试所有内容,以确保其完美运行。
npm run dev
访问 http://localhost:3000 并验证:
✅ 基本功能:
✅ Nexus SDK 集成:
✅ 错误处理:
✅ 用户体验:
[ ] 移动设备上的响应式设计
[ ] 平滑的过渡和动画
[ ] 对所有操作的清晰视觉反馈
恭喜!你刚刚构建了一些很棒的东西。让我们了解一下是什么让这个演示与众不同:
在以前,用户必须:
通过你的 Nexus SDK 集成,用户现在可以:
智能 SDK 管理:你的应用程序在钱包连接时自动初始化 SDK,并在断开连接时清理它。
错误恢复:全面的错误处理可确保用户在出现问题时始终有前进的道路。
性能优化:加载状态和适当的状态管理创造了流畅的用户体验。
面向未来:你构建的基础将支持第 2-4 部分中的高级功能。
🔧 SDK 无法初始化
🔧 未显示任何余额
确保你在受支持的网络 (Ethereum、Polygon、Arbitrum、Base、Optimism) 上#### ✅ 你构建的内容:
统一余额视图 - 在一个地方查看所有链上的资产
智能钱包集成 - 与视觉反馈的无缝连接
实时更新 - 具有刷新功能的新鲜余额数据
错误恢复 - 优雅地处理网络问题和极端情况
专业的 UI - 具有加载状态的干净、响应式设计
如何从头开始设置 Nexus SDK
使用 Avail Nexus 构建统一的 Web3 体验
正确的错误处理和用户反馈模式
创建可用于生产的钱包连接流程
在第 2 部分:跨链操作中,我们将通过添加以下内容来解锁 Nexus SDK 的真正力量:
跨链转移
智能交易流程
增强的用户体验
保留你的第 1 部分项目 - 我们将在其之上构建
确保你在不同的链上有一些测试网 Token
从水龙头获取测试网 ETH 用于测试
构建了第 1 部分? 我们很乐意看到它!
接下来:第 2 部分,我们将添加改变游戏规则的跨链桥接功能,这将使 Nexus SDK 真正具有革命性!
- 原文链接: blog.availproject.org/av...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!