Beitrag
Teile dein Wissen.
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
Antworten
2Expertenantwort:
- 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>
);
}
- 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.
- 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.
- 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
- Verwenden Sie @mysten /dapp-kit für vorgefertigte Wallet-Hooks.
- Legen Sie ein benutzerdefiniertes Gasbudget für komplexe Transaktionen fest.
- Überwachen Sie den RPC-Zustand — wechseln Sie die Endpunkte, wenn die Antworten langsam sind.
- Testen Sie vor der Mainnet-Bereitstellung auf Testnet.
###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]
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.
Verdiene deinen Anteil an 1000 Sui
Sammle Reputationspunkte und erhalte Belohnungen für deine Hilfe beim Wachstum der Sui-Community.

- ... SUIBigSneh+1396
- ... SUISuiLover+1333
- ... SUI0xduckmove+1207
- ... SUIThorfin+1202
- ... SUIPaul+1030
- ... SUIOwen+970
- ... SUIharry phan+847
- Warum benötigt BCS eine genaue Feldreihenfolge für die Deserialisierung, wenn Move-Strukturen benannte Felder haben?53
- Fehler bei der Überprüfung mehrerer Quellen“ in den Veröffentlichungen des Sui Move-Moduls — Automatisierte Fehlerbehebung43
- Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert25
- Wie interagieren Fähigkeitsbeschränkungen mit dynamischen Feldern in heterogenen Sammlungen?05