Sui.

帖子

分享您的知识。

Evgeniy CRYPTOCOIN.
Jun 26, 2025
专家问答

How to Properly Use the Sui SDK for Frontend Integration?

I'm building a frontend (React/Next.js) for a Sui dApp and need to interact with the blockchain—fetching objects, sending transactions, and listening to events. I’ve tried using the @mysten/sui.js SDK, but I’m running into issues:

Wallet Connection: Sometimes, the wallet doesn’t return the user’s address after connecting.

Transaction Handling: Transactions fail silently or return vague errors.

RPC Limits: I get rate-limited or timeouts when fetching large datasets.

Real-Time Updates: How can I listen for on-chain events (e.g., NFT mints, balance changes)?

What I’ve tried:

✔ Basic SuiClient setup with mainnet and testnet RPCs.

✔ Using useWallet() from @mysten/dapp-kit for wallet integration.

✔ Manual transaction signing with signAndExecuteTransactionBlock.

Questions:

What’s the recommended way to initialize the Sui SDK in a frontend app?

How do I handle errors gracefully (e.g., RPC failures, wallet rejections)?

Are there best practices for optimizing queries (batching, caching, etc.)?

How can I subscribe to real-time updates (e.g., new transactions, object changes)?

  • Sui
  • SDKs and Developer Tools
6
2
分享
评论
.

答案

2
Benjamin XDV.
Jun 30 2025, 18:13

专家答案:

  1. 初始化 Sui SDK @mysten /sui.js SDK 应使用可靠的 RPC 端点进行配置. 对于生产应用程序,请考虑:

默认 RPC:

ts
import { SuiClient, getFullnodeUrl } from '@mysten/sui.js/client';  

const client = new SuiClient({ url: getFullnodeUrl('mainnet') });  

备用 RPC:使用 Sui RPC 提供商等服务来避开速率限制.

要进行钱包集成,请使用 @mysten /dapp-kit:

tsx
import { createNetworkConfig, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';  
import { getFullnodeUrl } from '@mysten/sui.js/client';  

const { networkConfig } = createNetworkConfig({  
  mainnet: { url: getFullnodeUrl('mainnet') },  
  testnet: { url: getFullnodeUrl('testnet') },  
});  

function App() {  
  return (  
    <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">  
      <WalletProvider autoConnect>  
        <YourApp />  
      </WalletProvider>  
    </SuiClientProvider>  
  );  
}  
  1. 处理交易和错误 务必在错误处理中封装交易:

ts

try {  
  const tx = await signAndExecuteTransactionBlock({  
    transactionBlock: txBlock,  
    options: { showEffects: true },  
  });  
  console.log("Tx Digest:", tx.digest);  
} catch (err) {  
  console.error("Tx Failed:", err.message);  
  // Handle specific errors (e.g., user rejection, insufficient gas)  
}  

常见错误:

“用户拒绝了请求” → 钱包弹出窗口已关闭.

“超出天然气预算” → 使用 txblock.setGasBudget () 增加天然气预算.

“未找到对象” → 检查对象 ID 是否正确且仍然存在.

3.优化 RPC 调用 批处理请求:使用 MultigetObjects 在一次调用中获取多个对象.

缓存:使用 React Query 或 SWR 来缓存 RPC 响应:

ts
import { useSuiClientQuery } from '@mysten/dapp-kit';  

const { data } = useSuiClientQuery('getObject', {  
  id: objectId,  
  options: { showContent: true },  
});  

分页:对于大型数据集,使用带光标的 SUIX_getDynamicFields.

  1. 实时更新 使用 WebSockets 或投票:

WebSocket 订阅(高级):

ts
const unsubscribe = client.subscribeEvent({  
  filter: { sender: '0x123...' },  
  onMessage(event) { console.log("New event:", event); },  
});  

//卸载时清理 返回 () => 取消订阅 (); 使用 Hooks 进行投票:

ts
useSuiClientSubscription('subscribeEvent', {  
  filter: { eventType: 'ExampleEvent' },  
  onData(event) { console.log("Event:", event); },  
});  

专业小贴士

  1. 使用 @mysten /dapp-kit 获取预建的钱包挂钩.
  2. 为复杂的交易设置自定义燃气预算. 3.监控 RPC 运行状况 — 如果响应缓慢,则切换端点.
  3. 在主网部署之前在测试网上进行测试.
5
最佳答案
评论
.
HaGiang.
Jun 30 2025, 05:57

###1. 推荐的 SDK 初始化

对于生产级 React 或 Next.js 去中心化应用程序,推荐的堆栈结合了三个关键包. 此设置将低级区块链交互与应用程序状态管理分开. [1、2、3]

*核心库

*@mysten/sui.js:适用于所有直接 Sui 网络交互的基础 TypeScript SDK. [4] *@mysten/dapp-kit: 主要的 React 库,带有用于钱包连接和数据获取的挂钩和组件. [2、5、6] *@tanstack/react-query:用于将@mysten/dapp-kit缓存、重新获取和管理链上数据作为服务器状态的必需依赖项. [1, 7]

*提供商设置: 按照正确的顺序用这些提供程序包装应用程序的根组件,以确保所有挂钩都能正常运行. [3, 4]

   import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
   import { SuiClientProvider, WalletProvider, createNetworkConfig } from '@mysten/dapp-kit';
   import { getFullnodeUrl } from '@mysten/sui/client';
   import '@mysten/dapp-kit/dist/index.css';

   const queryClient = new QueryClient();
   const { networkConfig } = createNetworkConfig({
     mainnet: { url: getFullnodeUrl('mainnet') },
     testnet: { url: getFullnodeUrl('testnet') },
   });

   function AppRoot() {
     return (
       <QueryClientProvider client={queryClient}>
         <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
           <WalletProvider autoConnect>
             {/* Your Application Components */}
           </WalletProvider>
         </SuiClientProvider>
       </QueryClientProvider>
     );
   }
   ```

###**2. 优雅的错误处理**

有效处理错误对于用户体验至关重要. 以下是管理常见问题的方法. 

***钱包连接失败**:钱包地址在连接后无法立即可用的问题通常是异步状态问题. 

***解决方案**:务必检查`account``useCurrentAccount()`挂钩返回的对象是否为空. 获取依赖于地址的数据时,使用`enabled:!!account`中的选项`useSuiClientQuery`来防止查询在地址可用之前运行. [3]

***交易错误**:原始 RPC 错误通常是神秘的. 使用`suiclient-error-decoder`库将它们翻译成人类可读的消息. [8, 9]

***策略**:与您的智能合约开发者协调以定义错误代码地图. `try...catch`在你的前端中,使用这个地图和解码器来解析区块中捕获的错误. 

<!--end list-->

```typescript
   import { useSignAndExecuteTransactionBlock } from '@mysten/dapp-kit';
   import { SuiClientErrorDecoder } from 'suiclient-error-decoder';

   // 1. Define your custom error map
   const myErrorMap = { 1: "Mint limit has been reached." };
   const errorDecoder = new SuiClientErrorDecoder({ customErrorCodes: myErrorMap });

   // 2. Wrap your transaction call
   const { mutateAsync: signAndExecute } = useSignAndExecuteTransactionBlock();

   async function handleMint(txb) {
     try {
       await signAndExecute({ transactionBlock: txb });
       console.log("Transaction successful!");
     } catch (error) {
       const decodedError = errorDecoder.parseError(error);
       // Display decodedError.message to the user
       console.error(decodedError.message); 
     }
   }
   ```

***常见错误**:
*`"User rejected the request"`: 用户关闭了钱包弹出窗口. [10, 11]
*`"InsufficientGas"`:天然气预算太低了. 让钱包自动设置预算;除非必要,否则避免手动设置. 

###**3. 优化查询**

要避免 RPC 速率限制并提高性能,请结合使用批处理、分页和缓存. 

***批处理**:使用在单个请求中`sui_multiGetObjects`检索最多 50 个对象 ID 的数据,而不是逐个获取对象. 这显著减少了网络流量. 

`suix_getDynamicFields`***分页**:对于诸如对象动态字段之类的大型数据集,��使用分页端点,例如.这些端点使用光标逐页获取数据,从而防止超时. 

***缓存**:`useSuiClientQuery``@mysten/dapp-kit``staleTime`from 的挂钩会自动缓存响应. [1, 5] 要进一步优化,请为不经常更改的数据(例如 NFT 元数据)设置一个. 这告诉 React Query 在重新获取之前在指定的时长内提供缓存数据,从而减少冗余的 RPC 调用. [7、12、13]

```typescript
   const { data } = useSuiClientQuery(
     'getObject',
     { id: objectId, options: { showContent: true } },
     { staleTime: 10 * 60 * 1000 } // Cache is fresh for 10 minutes
   );
   ```

***RPC 提供商**:对于生产应用程序,使用专用 RPC 提供商,如 QuickNode、Ankr 或 Chainstack,以确保可靠性并避免公共端点的严格速率限制. [14、15、16]

###**4. 实时更新**

监听链上事件有三种主要方法,每种方法都有不同的权衡取舍. 

1. **投票**:最简单的方法. `useSuiClientQuery`与 a 一起使用`refetchInterval`可定期向网络请求更新. 这适用于延迟几秒钟的非关键数据. [17]

2. **WebSocket 订阅**:此方法提供低延迟的实时更新. 但是,官方的 Sui JSON-RPC WebSocket API 已过时,因此你必须使用提供 WebSocket 支持的第三方 RPC 提供商. [18、19] 你可以用它`client.subscribeEvent`来监听特定事件,并且必须在 React `useEffect`挂钩中仔细管理订阅生命周期以防止内存泄漏. [20、21、22]

```typescript
   useEffect(() => {
     const unsubscribe = await client.subscribeEvent({
       filter: { MoveEventModule: { package: '0x...', module: 'my_module' } },
       onMessage: (event) => {
         console.log("New event:", event);
       },
     });

     // Cleanup on component unmount
     return () => {
       unsubscribe();
     };
   },);
   ```

3.**自定义索引器**:适用于关键任务应用程序的最强大、最可靠的解决方案. 索引器是一种专用的后端服务,用于处理所有链上数据并将其存储在优化的数据库中. 这允许进行标准 RPC API 无法实现的复杂、低延迟的查询. 建议将这种方法用于生产级 DeFi、游戏或分析平台. [9、23、24]
3
评论
.

你知道答案吗?

请登录并分享。

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

610帖子1423答案
Sui.X.Peera.

赚取你的 1000 Sui 份额

获取声誉积分,并因帮助 Sui 社区成长而获得奖励。

奖励活动七月