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

Custom Adapters

You can create custom adapters by implementing the SignerAdapter interface or extending BaseSignerAdapter.

Extending BaseSignerAdapter

BaseSignerAdapter handles common boilerplate — account list management, change notifications, and cleanup. You only need to implement the initialization and key management logic.

import { BaseSignerAdapter, buildManagedAccount } from '@mysten/dev-wallet/adapters';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import type { ManagedAccount, CreateAccountOptions } from '@mysten/dev-wallet';

class LocalStorageAdapter extends BaseSignerAdapter {
	readonly id = 'local-storage';
	readonly name = 'LocalStorage';

	async initialize(): Promise<void> {
		const stored = localStorage.getItem('dev-wallet-keys');
		if (!stored) return;

		const entries: Array<{ secret: string; label: string }> = JSON.parse(stored);
		const accounts = entries.map((entry) => {
			// secret is a Bech32-encoded private key from getSecretKey()
			const keypair = Ed25519Keypair.fromSecretKey(entry.secret);
			const address = keypair.getPublicKey().toSuiAddress();
			return buildManagedAccount(keypair, address, entry.label);
		});

		this.setInitialAccounts(accounts);
	}

	async createAccount(options?: CreateAccountOptions): Promise<ManagedAccount> {
		const keypair = new Ed25519Keypair();
		const address = keypair.getPublicKey().toSuiAddress();
		const label = options?.label ?? `Account ${this.getAccounts().length + 1}`;
		const account = buildManagedAccount(keypair, address, label);
		this.addAccount(account);
		this.persist();
		return account;
	}

	async removeAccount(address: string): Promise<boolean> {
		const removed = this.removeAccountByAddress(address);
		if (removed) this.persist();
		return removed;
	}

	private persist(): void {
		const data = this.getAccounts().map((acc) => ({
			secret: (acc.signer as Ed25519Keypair).getSecretKey(),
			label: acc.label,
		}));
		localStorage.setItem('dev-wallet-keys', JSON.stringify(data));
	}
}

Using Your Custom Adapter

import { DevWallet } from '@mysten/dev-wallet';

const adapter = new LocalStorageAdapter();
await adapter.initialize();

const wallet = new DevWallet({
	adapters: [adapter],
});

BaseSignerAdapter Helper Methods

MethodDescription
setInitialAccounts(accounts)Set the initial account list during initialize()
addAccount(account)Add a ManagedAccount and notify listeners
removeAccountByAddress(address)Remove an account and notify listeners
replaceAccount(address, account)Replace an account (e.g., after rename)
_performRename(address, label)Rename by rebuilding the account with a new label
notifyListeners()Manually trigger account change notifications

The ManagedAccount Interface

interface ManagedAccount {
	address: string; // Sui address
	label: string; // Human-readable name
	signer: Signer; // Can sign transactions and messages
	walletAccount: ReadonlyWalletAccount; // Wallet-standard account
}

On this page