Wallet Kit
Wallet Standard

Wallet Standard

Browser extension wallets built for Sui are defined using the Wallet Standard (opens in a new tab). This is a cross-chain standard that defines how wallets can automatically be discovered and interacted with from dApps.

If you are building a wallet, we publish a helper library @mysten/wallet-standard which provides types and utilities that make it simple to get started.

Creating a wallet interface

You need to create a class that represents your wallet. You can use the Wallet interface from @mysten/wallet-standard to help ensure your class adheres to the standard.

import { SUI_DEVNET_CHAIN, Wallet } from '@mysten/wallet-standard';
 
class YourWallet implements Wallet {
	get version() {
		// Return the version of the Wallet Standard this implements (in this case, 1.0.0).
		return '1.0.0';
	}
	get name() {
		return 'Wallet Name';
	}
	get icon() {
		return 'some-icon-data-url';
	}
	// Return the Sui chains that your wallet supports.
	get chains() {
		return [SUI_DEVNET_CHAIN];
	}
}

Implementing features

Features are standard methods consumers can use to interact with a wallet. To be listed in the Sui wallet adapter, you must implement the following features in your wallet:

  • standard:connect - Used to initiate a connection to the wallet.
  • standard:events - Used to listen for changes that happen within the wallet, such as accounts being added or removed.
  • sui:signPersonalMessage - Used to prompt the user to sign a personal message, and return the message signature back to the dapp. This can be used to verify the user’s public key.
  • sui:signTransactionBlock - Used to prompt the user to sign a transaction block, and return the serialized transaction block and signature back to the dapp. This method does not submit the transaction block for execution.
  • sui:signAndExecuteTransactionBlock - Used to prompt the user to sign a transaction, then submit it for execution to the blockchain.

You can implement these features in your wallet class under the features property:

import {
  ConnectFeature,
  ConnectMethod,
  EventsFeature,
  EventsOnMethod,
  SuiFeatures,
  SuiSignPersonalMessageMethod,
  SuiSignTransactionBlockMethod,
  SuiSignAndExecuteTransactionBlockMethod
} from "@mysten/wallet-standard";
 
class YourWallet implements Wallet {
	/* ... existing code from above ... */
 
  get features(): ConnectFeature & EventsFeature & SuiFeatures {
    return {
      "standard:connect": {
        version: "1.0.0",
        connect: this.#connect,
      },
      "standard:events": {
        version: "1.0.0",
        on: this.#on,
      },
			"sui:signPersonalMessage": {
        version: "1.0.0",
				signPersonalMessage: this.#signPersonalMessage,
			},
      "sui:signTransactionBlock": {
        version: "1.0.0",
        signTransactionBlock: this.#signTransactionBlock,
      },
      "sui:signAndExecuteTransactionBlock": {
        version: "1.0.0",
        signAndExecuteTransactionBlock: this.#signAndExecuteTransactionBlock,
      },
    };
  },
 
  #on: EventsOnMethod = () => {
    // Your wallet's events on implementation.
  };
 
  #connect: ConnectMethod = () => {
    // Your wallet's connect implementation
  };
 
	#signPersonalMessage: SuiSignPersonalMessageMethod = () => {
    // Your wallet's signTransaction implementation
  };
 
  #signTransactionBlock: SuiSignTransactionBlockMethod = () => {
    // Your wallet's signTransaction implementation
  };
 
  #signAndExecuteTransactionBlock: SuiSignAndExecuteTransactionBlockMethod = () => {
    // Your wallet's signAndExecuteTransaction implementation
  };
}

Exposing accounts

The last requirement of the wallet interface is to expose an acccounts interface. This should expose all of the accounts that a connected dApp has access to. It can be empty prior to initiating a connection through the standard:connect feature.

The accounts can use the ReadonlyWalletAccount class to easily construct an account matching the required interface.

import { ReadonlyWalletAccount } from '@mysten/wallet-standard';
 
class YourWallet implements Wallet {
	get accounts() {
		// Assuming we already have some internal representation of accounts:
		return someWalletAccounts.map(
			(walletAccount) =>
				// Return
				new ReadonlyWalletAccount({
					address: walletAccount.suiAddress,
					publicKey: walletAccount.pubkey,
					// The Sui chains that your wallet supports.
					chains: [SUI_DEVNET_CHAIN],
					// The features that this account supports. This can be a subset of the wallet's supported features.
					// These features must exist on the wallet as well.
					features: [
						'sui:signPersonalMessage',
						'sui:signTransactionBlock',
						'sui:signAndExecuteTransactionBlock',
					],
				}),
		);
	}
}

Registering in the window

Once you have a compatible interface for your wallet, you register it using the registerWallet function.

import { registerWallet } from '@mysten/wallet-standard';
 
registerWallet(new YourWallet());