ReferenceAdapters
Custom Adapters
Build your own signer adapter by extending BaseSignerAdapter or implementing the interface
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-incubation/dev-wallet/adapters';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import type { ManagedAccount, CreateAccountOptions } from '@mysten-incubation/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-incubation/dev-wallet';
const adapter = new LocalStorageAdapter();
await adapter.initialize();
const wallet = new DevWallet({
adapters: [adapter],
});BaseSignerAdapter helper methods
| Method | Description |
|---|---|
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
}