Stake SUI with SDK
This tutorial provides a complete, end-to-end guide for building a simple web application that allows users to stake their SUI tokens directly from a browser wallet. We will delegate to the blockeden.xyz validator by interacting with the Sui blockchain using the official TypeScript SDK.
Why This Approach?
This method is designed with security and simplicity in mind, offering several key advantages for both developers and users:
- Zero Key Exposure: The user's private keys never leave their wallet. The wallet handles all cryptographic signing locally within its secure environment. Your application only constructs and requests a signature for a transaction, adhering to the best practices for non-custodial interactions.
- Universal Wallet Compatibility: By leveraging the
Sui Wallet Standard
, this approach works seamlessly with all major Sui wallets, including Sui Wallet, Suiet, Nightly, SafePal, and others. This frees you from writing wallet-specific code. - Reliable and Simple: The blockeden.xyz validator address is hard-coded into our application. This simplifies the logic and removes a potential point of failure or manipulation that could arise from fetching the address from an external, potentially compromised API.
Prerequisites
Before you start writing code, please ensure your development environment is set up with the following:
-
A funded Sui browser wallet: You'll need a browser extension wallet that supports the Sui Wallet Standard. Make sure it's funded with enough SUI to cover both the desired stake amount and the small network transaction fees (gas).
-
Node.js: You need Node.js version 18 or newer to run the TypeScript code and manage packages.
-
Sui Packages: Install the necessary Sui libraries using
npm
or your preferred package manager. Open your terminal and run:npm install @mysten/sui @mysten/dapp-kit
1. Set Up the Sui Client
The first step is to establish a connection to the Sui blockchain. We'll use the SuiClient
class from the @mysten/sui
library, which is our primary interface for reading data from the network.
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
// Initialize a client for the Sui Mainnet
export const client = new SuiClient({
url: getFullnodeUrl('mainnet'), // ← Switch to 'testnet' or 'devnet' if needed
});
This client instance will be used for tasks like fetching coin balances and querying stake information. Note that you can easily switch networks by changing the parameter to getFullnodeUrl('testnet')
or getFullnodeUrl('devnet')
for testing.
2. Discover and Connect to the User's Wallet
Next, your application needs to find and connect to the user's installed browser wallet. The @mysten/wallet-standard
library provides a standardized way to handle this discovery and connection process.
import {
getWallets,
SUI_MAINNET_CHAIN,
StandardConnectFeature,
SuiSignAndExecuteTransactionFeature,
WalletWithRequiredFeatures,
} from '@mysten/dapp-kit';
// Define a type for a wallet that has the features we need
type SuiWallet = WalletWithRequiredFeatures<
StandardConnectFeature & SuiSignAndExecuteTransactionFeature
>;
export async function connectWallet(): Promise<{
wallet: SuiWallet;
address: string;
}> {
// getWallets() scans the browser for all compatible wallets
const wallets = getWallets() as unknown as SuiWallet[];
if (!wallets.length) {
throw new Error('No Sui-compatible wallet found in the browser');
}
// In a real dApp, you would present a UI for the user to select a wallet.
// For simplicity, we'll just pick the first one found.
const wallet = wallets[0];
// Trigger the wallet's connection prompt
await wallet.features['standard:connect'].connect({
chains: [SUI_MAINNET_CHAIN], // Specify we are connecting to Mainnet
});
// Ensure the user has authorized at least one account
const account = wallet.accounts[0];
if (!account) {
throw new Error('Wallet connected but no account authorised');
}
return { wallet, address: account.address };
}
This connectWallet
function finds available wallets, prompts the user to connect, and returns the connected wallet instance and the user's public address.