Publicación
Comparte tu conocimiento.
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
Respuestas
2Respuesta de un experto:
- Inicialización del SDK de Sui El SDK @mysten /sui.js debe configurarse con un punto final de RPC confiable. Para las aplicaciones de producción, tenga en cuenta lo siguiente:
RPC predeterminados:
ts
import { SuiClient, getFullnodeUrl } from '@mysten/sui.js/client';
const client = new SuiClient({ url: getFullnodeUrl('mainnet') });
RPC alternativos: utiliza servicios como Sui RPC Providers para evitar los límites de velocidad.
Para la integración de monederos, usa @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>
);
}
- Manejo de transacciones y errores Incluya siempre las transacciones en la gestión de errores:
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)
}
Errores comunes:
«El usuario rechazó la solicitud» → Se cerró la ventana emergente de la billetera.
«Se ha superado el presupuesto de gas» → Aumente el presupuesto de gas con txBlock.setGasBudget ().
«Objeto no encontrado» → Compruebe si el ID del objeto es correcto y aún existe.
- Optimización de las llamadas RPC Solicitudes por lotes: utilice MultiGetObjects para obtener varios objetos en una llamada.
Almacenamiento en caché: utilice React Query o SWR para almacenar en caché las respuestas de RPC:
ts
import { useSuiClientQuery } from '@mysten/dapp-kit';
const { data } = useSuiClientQuery('getObject', {
id: objectId,
options: { showContent: true },
});
Paginación: para conjuntos de datos grandes, utilice suix_getDynamicFields con cursores.
- Actualizaciones en tiempo real Usa WebSockets para sondear:
Suscripciones a WebSocket (avanzadas):
ts
const unsubscribe = client.subscribeEvent({
filter: { sender: '0x123...' },
onMessage(event) { console.log("New event:", event); },
});
//Limpieza al desmontar return () => cancelar la suscripción (); Sondeos con Hooks:
ts
useSuiClientSubscription('subscribeEvent', {
filter: { eventType: 'ExampleEvent' },
onData(event) { console.log("Event:", event); },
});
Consejos profesionales
- Usa @mysten /dapp-kit para los ganchos de billetera prediseñados.
- Establezca un presupuesto de gas personalizado para transacciones complejas.
- Supervise el estado de la RPC: cambie de punto final si las respuestas son lentas.
- Realice una prueba en Testnet antes de la implementación de la red principal.
1. Inicialización del SDK recomendada**
Para una dApp de React o Next.js de nivel de producción, la pila recomendada combina tres paquetes clave. Esta configuración separa la interacción de cadena de bloques de bajo nivel de la administración del estado de las aplicaciones. [1, 2, 3]
*Bibliotecas principales:
*@mysten/sui.js
: El SDK de TypeScript fundamental para todas las interacciones directas de la red Sui. [4]
*@mysten/dapp-kit
: La biblioteca principal de React con ganchos y componentes para la conexión con monederos y la obtención de datos. [2, 5, 6]
*@tanstack/react-query
: Una dependencia necesaria para gestionar el almacenamiento en @mysten/dapp-kit
caché, la recuperación y la gestión de los datos en cadena según el estado del servidor. [1, 7]
*Configuración del proveedor: Incluye el componente raíz de tu aplicación con estos proveedores en el orden correcto para garantizar que todos los enlaces funcionen correctamente. [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. Gestión eficiente de errores**
Manejar los errores de forma eficaz es crucial para la experiencia del usuario. A continuación, se explica cómo gestionar los problemas comunes.
***Fallos de conexión con la billetera**: El hecho de que la dirección de una billetera no esté disponible inmediatamente después de la conexión suele ser un problema de estado asincrónico.
`account``useCurrentAccount()`***Solución**: Compruebe siempre si el objeto devuelto por el gancho es nulo. Cuando obtengas datos que dependan de la dirección, usa la `enabled:!!account`opción in `useSuiClientQuery`para evitar que la consulta se ejecute hasta que la dirección esté disponible. [3]
***Errores de transacción**: los errores de RPC sin procesar suelen ser crípticos. Usa la `suiclient-error-decoder`biblioteca para traducirlos en mensajes legibles por humanos. [8, 9]
***Estrategia**: coordínate con tu desarrollador de contratos inteligentes para definir un mapa de códigos de error. `try...catch`En tu interfaz, usa este mapa con el decodificador para analizar los errores detectados en un bloque.
<!-- 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);
}
}
```
***Errores comunes**:
*`"User rejected the request"`: El usuario cerró la ventana emergente del monedero. [10, 11]
*`"InsufficientGas"`: El presupuesto de gas era demasiado bajo. Deja que el monedero establezca automáticamente el presupuesto; evita configurarlo manualmente a menos que sea necesario.
###**3. Optimización de consultas**
Para evitar los límites de velocidad de RPC y mejorar el rendimiento, utilice una combinación de procesamiento por lotes, paginación y almacenamiento en caché.
***Procesamiento por lotes**: en lugar de buscar los objetos uno por uno, utilízalo `sui_multiGetObjects`para recuperar datos de hasta 50 ID de objetos en una sola solicitud. Esto reduce considerablemente el tráfico de red.
`suix_getDynamicFields`***Paginación**: para conjuntos de datos grandes, como los campos dinámicos de un objeto, utilice puntos finales paginados como. Estos puntos finales utilizan un cursor para buscar los datos página por página, lo que evita que se agoten los tiempos de espera.
***Almacenamiento en caché**: el `useSuiClientQuery`enlace `@mysten/dapp-kit`almacena automáticamente las respuestas en caché. [1, 5] Para optimizar aún más, defina una opción para los `staleTime`datos que no cambien con frecuencia (por ejemplo, los metadatos de NFT). Esto le indica a React Query que sirva los datos en caché durante un tiempo específico antes de volver a recuperarlos, lo que reduce las llamadas de RPC redundantes. [7, 12, 13]
```typescript
const { data } = useSuiClientQuery(
'getObject',
{ id: objectId, options: { showContent: true } },
{ staleTime: 10 * 60 * 1000 } // Cache is fresh for 10 minutes
);
```
***Proveedores de RPC**: Para las aplicaciones de producción, usa un proveedor de RPC dedicado como QuickNode, Ankr o Chainstack para garantizar la confiabilidad y evitar los estrictos límites de velocidad de los puntos finales públicos. [14, 15, 16]
###**4. Actualizaciones en tiempo real**
Hay tres métodos principales para escuchar los eventos de la cadena, cada uno con diferentes ventajas y desventajas.
1.**Encuesta**: el método más simple. `useSuiClientQuery`Utilícelo con un `refetchInterval`para solicitar actualizaciones periódicamente a la red. Esto es adecuado para datos que no son críticos, en los que es aceptable un retraso de unos segundos. [17]
2.**Suscripciones a WebSocket**: este método ofrece actualizaciones en tiempo real y de baja latencia. `client.subscribeEvent`Sin embargo, la API oficial de WebSocket de Sui JSON-RPC está en desuso, por lo que debes usar un proveedor de RPC externo que ofrezca soporte para WebSocket. [18, 19] Puedes usarla `useEffect`para escuchar eventos específicos y debes gestionar el ciclo de vida de la suscripción con cuidado dentro de un React Hook para evitar pérdidas de memoria. [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.**Indizador personalizado**: la solución más potente y fiable para aplicaciones de misión crítica. Un indexador es un servicio de backend dedicado que procesa todos los datos de la cadena y los almacena en una base de datos optimizada. Esto permite realizar consultas complejas y de baja latencia que no son posibles con la API de RPC estándar. Este enfoque se recomienda para plataformas DeFi, juegos o análisis de nivel de producción. [9, 23, 24]
Sabes la respuesta?
Inicie sesión y compártalo.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Gana tu parte de 1000 Sui
Gana puntos de reputación y obtén recompensas por ayudar a crecer a la comunidad de Sui.

- ... SUIBigSneh+1396
- ... SUISuiLover+1333
- ... SUI0xduckmove+1207
- ... SUIThorfin+1202
- ... SUIPaul+1030
- ... SUIOwen+980
- ... SUIharry phan+847
- ¿Por qué BCS requiere un orden de campo exacto para la deserialización cuando las estructuras Move tienen campos con nombre?53
- «Errores de verificación de múltiples fuentes» en las publicaciones del módulo Sui Move: resolución automática de errores43
- Fallo en la transacción Sui: objetos reservados para otra transacción25
- ¿Cómo interactúan las restricciones de capacidad con los campos dinámicos en colecciones heterogéneas?05