Build React Apps on Sui with dApp Kit
Introducing a new SDK for developers to start building quickly and efficiently
Today Mysten Labs introduced dApp Kit, an all-in-one solution for developing React applications and decentralized applications (dApps) on Sui. The @mysten/dapp-kit
is a brand-new SDK tailored for React and designed to streamline essential tasks such as connecting to wallets, signing transactions, and fetching data from RPC nodes. dApp Kit offers both themeable, pre built components like
dApp kit is a distillation of lessons learned from Mysten Labs, created with a goal of making it easier for everyone to start building dApps. In fact, Mysten Labs is starting to use dApp kit across all their own dApps; from Sui Explorer to Sui Wallet, every app we built uses dApp kit. We are just getting started, but we are excited to share the kit, and help get it into the hands of more builders!
For comprehensive documentation on dApp Kit, check out the full docs. In this blog post, we will guide you through setting up dApp Kit in your React project.
Installation
To get started with dApp Kit, first install it along with react-query:
npm install --save @mysten/dapp-kit @mysten/sui.js @tanstack/react-query
With the packages installed, you need to set up some providers in the application to ensure that dApp Kit functions smoothly:
import '@mysten/dapp-kit/dist/index.css';
import { SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl } from '@mysten/sui.js/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
const networks = {
localnet: { url: getFullnodeUrl('localnet') },
devnet: { url: getFullnodeUrl('devnet') },
testnet: { url: getFullnodeUrl('testnet') },
mainnet: { url: getFullnodeUrl('mainnet') },
};
ReactDOM.createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}>
<SuiClientProvider networks={networks} defaultNetwork="devnet">
<WalletProvider>
<App />
</WalletProvider>
</SuiClientProvider>
</QueryClientProvider>,
);
In this code snippet, you:
- Import the necessary dApp Kit CSS for rendering components correctly.
- Set up a react-query provider to manage the state of requests made by dApp Kit.
- Initialize the SuiClientProvider, which provides an instance of SuiClient and manages the connected network.
- Configure the WalletProvider, responsible for managing wallet connections.
Now that the app is set up properly, you can dive into using dApp Kit's features.
Connecting a Wallet
To enable users to connect their Sui Wallet to the dApp, you can easily add a ConnectButton
:
import { ConnectButton } from '@mysten/dapp-kit';
function App() {
return (
<div>
<nav>
<ConnectButton />
</nav>
<section>Hello, world</section>
</div>
);
}
This code will render a Button that opens a Modal and prompts users to connect their wallet. Once connected, users will see their connected walle and have the option to disconnect their wallet again.
Managing Wallet State
dApp Kit provides a variety of hooks for managing wallet state. For instance, the useCurrentWallet
hook enables you to retrieve information about the user's connected account:
import { ConnectButton, useCurrentAccount } from '@mysten/dapp-kit';
function App() {
const account = useCurrentAccount();
return (
<div>
<nav>
<ConnectButton />
</nav>
<section>{account ? 'No wallet connected' : `Your address is ${account.address}`}</section>
</div>
);
}
This allows you to display relevant information based on the user's wallet status.
Fetching Data
dApp Kit also facilitates data fetching for the currently connected user. The useSuiClientQuery
hook can be used to call RPC methods. You can use getOwnedObjects
to access and display a list of objects owned by the connected account:
import { ConnectButton, useCurrentAccount } from '@mysten/dapp-kit';
function App() {
const account = useCurrentAccount();
return (
<div>
<nav>
<ConnectButton />
</nav>
<section>{account ? 'No wallet connected' : <OwnedObjects />}</section>
</div>
);
}
export function OwnedObjects() {
const account = useCurrentAccount()!;
const { data } = useSuiClientQuery('getOwnedObjects', { owner: account.address });
return (
<ul>
{data.data.map((object) => (
<li key={object.data?.objectId}>{object.data?.objectId}</li>
))}
</ul>
);
}
You can read more about the hooks available for making RPC calls in the docs.
Transaction Building
Many dApps require the ability to create and sign transaction blocks. dApp Kit simplifies this process with the useSignAndExecuteTransactionBlock
hook. Let's create a button that sends SUI to a predefined address:
import { signAndExecuteTransactionBlock } from '@mysten/dapp-kit';
import { TransactionBlock } from '@mysten/sui.js/transactions';
export function SendSui() {
const { mutateAsync: signAndExecuteTransactionBlock } = useSignAndExecuteTransactionBlock();
function sendMessage() {
const txb = new TransactionBlock();
const coin = txb.splitCoins(txb.gas, [10]);
txb.transferObjects([coin], 'Ox...');
signAndExecuteTransactionBlock({
transactionBlock: txb,
}).then(async (result) => {
alert('Sui sent successfully');
});
}
return <button onClick={() => sendMessage()}>Send me Sui!</button>;
}
When the button is pressed it will:
- Create a new
TransactionBlock
- Adds a
splitCoins
transaction that splits off SUI from the gas coin into a new coin - Adds a new
transferObject
transaction that transfers the new coin to another address - Signs and executes the
TransactionBlock
using the connected wallet - Triggers an
alert
to let you know when the transaction has been executed
And much more
dApp Kit has many more features to help you quickly and easily build dApps. For more details and advanced features, explore the full documentation.