UNPKG

@keccak256-evg/passport-sdk

Version:

T-REX Passport SDK for interacting with Passport and Registry contracts

465 lines (388 loc) 10.6 kB
# 🎣 React Hooks 使用指南 T-REX Passport SDK 现在提供官方的 React Hook 支持,让您能够轻松地在 React 应用中集成 Passport 功能! ## ✨ 特性 - 🔄 **自动状态管理** - 自动处理加载状态、错误处理和数据更新 - 🔗 **智能重连** - 自动监听钱包和网络变化 - ⚡ **轮询支持** - 可配置的数据轮询更新 - 🎯 **类型安全** - 完整的 TypeScript 支持 - 🧹 **自动清理** - 组件卸载时自动清理资源 - 📦 **可选依赖** - React 是可选的,不会影响非 React 用户 ## 📦 安装 ```bash # 安装主包 npm install @keccak256-evg/passport-sdk # 如果使用 React Hook,还需要安装 React(如果还没有的话) npm install react ``` ## 🚀 快速开始 ### 1. useUnifiedPassportSDK - 主要 SDK Hook ```typescript import { useUnifiedPassportSDK } from '@keccak256-evg/passport-sdk'; function MyComponent() { const { sdk, isInitializing, error, providerInfo } = useUnifiedPassportSDK({ chain: { id: 1962, name: 'T-Rex Testnet', rpcUrls: { default: { http: ['https://testnetrpc.trex.xyz'] } } }, autoInitialize: true, // 自动初始化 userAddress: userWalletAddress // 监听用户地址变化 }); if (isInitializing) return <div>初始化中...</div>; if (error) return <div>错误: {error.message}</div>; if (!sdk) return <div>请连接钱包</div>; return <div>SDK 已就绪!钱包类型: {providerInfo?.isMetaMask ? 'MetaMask' : '其他'}</div>; } ``` ### 2. useWalletPassport - 检查钱包 Passport ```typescript import { useWalletPassport } from '@keccak256-evg/passport-sdk'; function PassportStatus({ sdk, userAddress }) { const { hasPassport, passportId, passportAddress, isLoading, error, check } = useWalletPassport({ sdk, walletAddress: userAddress, autoCheck: true, pollingInterval: 30000 // 每30秒检查一次 }); if (isLoading) return <div>检查中...</div>; if (error) return <div>错误: {error.message} <button onClick={check}>重试</button></div>; return ( <div> {hasPassport ? ( <div> ✅ 您有 Passport! <p>ID: {passportId}</p> <p>地址: {passportAddress}</p> </div> ) : ( <div>❌ 您还没有 Passport</div> )} </div> ); } ``` ### 3. usePassportInfo - 获取 Passport 详细信息 ```typescript import { usePassportInfo } from '@keccak256-evg/passport-sdk'; function PassportDetails({ sdk, passportAddress }) { const { passportInfo, isLoading, error, refresh } = usePassportInfo({ sdk, passportAddress, autoFetch: true, pollingInterval: 60000 // 每分钟更新一次 }); if (isLoading) return <div>加载中...</div>; if (error) return <div>错误: {error.message} <button onClick={refresh}>重新加载</button></div>; if (!passportInfo) return null; return ( <div> <h3>Passport 详细信息</h3> <p>ID: {passportInfo.passportId}</p> <p>地址: {passportInfo.passportAddress}</p> <p>绑定钱包数量: {passportInfo.walletCount}</p> <div> <h4>绑定的钱包:</h4> {passportInfo.boundWallets.map((wallet, index) => ( <p key={index}>{wallet}</p> ))} </div> <button onClick={refresh}>刷新</button> </div> ); } ``` ## 🔧 Hook API 参考 ### useUnifiedPassportSDK **配置选项:** ```typescript interface UseUnifiedPassportSDKConfig { chain: { id: number; name: string; rpcUrls: { default: { http: string[] } }; nativeCurrency?: { name: string; symbol: string; decimals: number }; blockExplorers?: { default: { name: string; url: string } }; }; env?: 'dev' | 'prod'; registryAddress?: string; autoInitialize?: boolean; // 默认 true userAddress?: string; // 用于监听地址变化 } ``` **返回值:** ```typescript interface UseUnifiedPassportSDKReturn { sdk: UnifiedPassportSDK | null; isInitializing: boolean; error: Error | null; initialize: () => Promise<void>; cleanup: () => void; providerInfo: { isMetaMask: boolean; isCoinbaseWallet: boolean; chainId?: string; selectedAddress?: string; } | null; } ``` ### useWalletPassport **配置选项:** ```typescript interface UseWalletPassportConfig { sdk: UnifiedPassportSDK | null; walletAddress?: Address; autoCheck?: boolean; // 默认 true pollingInterval?: number; // 0 表示不轮询 } ``` **返回值:** ```typescript interface UseWalletPassportReturn { walletPassport: WalletPassportResult | null; isLoading: boolean; error: Error | null; check: () => Promise<void>; clear: () => void; // 便捷属性 hasPassport: boolean; passportId?: number; passportAddress?: Address; } ``` ### usePassportInfo **配置选项:** ```typescript interface UsePassportInfoConfig { sdk: UnifiedPassportSDK | null; passportAddress?: Address; autoFetch?: boolean; // 默认 true pollingInterval?: number; // 0 表示不轮询 } ``` **返回值:** ```typescript interface UsePassportInfoReturn { passportInfo: PassportInfo | null; isLoading: boolean; error: Error | null; refresh: () => Promise<void>; clear: () => void; } ``` ## 💡 最佳实践 ### 1. 组合使用 Hooks ```typescript function PassportDashboard({ userAddress }) { // 1. 初始化 SDK const { sdk, isInitializing, error } = useUnifiedPassportSDK({ chain: tRexTestnetConfig, userAddress, autoInitialize: true }); // 2. 检查钱包状态 const { hasPassport, passportAddress } = useWalletPassport({ sdk, walletAddress: userAddress, autoCheck: true }); // 3. 获取详细信息(仅当有 Passport 时) const { passportInfo } = usePassportInfo({ sdk, passportAddress: hasPassport ? passportAddress : undefined, autoFetch: true }); // 渲染逻辑... } ``` ### 2. 自定义 Hook ```typescript // 封装常用逻辑 function usePassportOperations(userAddress?: string) { const sdkResult = useUnifiedPassportSDK({ chain: tRexTestnetConfig, userAddress, autoInitialize: true }); const walletResult = useWalletPassport({ sdk: sdkResult.sdk, walletAddress: userAddress, autoCheck: true }); const createPassport = async () => { if (!sdkResult.sdk) throw new Error('SDK not ready'); return await sdkResult.sdk.createPassport(); }; return { ...sdkResult, ...walletResult, createPassport, isReady: !!sdkResult.sdk && !sdkResult.isInitializing && !sdkResult.error }; } // 使用自定义 Hook function MyComponent({ userAddress }) { const { isReady, hasPassport, createPassport, isInitializing } = usePassportOperations(userAddress); if (isInitializing) return <div>加载中...</div>; if (!isReady) return <div>SDK 未就绪</div>; return ( <div> {hasPassport ? ( <div>您已有 Passport</div> ) : ( <button onClick={createPassport}>创建 Passport</button> )} </div> ); } ``` ### 3. 错误处理 ```typescript function ErrorBoundaryComponent() { const { sdk, error, initialize } = useUnifiedPassportSDK({ chain: tRexTestnetConfig, autoInitialize: true }); // 全局错误处理 React.useEffect(() => { if (error) { console.error('SDK Error:', error); // 可以发送到错误追踪服务 // trackError(error); } }, [error]); if (error) { return ( <div className="error-state"> <h3>出错了 😞</h3> <p>{error.message}</p> <button onClick={initialize}>重试</button> <details> <summary>技术详情</summary> <pre>{error.stack}</pre> </details> </div> ); } // 正常渲染... } ``` ### 4. 轮询控制 ```typescript function PassportMonitor({ userAddress }) { const [isMonitoring, setIsMonitoring] = useState(true); const { hasPassport, passportAddress } = useWalletPassport({ sdk, walletAddress: userAddress, autoCheck: true, pollingInterval: isMonitoring ? 30000 : 0 // 根据状态控制轮询 }); return ( <div> <label> <input type="checkbox" checked={isMonitoring} onChange={e => setIsMonitoring(e.target.checked)} /> 启用自动监控 </label> {/* 其他内容... */} </div> ); } ``` ## 🎨 样式建议 ```css /* 推荐的基础样式 */ .passport-dashboard { max-width: 600px; margin: 0 auto; padding: 20px; } .passport-dashboard.loading { text-align: center; opacity: 0.7; } .passport-dashboard.error { border: 2px solid #ff6b6b; border-radius: 8px; padding: 20px; background: #ffe0e0; } .provider-info { background: #f0f8ff; padding: 15px; border-radius: 8px; margin: 15px 0; } .wallet-passport { border: 1px solid #ddd; padding: 15px; border-radius: 8px; margin: 15px 0; } .has-passport { color: #4caf50; } .no-passport { color: #ff9800; } .actions { display: flex; gap: 10px; margin-top: 20px; } .actions button { padding: 10px 15px; border: none; border-radius: 5px; background: #007bff; color: white; cursor: pointer; } .actions button:hover { background: #0056b3; } ``` ## 📱 完整示例 查看 [`examples/react-hooks-usage.tsx`](./examples/react-hooks-usage.tsx) 获取完整的使用示例,包括: - 完整的 Passport 仪表板 - 错误处理和重试逻辑 - 自定义 Hook 封装 - 轮询和实时更新 - 样式和用户体验最佳实践 ## ❓ 常见问题 ### Q: Hook 是否支持服务端渲染 (SSR)? A: 部分支持。Hook 会自动检测环境,在服务端不会尝试访问 `window` 对象,但 SDK 功能需要在客户端才能工作。 ### Q: 如何处理网络切换? A: Hook 会自动监听网络变化并在控制台输出警告。您可以通过 `providerInfo.chainId` 检查当前网络。 ### Q: 是否可以同时使用多个 SDK 实例? A: 可以,每个 Hook 实例都是独立的。但通常一个应用只需要一个 SDK 实例。 ### Q: Hook 的性能如何? A: Hook 使用了 React 的最佳实践,包括 `useCallback`、`useMemo` 等优化。轮询是可选的,不会影响不需要实时数据的组件。 ### Q: 如何在 React Native 中使用? A: 目前主要针对 Web 环境优化。React Native 支持可能需要额外的 polyfill 和配置。 --- **开始使用 React Hook 让 Passport 集成变得前所未有的简单!** 🚀