@mysten/sui
Version:
Sui TypeScript API
351 lines (270 loc) • 12.6 kB
Markdown
# @mysten/dapp-kit
> Migrate @mysten/dapp-kit to 2.0
This guide helps you migrate from the original `@mysten/dapp-kit` (legacy) to the new
`@mysten/dapp-kit-react` package.
> **Note:** The legacy `@mysten/dapp-kit` package will continue to work with the latest SDK, but it
> only supports JSON-RPC and will not receive further updates. We recommend migrating to
> `@mysten/dapp-kit-react` for new features and gRPC support.
## Overview
The new dApp Kit SDK represents a complete rewrite with these key changes:
- **Framework agnostic**: Split into `@mysten/dapp-kit-core` (framework-agnostic) and
`@mysten/dapp-kit-react` (React bindings)
- **No React Query dependency**: Direct promise-based API instead of mutation hooks
- **Web Components**: UI components built with Lit Elements for cross-framework compatibility
- **Smaller bundle size**: No React Query dependency, lighter state management with nanostores
- **Better SSR support**: Compatible with SSR frameworks like Next.js
- **Cross-framework compatibility**: Core functionality can be used in vanilla JS, Vue, React, and
other frameworks
## Step-by-Step Migration
### 1. Update Dependencies
Remove the old package and install the new ones:
```bash
npm uninstall @mysten/dapp-kit
npm i @mysten/dapp-kit-react @mysten/dapp-kit-core @mysten/sui
```
### 2. Create dApp Kit Instance
Create a new instance of the dApp Kit using the `createDAppKit` function and register the global
type.
```tsx
// dapp-kit.ts
const GRPC_URLS = {
testnet: 'https://fullnode.testnet.sui.io:443',
};
networks: ['testnet'],
createClient(network) {
return new SuiGrpcClient({ network, baseUrl: GRPC_URLS[network] });
},
});
// global type registration necessary for the hooks to work correctly
declare module '@mysten/dapp-kit-react' {
interface Register {
dAppKit: typeof dAppKit;
}
}
```
### 3. Register Types
The `declare module` block in the previous step registers your dApp Kit instance's type globally.
This enables all hooks like `useDAppKit()`, `useCurrentNetwork()`, and `useCurrentClient()` to
automatically infer the correct types based on your configuration (e.g., your specific networks and
client type).
```tsx
declare module '@mysten/dapp-kit-react' {
interface Register {
dAppKit: typeof dAppKit;
}
}
```
Without this registration, hooks return generic types and you lose type safety for things like
network names. If you prefer not to use global type registration, you can pass the `dAppKit`
instance explicitly to each hook instead:
```tsx
const connection = useWalletConnection({ dAppKit });
const network = useCurrentNetwork({ dAppKit });
```
### 4. Replace Provider Setup
Replace the nested dApp Kit providers with a single unified provider. You can keep your existing
`QueryClientProvider` for data fetching.
```diff
// App.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
- import { SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
+ import { DAppKitProvider } from '@mysten/dapp-kit-react';
+ import { dAppKit } from './dapp-kit.ts';
export function App() {
const queryClient = new QueryClient();
- const networkConfig = {
- mainnet: { url: 'https://mainnet.sui.io:443' },
- testnet: { url: 'https://testnet.sui.io:443' },
- };
return (
<QueryClientProvider client={queryClient}>
- <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
- <WalletProvider>
- <App />
- </WalletProvider>
- </SuiClientProvider>
+ <DAppKitProvider dAppKit={dAppKit}>
+ <App />
+ </DAppKitProvider>
</QueryClientProvider>
);
}
```
### 5. Configuration Option Changes
The `createDAppKit` function has different configuration options than the old `WalletProvider`:
| Old (`WalletProvider`) | New (`createDAppKit`) | Notes |
| ---------------------- | --------------------- | -------------------------------------------------------------------- |
| - | `networks` (required) | List of network identifiers your app supports |
| - | `createClient` | Function to create a client for each network |
| - | `defaultNetwork` | Network to use by default (defaults to first in `networks`) |
| `autoConnect` (false) | `autoConnect` (true) | Default changed from `false` to `true` |
| `enableUnsafeBurner` | `enableBurnerWallet` | Renamed |
| `slushWallet` | `slushWalletConfig` | Renamed |
| `storage` | `storage` | Unchanged |
| `storageKey` | `storageKey` | Unchanged |
| `preferredWallets` | - | Removed |
| `walletFilter` | - | Removed (wallets filtered by network compatibility) |
| `theme` | - | Removed (UI components are now web components with built-in styling) |
| - | `walletInitializers` | New option for registering custom wallets |
### 6. Update Hook Usage
The new dApp Kit has a dramatically simplified hook API. Most hooks from the original version have
been replaced with direct action calls through `useDAppKit()`.
**Available hooks in the new version:**
- `useDAppKit()` - Access the dAppKit instance for calling actions
- `useCurrentClient()` - Get the blockchain client (renamed from `useSuiClient`)
- `useCurrentAccount()` - Get the current connected account
- `useCurrentWallet()` - Get the current connected wallet
- `useWallets()` - Get the list of available wallets
- `useWalletConnection()` - Get the current wallet connection status
- `useCurrentNetwork()` - Get the current network
**Removed hooks:**
All wallet action hooks have been replaced with direct action calls via `useDAppKit()`:
- `useConnectWallet` -> Use `dAppKit.connectWallet()`
- `useDisconnectWallet` -> Use `dAppKit.disconnectWallet()`
- `useSignTransaction` -> Use `dAppKit.signTransaction()`
- `useSignAndExecuteTransaction` -> Use `dAppKit.signAndExecuteTransaction()`
- `useSignPersonalMessage` -> Use `dAppKit.signPersonalMessage()`
- `useSwitchAccount` -> Use `dAppKit.switchAccount()`
All data fetching hooks have been removed (giving you flexibility to use your preferred solution):
- `useSuiClientQuery` -> Use `useCurrentClient()` with your data fetching solution
- `useSuiClientMutation` -> Use `useCurrentClient()` with your data fetching solution
- `useSuiClientInfiniteQuery` -> Use `useCurrentClient()` with your data fetching solution
- `useSuiClientQueries` -> Use `useCurrentClient()` with your data fetching solution
- `useResolveSuiNSNames` -> Use `useCurrentClient()` directly
Other removed hooks:
- `useAutoConnectWallet` -> Auto-connect is enabled by default
- `useAccounts` -> Use `useWalletConnection()` to access `connection.wallet.accounts`
- `useWalletStore` -> Use specific hooks like `useWalletConnection()` instead
### 7. Replace Mutation Patterns
The built-in mutation hooks have been removed. Use TanStack Query's `useMutation` with
`useDAppKit()` to get similar functionality.
**Chain parameter replaced with network:**
In the old dapp-kit, you could optionally pass a `chain` parameter (e.g., `sui:mainnet`) to methods
like `signTransaction` and `signAndExecuteTransaction`. In the new dapp-kit, use the `network`
parameter instead - the chain is automatically derived from the network.
```diff
- const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();
- await signAndExecute({ transaction, chain: 'sui:mainnet' });
+ const dAppKit = useDAppKit();
+ await dAppKit.signAndExecuteTransaction({ transaction, network: 'mainnet' });
```
**Mutation example:**
```diff
- import { useSignAndExecuteTransaction } from '@mysten/dapp-kit';
+ import { useMutation } from '@tanstack/react-query';
+ import { useDAppKit } from '@mysten/dapp-kit-react';
import type { Transaction } from '@mysten/sui/transactions';
export function ExampleComponent({ transaction }: { transaction: Transaction }) {
- const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();
+ const dAppKit = useDAppKit();
+
+ const { mutateAsync: signAndExecute } = useMutation({
+ mutationFn: (tx: Transaction) => dAppKit.signAndExecuteTransaction({ transaction: tx }),
+ });
const handleClick = async () => {
- await signAndExecute(
- { transaction },
- {
- onSuccess: (result: any) => console.log(result),
- onError: (error: any) => console.error(error),
- },
- );
+ await signAndExecute(transaction, {
+ onSuccess: (result) => console.log(result),
+ onError: (error) => console.error(error),
+ });
};
return <button onClick={handleClick}>Sign and Execute</button>;
}
```
**Alternative: Direct promise-based calls**
If you don't need React Query's state management, you can call `dAppKit` methods directly:
```tsx
const dAppKit = useDAppKit();
const handleClick = async () => {
try {
const result = await dAppKit.signAndExecuteTransaction({ transaction });
console.log(result);
} catch (error) {
console.error(error);
}
};
return <button onClick={handleClick}>Sign and Execute</button>;
}
```
### 8. Replace Data Fetching Patterns
The built-in data fetching hooks have been removed. Use TanStack Query's `useQuery` with
`useCurrentClient()` to get similar functionality:
```diff
- import { useSuiClientQuery } from '@mysten/dapp-kit';
+ import { useQuery } from '@tanstack/react-query';
+ import { useCurrentClient } from '@mysten/dapp-kit-react';
export function ExampleComponent({ objectId }: { objectId: string }) {
+ const client = useCurrentClient();
+
- const { data, isLoading, error } = useSuiClientQuery('getObject', {
- id: objectId,
- });
+ const { data, isLoading, error } = useQuery({
+ queryKey: ['object', objectId],
+ queryFn: () => client.core.getObject({ objectId }),
+ });
// ...
}
```
**Alternative: Direct data fetching**
If you don't need React Query's caching and state management, you can fetch data directly:
```tsx
const client = useCurrentClient();
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
client.core
.getObject({ objectId })
.then((result) => setData(result.object ?? null))
.catch((err) => setError(err.message))
.finally(() => setIsLoading(false));
}, [client, objectId]);
// ...
}
```
### 9. Update The Remaining Code
The following hooks from the original dApp Kit are not available anymore:
- `useSuiClientQuery` → Use `useQuery` from `@tanstack/react-query`
- `useSuiClientMutation` → Use `useMutation` from `@tanstack/react-query`
- `useSuiClientInfiniteQuery` → Use `useInfiniteQuery` from `@tanstack/react-query`
- `useResolveSuiNSNames` → Use `useCurrentClient()` with the suins extension
> **Warning:** The `reportTransactionEffects` feature is planned for deprecation in the
> [Wallet Standard](https://docs.sui.io/standards/wallet-standard) and so the dApp Kit provides no
> replacement.
The following have been removed:
- `useReportTransactionEffects` hook
- `reportTransactionEffects` callback from `useSignTransaction`
- Automatic transaction effects reporting from `useSignAndExecuteTransaction`
## CSS and Theming Changes
The new dApp Kit no longer bundles a CSS file. If you were importing the old CSS file, remove the
import:
```diff
- import '@mysten/dapp-kit/dist/full/index.css';
```
The new dApp Kit uses web components with built-in styling that can be customized using CSS custom
properties. See the [Theming documentation](/dapp-kit/theming) for details on customizing the
appearance of dApp Kit components.
**Quick theme setup:**
```css
:root {
--primary: #4f46e5;
--primary-foreground: #ffffff;
--background: #ffffff;
--foreground: #0f172a;
--border: #e2e8f0;
--radius: 0.5rem;
}
```
## Removing TanStack Query
If you were only using `@tanstack/react-query` for dApp Kit and don't need it for other parts of
your application, you can now remove it:
```bash
npm uninstall @tanstack/react-query
```