Multi-Account Management
Relevant source files
The following files were used as context for generating this wiki page:The sui-svelte-wallet-kit provides robust support for wallets that manage multiple accounts. The system is designed to automatically detect all accounts associated with a connected wallet, allow the user to seamlessly switch between them, and persist the user's selection across sessions. This functionality is primarily managed within the SuiModule component.
When a wallet is connected, the kit retrieves a list of all available accounts. It designates one as the "active" account, which is then used for all subsequent operations like signing transactions or fetching balances. The kit exposes reactive stores and functions to enable developers to build UIs for account switching and to display information relevant to the currently active account.
Sources: README.md, src/lib/SuiModule/SuiModule.svelte
Core Architecture and State
The multi-account functionality is managed by a set of reactive state variables within SuiModule.svelte. These variables track the full list of accounts, the currently active account, and related derived state.
Sources: src/lib/SuiModule/SuiModule.svelte:26-51
Key State Variables
| Variable | Type | Description | Source File |
|---|---|---|---|
_account | SuiAccount | The currently active wallet account object. All dApp interactions are performed with this account. | src/lib/SuiModule/SuiModule.svelte:28 |
_accountsSnapshot | SuiAccount[] | An immutable snapshot of all accounts retrieved from the wallet upon connection. | src/lib/SuiModule/SuiModule.svelte:51 |
activeAccountIndex | ReadableStore<number> | A derived store that provides the index of the _account within the _accountsSnapshot array. Returns -1 if not found. | src/lib/SuiModule/SuiModule.svelte:786-791 |
_suiNamesByAddress | Record<string, string[]> | A mapping of account addresses to their fetched SuiNS names. Used to display friendly names in the UI. | src/lib/SuiModule/SuiModule.svelte:31 |
_suiBalanceByAddress | Record<string, string> | A mapping of account addresses to their SUI balance. | src/lib/SuiModule/SuiModule.svelte:32 |
State Management Flow
The following diagram illustrates the relationship between the core state variables for account management.
This diagram shows that upon connection, the walletAdapter provides all accounts to _accountsSnapshot. The switchAccount function selects an account from this snapshot to become the active _account, and the activeAccountIndex is derived from this relationship.
Sources: src/lib/SuiModule/SuiModule.svelte:28, 51, 786-818
Account Discovery and Session Persistence
Accounts are discovered when a user connects their wallet. The selection is persisted to localStorage to be restored in subsequent sessions.
Connection and Discovery Flow
- The
connectfunction is called with a selected wallet. - It accesses the
walletAdapter.accountsproperty to get a raw list of accounts. - This list is filtered to include only valid
SuiAccountobjects and stored in_accountsSnapshot. - The system checks
localStoragefor aselectedAccountAddressfrom a previous session. - If a preferred address is found and exists in the snapshot, it is set as the active account. Otherwise, the first account in the list (
allAccounts[0]) is used as the default. - The chosen account is set as the active
_account. - Connection data, including the
selectedAccountAddress, is saved tolocalStorageviasaveConnectionDataandupdateConnectionData.
Sources: src/lib/SuiModule/SuiModule.svelte:879-918, 225-233
The following sequence diagram details the account discovery process during a wallet connection.
Switching Accounts
The kit provides the switchAccount function to change the active account. This function is designed to be called from the application's UI, for example, from a dropdown list of available accounts.
switchAccount(selector)
This function updates the application's active account.
selector: Can be anumber(the index in theuseAccounts()array), astring(the account address), or aSuiAccountobject.
The function performs the following steps:
- Finds the corresponding account in the
_accountsSnapshotarray based on theselector. - If a matching account is found, it updates the
_accountstate variable to the new account. - It calls
updateConnectionDatato persist the newselectedAccountAddressinlocalStorage. - It immediately updates the
_suiNamesstore with cached SuiNS names for the new account, if available, to ensure a responsive UI.
Sources: src/lib/SuiModule/SuiModule.svelte:793-826, src/routes/+page.svelte:74-76
Account Switching Flow
This flowchart shows the logic inside the switchAccount function.
UI Implementation Example
The demo page provides a practical example of an account switcher UI using a <select> element.
<!-- src/routes/+page.svelte:311-327 -->
{#if accounts.length > 1}
<div class="account-switcher">
<label for="account-select"><strong>Switch account:</strong></label>
<select
id="account-select"
bind:value={selectedAccountIndex}
onchange={onAccountChange}
class="account-select"
>
{#each accounts as acc, i}
<option value={i} selected={i === activeAccountIndex.value}>
#{i + 1} —
{#if Array.isArray(suiNamesByAddress.value?.[acc.address]) && suiNamesByAddress.value[acc.address].length > 0}
{suiNamesByAddress.value[acc.address][0]} ({acc.address})
{:else}
{acc.address}
{/if}
</option>
{/each}
</select>
</div>
{/if}
<script lang="ts">
// src/routes/+page.svelte:74-76
const onAccountChange = async (): Promise<void> => {
switchAccount(Number(selectedAccountIndex));
};
</script>
This snippet demonstrates binding a state variable selectedAccountIndex to the select input and calling switchAccount when the value changes. It also shows how to use suiNamesByAddress to display a friendly name for each account.
Sources: src/routes/+page.svelte:74-76, 311-327
Reactive Data Fetching
Data specific to an account, such as SUI balance and SuiNS names, is fetched automatically whenever the active account changes. This is achieved through Svelte 5 $effect runes that watch for changes in the active _account.
When _account is updated (e.g., after switchAccount is called):
- An
$effectis triggered, comparing the new account's address and chain to a_lastRefreshKey. - If the key has changed, it calls
refreshSuiNamesForActive()to fetch SuiNS names. - A separate
$effectis triggered to callrefreshSuiBalance()for the new account's address.
This ensures that the UI, which consumes the suiBalance and suiNames stores, is always up-to-date with the data for the currently selected account.
Sources: src/lib/SuiModule/SuiModule.svelte:1134-1155
Public API and Data Structures
The following functions and stores are exported for managing multiple accounts.
API Reference
| Export | Type | Description |
|---|---|---|
useCurrentAccount() | `() => SuiAccount | undefined` |
useAccounts() | () => SuiAccount[] | A reactive hook (getter) that returns the full array of accounts discovered from the connected wallet. |
activeAccountIndex | ReadableStore<number> | A reactive store holding the index of the current account in the useAccounts() array. |
switchAccount() | `(selector: number | string) => boolean` |
setAccountLabel() | (name: string) => void | Manually sets the label property on the current account object. |
Sources: src/lib/SuiModule/index.d.ts:8-12, README.md, src/lib/SuiModule/SuiModule.svelte:743-751, 793-794, 739-741
SuiAccount Data Structure
The SuiAccount interface represents a single wallet account and is compatible with the Wallet Standard WalletAccount.
| Field | Type | Description |
|---|---|---|
address | string | The public address of the account. |
publicKey | Uint8Array | The public key of the account. |
chains | readonly ('sui:mainnet' | ...) | An array of chain identifiers the account supports (e.g., sui:testnet). |
features | readonly string[] | An array of features supported by the account. |
label | string (optional) | An optional, user-defined friendly name for the account. |
icon | string (optional) | An optional data URI for an icon. |
Sources: src/lib/SuiModule/types.ts:13, 375-378
Summary
The multi-account management system in sui-svelte-wallet-kit is a comprehensive feature that simplifies the handling of multiple user accounts. By automatically discovering accounts, providing a straightforward API for switching, and reactively updating account-specific data, it offers developers a powerful and easy-to-use toolset. The persistence of the selected account enhances user experience by remembering their choice across sessions.
Sources: README.md, src/lib/SuiModule/SuiModule.svelte