Пост
Поделитесь своими знаниями.
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
Ответы
2Ответ эксперта:
- Инициализация Sui SDK 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 Providers, чтобы избежать ограничений по скорости.
Для интеграции кошельков используйте @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>
);
}
- Обработка транзакций и ошибок Всегда относите транзакции к обработке ошибок:
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 ().
«Объект не найден» → Проверьте правильность идентификатора объекта и существует ли он до сих пор.
- Оптимизация вызовов RPC Пакетная обработка запросов: используйте MultiGetObjects для получения нескольких объектов за один вызов.
Кэширование: используйте React Query или SWR для кэширования ответов RPC:
ts
import { useSuiClientQuery } from '@mysten/dapp-kit';
const { data } = useSuiClientQuery('getObject', {
id: objectId,
options: { showContent: true },
});
Разбиение на страницы: для больших наборов данных используйте Suix_GetDynamicFields с курсорами.
- Обновления в реальном времени Используйте 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); },
});
Советы профессионалов
- Используйте @mysten /dapp-kit для готовых крючков для кошельков.
- Установите индивидуальный бюджет на газ для сложных транзакций.
- Отслеживайте состояние RPC — переключайте конечные точки, если ответы поступают медленно.
- Протестируйте в тестовой сети перед развертыванием основной сети.
###1. Рекомендуемая инициализация SDK
Для dApp производственного уровня React или Next.js рекомендуемый стек включает три пакета ключей. Эта настройка отделяет низкоуровневое взаимодействие с блокчейном от управления состоянием приложения. [1, 2, 3]
*Основные библиотеки:
*@mysten/sui.js
: Базовый TypeScript SDK для всех прямых сетевых взаимодействий 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 и повысить производительность, используйте комбинацию пакетной обработки, разбиения на страницы и кеширования.
***Пакетная обработка**: вместо поочередного извлечения объектов используйте для `sui_multiGetObjects`извлечения данных до 50 идентификаторов объектов за один запрос. Это значительно снижает сетевой трафик.
`suix_getDynamicFields`***Разбиение на страницы**: для больших наборов данных, таких как динамические поля объекта, используйте конечные точки с разбиением на страницы, например. Эти конечные точки используют курсор для загрузки данных страницу за страницей, предотвращая тайм-ауты.
***Кэширование**: функция `useSuiClientQuery``@mysten/dapp-kit`автоматического кэширования ответов. [1, 5] Для дальнейшей оптимизации задайте значение для данных, `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`with a, `refetchInterval`чтобы периодически запрашивать обновления в сети. Это подходит для некритических данных, для которых допустима задержка в несколько секунд. [17]
2.**Подписки WebSocket**: этот метод обеспечивает обновления в реальном времени с малой задержкой. `client.subscribeEvent`Однако официальный API Sui JSON-RPC WebSocket устарел, поэтому вам следует обратиться к стороннему поставщику RPC, предлагающему поддержку WebSocket. [18, 19] Его можно использовать `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]
Знаете ответ?
Пожалуйста, войдите в систему и поделитесь им.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Заработай свою долю из 1000 Sui
Зарабатывай очки репутации и получай награды за помощь в развитии сообщества Sui.

- ... SUIBigSneh+1396
- ... SUISuiLover+1333
- ... SUI0xduckmove+1207
- ... SUIThorfin+1202
- ... SUIPaul+1030
- ... SUIOwen+980
- ... SUIharry phan+847
- Почему BCS требует точного порядка полей для десериализации, когда структуры Move содержат именованные поля?53
- «Ошибки проверки нескольких источников» в публикациях модуля Sui Move — автоматическое устранение ошибок43
- Сбой транзакции Sui: объекты, зарезервированные для другой транзакции25
- Как ограничения возможностей взаимодействуют с динамическими полями в гетерогенных коллекциях?05