Sui.

Beitrag

Teile dein Wissen.

Evgeniy CRYPTOCOIN.
Jun 26, 2025
Experten Q&A

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
Teilen
Kommentare
.

Antworten

2
Benjamin XDV.
Jun 30 2025, 18:13

Expertenantwort:

  1. Initialisierung des Sui SDK Das @mysten /sui.js SDK sollte mit einem zuverlässigen RPC-Endpunkt konfiguriert werden. Beachten Sie bei Produktions-Apps Folgendes:

Standard-RPCs:

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

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

Fallback-RPCs: Verwenden Sie Dienste wie Sui RPC Providers, um Ratenbeschränkungen zu umgehen.

Verwenden Sie für die Wallet-Integration @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. Umgang mit Transaktionen und Fehlern Schließen Sie Transaktionen immer in die Fehlerbehandlung ein:

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)  
}  

Häufige Fehler:

„Der Benutzer hat die Anfrage abgelehnt“ → Das Wallet-Popup wurde geschlossen.

„Gasbudget überschritten“ → Erhöhen Sie das Gasbudget mit txBlock.setGasBudget ().

„Objekt nicht gefunden“ → Prüfen Sie, ob die Objekt-ID korrekt ist und noch existiert.

  1. Optimierung von RPC-Aufrufen Batch-Anfragen: Verwenden Sie MultiGetObjects, um mehrere Objekte in einem Aufruf abzurufen.

Caching: Verwenden Sie React Query oder SWR, um RPC-Antworten zwischenzuspeichern:

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

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

Paginierung: Verwenden Sie für große Datensätze SUIX_GetDynamicFields mit Cursorn.

  1. Aktualisierungen in Echtzeit Verwenden Sie WebSockets oder Polling:

WebSocket-Abonnements (fortgeschritten):

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

//Beim Unmounten aufräumen return () => unsubscribe (); Abfragen mit Hooks:

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

Tipps für Profis

  1. Verwenden Sie @mysten /dapp-kit für vorgefertigte Wallet-Hooks.
  2. Legen Sie ein benutzerdefiniertes Gasbudget für komplexe Transaktionen fest.
  3. Überwachen Sie den RPC-Zustand — wechseln Sie die Endpunkte, wenn die Antworten langsam sind.
  4. Testen Sie vor der Mainnet-Bereitstellung auf Testnet.
5
Beste Antwort
Kommentare
.
HaGiang.
Jun 30 2025, 05:57

###1. Empfohlene SDK-Initialisierung

Für eine React- oder Next.js -DApp in Produktionsqualität kombiniert der empfohlene Stack drei Schlüsselpakete. Dieses Setup trennt die Blockchain-Interaktion auf niedriger Ebene von der Verwaltung des Anwendungsstatus. [1, 2, 3]

*Kernbibliotheken:

*@mysten/sui.js: Das grundlegende TypeScript-SDK für alle direkten Sui-Netzwerkinteraktionen. [4] *@mysten/dapp-kit: Die primäre React-Bibliothek mit Hooks und Komponenten für die Wallet-Verbindung und das Abrufen von Daten. [2, 5, 6] *@tanstack/react-query: Eine dafür erforderliche Abhängigkeit @mysten/dapp-kitübernimmt das Caching, das erneute Abrufen und die Verwaltung von On-Chain-Daten als Serverstatus. [1, 7]

*Anbieter-Setup: Binden Sie die Root-Komponente Ihrer Anwendung mit diesen Providern in der richtigen Reihenfolge ein, um sicherzustellen, dass alle Hooks ordnungsgemäß funktionieren. [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. Anspruchsvolle Fehlerbehandlung**

Der effektive Umgang mit Fehlern ist entscheidend für die Benutzererfahrung. Hier erfahren Sie, wie Sie häufig auftretende Probleme lösen können.

***Fehler bei der Wallet-Verbindung**: Das Problem, dass eine Wallet-Adresse nicht sofort nach dem Verbindungsaufbau verfügbar ist, ist in der Regel ein asynchrones Statusproblem.

`account``useCurrentAccount()`***Lösung**: Prüfen Sie immer, ob das vom Hook zurückgegebene Objekt Null ist. Wenn Sie Daten abrufen, die von der Adresse abhängen, verwenden Sie die `enabled:!!account`Option in, `useSuiClientQuery`um zu verhindern, dass die Abfrage ausgeführt wird, bis die Adresse verfügbar ist. [3]

***Transaktionsfehler**: RPC-Rohfehler sind oft kryptisch. Benutze die `suiclient-error-decoder`Bibliothek, um sie in menschenlesbare Nachrichten zu übersetzen. [8, 9]

***Strategie**: Stimmen Sie sich mit Ihrem Smart-Contract-Entwickler ab, um eine Karte mit Fehlercodes zu definieren. `try...catch`Verwenden Sie diese Map in Ihrem Frontend zusammen mit dem Decoder, um Fehler zu analysieren, die in einem Block aufgetreten sind.

<!-- 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); 
     }
   }
   ```

***Häufige Fehler**:
*`"User rejected the request"`: Der Benutzer hat das Wallet-Popup geschlossen. [10, 11]
*`"InsufficientGas"`: Das Gasbudget war zu niedrig. Lassen Sie das Budget von der Wallet automatisch festlegen. Vermeiden Sie es, es manuell festzulegen, es sei denn, dies ist erforderlich.

###**3. Optimieren von Abfragen**

Verwenden Sie eine Kombination aus Batching, Paginierung und Caching, um RPC-Ratenbeschränkungen zu umgehen und die Leistung zu verbessern.

***Batching**: Anstatt Objekte einzeln abzurufen, verwenden Sie diese Option, um `sui_multiGetObjects`Daten für bis zu 50 Objekt-IDs in einer einzigen Anfrage abzurufen. Dadurch wird der Netzwerkverkehr erheblich reduziert.

`suix_getDynamicFields`***Paginierung**: Verwenden Sie für große Datensätze wie die dynamischen Felder eines Objekts paginierte Endpunkte wie. Diese Endpunkte verwenden einen Cursor, um Daten Seite für Seite abzurufen und so Timeouts zu vermeiden.

***Caching**: Der `useSuiClientQuery`Hook von `@mysten/dapp-kit`speichert Antworten automatisch im Cache. [1, 5] Zur weiteren Optimierung setzen Sie a `staleTime`für Daten, die sich nicht häufig ändern (z. B. NFT-Metadaten). Dadurch wird React Query angewiesen, zwischengespeicherte Daten für eine bestimmte Dauer bereitzustellen, bevor sie erneut abgerufen werden, wodurch redundante RPC-Aufrufe reduziert werden. [7, 12, 13]

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

***RPC-Anbieter**: Verwenden Sie für Produktionsanwendungen einen dedizierten RPC-Anbieter wie QuickNode, Ankr oder Chainstack, um die Zuverlässigkeit zu gewährleisten und die strengen Ratenbeschränkungen öffentlicher Endpunkte zu vermeiden. [14, 15, 16]

###**4. Aktualisierungen**in Echtzeit**

Es gibt drei Hauptmethoden zum Abhören von On-Chain-Ereignissen, die jeweils mit unterschiedlichen Kompromissen verbunden sind.

1.**Polling**: Die einfachste Methode. Verwenden Sie `useSuiClientQuery`zusammen mit a`refetchInterval`, um das Netzwerk regelmäßig nach Updates zu fragen. Dies ist für unkritische Daten geeignet, bei denen eine Verzögerung von einigen Sekunden akzeptabel ist. [17]

2.**WebSocket-Abonnements**: Diese Methode bietet Aktualisierungen in Echtzeit mit niedriger Latenz. `client.subscribeEvent`Die offizielle Sui JSON-RPC WebSocket-API ist jedoch veraltet, daher musst du einen RPC-Drittanbieter verwenden, der WebSocket-Unterstützung anbietet. [18, 19] Du kannst sie verwenden, um auf `useEffect`bestimmte Ereignisse zu warten und musst den Abonnement-Lebenszyklus innerhalb eines React-Hooks sorgfältig verwalten, um Speicherlecks zu verhindern. [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**: Die leistungsstärkste und zuverlässigste Lösung für unternehmenskritische Anwendungen. Ein Indexer ist ein dedizierter Backend-Service, der alle On-Chain-Daten verarbeitet und in einer optimierten Datenbank speichert. Dies ermöglicht komplexe Abfragen mit niedriger Latenz, die mit der Standard-RPC-API nicht möglich sind. Dieser Ansatz wird für DeFi-, Gaming- oder Analyseplattformen in Produktionsqualität empfohlen. [9, 23, 24]
3
Kommentare
.

Weißt du die Antwort?

Bitte melde dich an und teile sie.

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

610Beiträge1423Antworten
Sui.X.Peera.

Verdiene deinen Anteil an 1000 Sui

Sammle Reputationspunkte und erhalte Belohnungen für deine Hilfe beim Wachstum der Sui-Community.

BelohnungskampagneJuli