@mysten/sui v2.0 and a new dApp Kit are here! Check out the migration guide
Mysten Labs SDKs
Reference

React Integration

Dev Wallet provides React hooks, a context provider, and React-wrapped Lit components.

useDevWallet Hook

The primary hook that initializes a DevWallet, registers it with wallet-standard, and optionally mounts the UI:

import { useDevWallet } from '@mysten/dev-wallet/react';
import { WebCryptoSignerAdapter } from '@mysten/dev-wallet/adapters';
import { useMemo } from 'react';

function App() {
	const adapters = useMemo(() => [new WebCryptoSignerAdapter()], []);

	const { wallet, error, loading } = useDevWallet({
		adapters,
		createInitialAccount: true,
		mountUI: true,
		autoConnect: true,
	});

	if (loading) return <div>Loading...</div>;
	if (error) return <div>Error: {error.message}</div>;

	return <div>{wallet?.accounts.length} accounts ready</div>;
}

Options

OptionTypeDefaultDescription
adaptersSignerAdapter[]requiredSigner adapters to use
networksRecord<string, string>Default URLsNetwork name → gRPC URL map
namestring'Dev Wallet'Display name
iconWalletIconBuilt-in iconData URI icon
activeNetworkstringFirst networkInitially active network
autoApproveboolean | functionfalseAuto-approval policy
autoConnectbooleanfalseSkip account picker on connect
autoInitializebooleantrueCall adapter.initialize() automatically
createInitialAccountbooleantrueCreate an account if none exist
mountUIbooleantrueMount the floating wallet panel
containerHTMLElementdocument.bodyWhere to mount the panel
clientFactoryfunctionSuiGrpcClientFactory for creating clients

Return Value

{
	wallet: DevWallet | null; // null during initialization
	error: Error | null; // initialization error, if any
	loading: boolean; // true while initializing
}

Stable adapter references required. Create adapters outside your component or wrap them in useMemo. Recreating adapters on every render causes infinite re-initialization.

DevWalletProvider

Share the wallet instance across your component tree via React context:

import { DevWalletProvider, useDevWalletInstance } from '@mysten/dev-wallet/react';

function App() {
	const { wallet, loading } = useDevWallet({ adapters, mountUI: true });

	if (loading || !wallet) return <div>Loading...</div>;

	return (
		<DevWalletProvider wallet={wallet}>
			<ChildComponent />
		</DevWalletProvider>
	);
}

function ChildComponent() {
	const wallet = useDevWalletInstance();
	// wallet is the DevWallet instance
}

React-Wrapped Lit Components

These React components wrap the underlying Lit Web Components using @lit/react:

import {
	DevWalletPanel,
	DevWalletAccounts,
	DevWalletBalances,
	DevWalletNewAccount,
	DevWalletSigning,
} from '@mysten/dev-wallet/react';
ComponentDescription
<DevWalletPanel>Full floating panel with sidebar
<DevWalletAccounts>Account list and management
<DevWalletBalances>Coin balances display
<DevWalletNewAccount>Account creation form
<DevWalletSigning>Signing request approval UI

All components accept a wallet prop:

<DevWalletPanel wallet={wallet} />

Next.js

All components from @mysten/dev-wallet/react require browser APIs (DOM, Web Components). In Next.js, use dynamic imports with SSR disabled:

import dynamic from 'next/dynamic';

const WalletSetup = dynamic(() => import('./WalletSetup'), { ssr: false });

Full dApp Kit Integration

The recommended approach uses devWalletInitializer to register the wallet through dApp Kit's plugin system. The wallet automatically uses dApp Kit's networks and clients:

import { createDAppKit, DAppKitProvider } from '@mysten/dapp-kit-react';
import { ConnectButton } from '@mysten/dapp-kit-react/ui';
import { devWalletInitializer } from '@mysten/dev-wallet';
import { InMemorySignerAdapter, WebCryptoSignerAdapter } from '@mysten/dev-wallet/adapters';
import { SuiGrpcClient } from '@mysten/sui/grpc';

const dAppKit = createDAppKit({
	networks: ['devnet', 'testnet'],
	createClient: (network) =>
		new SuiGrpcClient({
			network,
			baseUrl: `https://fullnode.${network}.sui.io:443`,
		}),
	walletInitializers: [
		devWalletInitializer({
			adapters: [new WebCryptoSignerAdapter(), new InMemorySignerAdapter()],
			autoConnect: true,
			mountUI: true,
		}),
	],
});

declare module '@mysten/dapp-kit-react' {
	interface Register {
		dAppKit: typeof dAppKit;
	}
}

function App() {
	return (
		<DAppKitProvider dAppKit={dAppKit}>
			<header>
				<ConnectButton />
			</header>
			<main>{/* Your app content — Dev Wallet appears in the wallet picker */}</main>
		</DAppKitProvider>
	);
}

If you need programmatic access to the DevWallet instance (e.g. for custom approval UIs), use the onWalletCreated callback:

let devWallet: DevWallet;

const dAppKit = createDAppKit({
	// ...
	walletInitializers: [
		devWalletInitializer({
			adapters: [new WebCryptoSignerAdapter()],
			onWalletCreated: (wallet) => {
				devWallet = wallet;
			},
		}),
	],
});

Using useDevWallet Instead

For finer-grained control within React components, you can still use the useDevWallet hook directly. This is useful when you need the wallet instance in React state or want to manage the wallet lifecycle within a component:

import { useDevWallet } from '@mysten/dev-wallet/react';
import { InMemorySignerAdapter, WebCryptoSignerAdapter } from '@mysten/dev-wallet/adapters';
import { useMemo } from 'react';

function App() {
	const adapters = useMemo(() => [new WebCryptoSignerAdapter(), new InMemorySignerAdapter()], []);

	const { wallet, error, loading } = useDevWallet({
		adapters,
		createInitialAccount: true,
		mountUI: true,
		autoConnect: true,
	});

	// wallet instance available for programmatic use
}

On this page