Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
The sui-svelte-wallet-kit is a Svelte 5 library designed to simplify Sui blockchain integration in dApps. Its architecture is centered around a primary Svelte component, SuiModule, which acts as a state manager and provider for all wallet-related functionalities. It leverages Svelte 5 runes for reactive state management and exposes a "hook-like" API for consuming wallet data and functions throughout an application.
The system is built upon the @suiet/wallet-sdk and @mysten/wallet-standard libraries for wallet discovery and interaction. It provides pre-built UI components like ConnectButton and ConnectModal for a streamlined user experience, and supports advanced features like multi-account management, automatic SuiNS and balance fetching, and zkLogin via Enoki.
Core Components
The library's architecture is composed of a few key Svelte components and a central module script that orchestrates the logic.
This diagram shows the high-level component hierarchy. The SuiModule component wraps the user's application, providing a context for all wallet interactions. The ConnectButton and the application code interact with the module's exported API to manage state and trigger actions.
Sources: src/lib/SuiModule/SuiModule.svelte, src/routes/+page.svelte:261-268, src/lib/index.js
SuiModule.svelte
This is the heart of the library. It is a provider component that must wrap the application or the parts of it that require wallet access. It is responsible for:
- State Management: It uses Svelte 5 runes (
$state) to manage all wallet-related state internally. - API Exposure: It exports a comprehensive API of functions and reactive getters from its
<script module>block. This allows any part of the application to import and use wallet functionality without prop drilling. - Wallet Discovery: Initializes and manages the discovery of installed Sui wallets.
- Connection Lifecycle: Handles connecting, disconnecting, and auto-reconnecting to wallets.
- Data Fetching: Orchestrates the automatic fetching of SUI balance and SuiNS names for connected accounts.
- Internal Components: It renders the
ConnectModalcomponent, which is used for wallet selection.
Sources: src/lib/SuiModule/SuiModule.svelte:1-1250
SuiModule Props
| Prop | Type | Default | Description |
|---|---|---|---|
onConnect | () => void | undefined | A callback function that is executed when a wallet successfully connects. |
autoConnect | boolean | false | If true, the module attempts to automatically reconnect to the last used wallet on page load. |
autoSuiNS | boolean | true | If true, automatically fetches SuiNS names for the connected account. |
autoSuiBalance | boolean | true | If true, automatically fetches the SUI balance for the connected account. |
walletConfig | WalletConfig | {} | An object to customize wallet ordering and display names in the ConnectModal. |
zkLoginGoogle | ZkLoginGoogleConfig | null | Configuration object to enable "Sign in with Google" via Enoki zkLogin. |
children | any | undefined | The content to be rendered inside the module, typically the rest of the application. |
Sources: src/lib/SuiModule/SuiModule.svelte:1190-1198, src/lib/SuiModule/types.ts:167-175
ConnectButton
A simple, pre-styled button that displays the connection status. When clicked, it opens the ConnectModal if not connected, or triggers a disconnect if already connected. It is a consumer of the state provided by SuiModule.
Sources: README.md:100-106, src/lib/index.js:2
ConnectModal
A modal dialog, used internally by SuiModule, that lists all available (and installed) wallets for the user to choose from. Its visibility is controlled by the SuiModule.
Sources: src/lib/SuiModule/SuiModule.svelte:1248-1257
State Management and API
The library employs a modern Svelte 5 approach to state management using runes. All core state is defined within the <script module> section of SuiModule.svelte, making it a singleton across the application.
Internal State
The following table lists some of the key internal state variables managed by SuiModule.
| State Variable | Type | Description |
|---|---|---|
walletAdapter | `SuiWalletAdapter | undefined` |
status | ConnectionStatus | The current connection status (DISCONNECTED, CONNECTING, CONNECTED). |
_account | `SuiAccount | undefined` |
_wallet | `WalletWithStatus | undefined` |
_suiNamesByAddress | Record<string, string[]> | A cache of SuiNS names, keyed by address. |
_suiBalanceByAddress | Record<string, string> | A cache of SUI balances, keyed by address. |
_accountsSnapshot | SuiAccount[] | A list of all accounts available from the connected wallet. |
_lastWalletSelection | { wallet: Wallet; installed: boolean } | Stores the last wallet the user selected from the modal. |
Sources: src/lib/SuiModule/SuiModule.svelte:15-50
Public API (Exports)
The internal state is exposed to the application via a set of "hook-style" functions and reactive getters. These are all exported from SuiModule and re-exported from the package's main entry point.
This diagram illustrates how internal state is exposed through the public API.
Key exports include:
- State Getters:
useCurrentAccount,useCurrentWallet,useAccounts,suiBalance,suiNames. - Action Functions:
connect,disconnect,switchWallet,switchAccount,signAndExecuteTransaction,signMessage. - Utility Functions:
canSignMessage,isZkLoginWallet,getZkLoginInfo,refreshSuiBalance.
Sources: src/lib/index.js:3-33, src/lib/SuiModule/index.js:5-35
Wallet Connection and Discovery
The wallet connection process is a core feature, involving discovery, user selection, and state persistence.
Wallet Discovery Flow
Wallet discovery is initiated by initWalletDiscovery and runs multiple times on startup to detect wallets that may initialize late. It uses @suiet/wallet-sdk's WalletRadar and the Wallet Standard's getWallets() function.
This flowchart shows the process of discovering and preparing the list of wallets to be displayed in the ConnectModal.
Sources: src/lib/SuiModule/SuiModule.svelte:1098-1153
Connection Sequence
The following diagram shows the sequence of events when a user connects a wallet for the first time.
This sequence illustrates the interaction between the user, the UI components, the core module, and the browser wallet extension.
Sources: src/lib/SuiModule/SuiModule.svelte:782-803, src/lib/SuiModule/SuiModule.svelte:805-851
Auto-Connect
If autoConnect={true} is passed to SuiModule, the component will attempt to reconnect to the previously used wallet on initialization.
- On successful connection,
saveConnectionDatastores the wallet name andautoConnect: trueinlocalStorageunder the keysui-module-connection. - On page load, an
$effectinSuiModulechecks for available wallets. - Once wallets are detected,
autoConnectWalletis called. autoConnectWalletreadslocalStorage, finds the matching installed wallet from the available list, and callsconnect(wallet).
Sources: src/lib/SuiModule/SuiModule.svelte:1222-1233, src/lib/SuiModule/SuiModule.svelte:210-224, src/lib/SuiModule/SuiModule.svelte:113-122
Data Fetching
The library automatically fetches and caches on-chain data like SUI balance and SuiNS names.
SUI Balance Fetching
- Trigger: A Svelte
$effecthook observes changes to the current account's address or chain. - Function:
refreshSuiBalanceis called. - Caching: The function implements both TTL (Time To Live) and in-flight request deduplication.
- A balance is considered "fresh" if fetched within the
_balanceCacheTTLms(default 2000ms). - Concurrent calls for the same address/chain will return the same promise (
_balanceInflightByKey).
- A balance is considered "fresh" if fetched within the
- State Update: The result is stored in
_suiBalanceByAddress, and thesuiBalancegetter provides the value for the current account.
Sources: src/lib/SuiModule/SuiModule.svelte:449-460, src/lib/SuiModule/SuiModule.svelte:1236-1246
SuiNS Name Fetching
- Trigger: A Svelte
$effecthook observes changes to the current account. - Function:
refreshSuiNamesForAll()is called on the first connection, andrefreshSuiNamesForActive()is called on subsequent account switches. - Logic: It uses
resolveAddressToSuiNSNamesfrom@suiet/wallet-sdkto query names. - State Update: Results are stored in
_suiNamesByAddress. If the current account has nolabel, the first resolved SuiNS name is automatically assigned as its label.
Sources: src/lib/SuiModule/SuiModule.svelte:226-258, src/lib/SuiModule/SuiModule.svelte:1236-1246
zkLogin (Enoki) Integration
The library supports Google zkLogin through the @mysten/enoki SDK.
- Activation: Enabled by passing a valid
zkLoginGoogleconfiguration object toSuiModule. - Registration: When enabled,
SuiModulecallsregisterEnokiWallets, which adds a "Sign in with Google" option to the list of available wallets. - Validation: The module performs a basic probe of the Enoki API key to provide developers with early feedback on its validity. It also checks for common configuration mistakes, like a malformed Google Client ID.
- API: Specific functions like
isZkLoginWallet()andgetZkLoginInfo()are provided to interact with zkLogin session data.
Sources: src/lib/SuiModule/SuiModule.svelte:145-189, src/lib/SuiModule/SuiModule.svelte:1005-1025, src/routes/+page.svelte:255-259
Summary
The sui-svelte-wallet-kit architecture is a robust and modern implementation that leverages Svelte 5's reactivity model to provide a seamless developer experience. By centralizing state and logic within the SuiModule and exposing a clean, hook-like API, it abstracts away the complexities of wallet management, connection persistence, and on-chain data fetching. Its modular design, with distinct components for UI and a powerful core for logic, makes it both easy to use for beginners and flexible enough for advanced use cases like zkLogin.