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. Ініціалізація SDK Sui SDK @mysten /sui.js повинен бути налаштований з надійною кінцевою точкою 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. ��бробка транзакцій та помилок Завжди включайте транзакції в обробку помилок:

тс

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 ().

«Об'єкт не знайдено» → Перевірте, чи ідентифікатор об'єкта правильний і все ще існує.

  1. Оптимізація викликів 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); },  
});  

//Очищення при демонтажі return () => скасувати підписку (); Опитування за допомогою гачків:

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

Поради професіоналів

  1. Використовуйте @mysten /dapp-kit для попередньо створених гачків гаманців.
  2. Встановіть власний бюджет газу для складних операцій.
  3. Моніторинг стану RPC — перемикайте кінцеві точки, якщо відповіді повільні.
  4. Тест на Testnet перед розгортанням основної мережі.
5
Найкраща відповідь
Коментарі
.
HaGiang.
Jun 30 2025, 05:57

###1. Рекомендована ініціалізація SDK

Для виробничого рівня React або Next.js DApp рекомендований стек об'єднує три ключові пакети. Ця установка відокремлює низькорівневу взаємодію блокчейну від управління станом програми. [1, 2, 3]

*Основні бібліотеки:

*@mysten/sui.js: Фундаментальний SDK TypeScript для всіх прямих взаємодій з мережею Sui. [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`параметр in, `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 та покращити продуктивність, використовуйте комбінацію пакетування, нумерації сторінок та кешування.

***Batching**: Замість отримання об'єктів один за одним, використовуйте `sui_multiGetObjects`для отримання даних до 50 ідентифікаторів об'єктів в одному запиті. Це значно зменшує мережевий трафік.

`suix_getDynamicFields`***Pagination**: Для великих наборів даних, таких як динамічні поля об'єкта, використовуйте кінцеві точки з сторінками, наприклад. Ці кінцеві точки використовують курсор для отримання даних по сторінці, запобігаючи тайм-аутам.

***Кешування**: `useSuiClientQuery`гачок `@mysten/dapp-kit`автоматично кешує відповіді. [1, 5] Для подальшої оптимізації встановіть a `staleTime`для даних, які не змінюються часто (наприклад, метадані 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**: Цей метод пропонує оновлення в режимі реального часу з низькою затримкою. Однак офіційний API WebSocket Sui JSON-RPC застарілий, тому ви повинні використовувати стороннього постачальника RPC, який пропонує підтримку WebSocket. [18, 19] Ви можете використовувати `client.subscribeEvent`для `useEffect`прослуховування конкретних подій і повинні ретельно керувати життєвим циклом підписки в React-хуку, щоб запобігти витоку пам'яті. [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.** Custom Indexer**: найпотужніше та надійне рішення для критично важливих програм. Індексатор - це спеціальна служба підтримки, яка обробляє всі дані в ланцюжку та зберігає їх у оптимізованій базі даних. Це дозволяє виконувати складні запити з низькою затримкою, які неможливі за допомогою стандартного API RPC. Цей підхід рекомендується для платформ 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.

Кампанія винагородЛипень