UNPKG

@mysten/sui

Version:
351 lines (270 loc) 12.6 kB
# @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 ```