Handling Wallet Events
Relevant source files
The following files were used as context for generating this wiki page:
The sui-svelte-wallet-kit provides a robust system for handling wallet-related events through a combination of component props, function callbacks, and reactive Svelte 5 runes. This allows developers to respond to user actions like connecting a wallet, as well as to state changes originating from the wallet extension itself, such as switching accounts or networks.
The core of the event system is orchestrated by the SuiModule component, which manages the connection state and listens for changes. UI components like ConnectButton and ConnectModal provide hooks to intercept user interactions, while exported functions like switchWallet offer fine-grained control over complex flows with multiple callback points.
Core Event Architecture
The event handling architecture is centered around the SuiModule component, which acts as the state manager. It interacts with the ConnectModal for wallet selection and listens for events from the connected wallet adapter. Application code can subscribe to these events via props on components or callbacks in functions.
This diagram illustrates the high-level interaction between the main components involved in event handling.
Connection and Selection Events
These events are tied to direct user actions, such as initiating a connection or selecting a wallet from the modal.
Initial Connection (onConnect)
The SuiModule component accepts an onConnect prop, which is a callback function that fires once a wallet has been successfully connected. This is useful for initializing application state that depends on a connected wallet.
The onConnect callback is triggered at the end of the connect function, after the wallet adapter has connected, the account state has been set, and the connection data has been persisted to localStorage.
Sources: src/lib/SuiModule/SuiModule.svelte:1003-1006, src/lib/SuiModule/SuiModule.svelte:811-815
The following sequence diagram shows the flow that leads to the onConnect callback being invoked.
Wallet Selection (onWalletSelection)
The ConnectButton component exposes an onWalletSelection prop. This callback is invoked whenever a user makes a selection in the ConnectModal, regardless of whether the wallet is installed. Its primary purpose is to allow the application to provide feedback to the user, such as showing an alert to install a wallet if it's not detected.
The callback receives a WalletSelectionPayload object.
| Property | Type | Description |
|---|---|---|
wallet | SuiWallet | The wallet object that the user selected. |
installed | boolean | true if the selected wallet is installed. |
Sources: src/lib/SuiModule/types.ts:291-295, README.md:100-109
Here is an example of its usage from the demo page:
<script lang="ts">
import { ConnectButton } from 'sui-svelte-wallet-kit';
import type { WalletSelectionPayload } from '$lib';
const onWalletSelection = (payload: WalletSelectionPayload): void => {
try {
const selectedWallet = payload?.wallet ?? payload;
const installed =
typeof payload === 'object' ? !!payload?.installed : !!selectedWallet?.installed;
if (!installed) {
console.log('[Page] Selected wallet not installed:', selectedWallet?.name);
alert('Please install the wallet: ' + selectedWallet?.name);
}
} catch {}
};
</script>
<ConnectButton class="connect-btn" {onWalletSelection} />
Sources: src/routes/+page.svelte:245-257, src/routes/+page.svelte:300
Programmatic Switching (switchWallet)
The switchWallet function provides a way to programmatically open the wallet selection modal and manage the process of switching from one wallet to another. It accepts an options object with several callbacks to hook into different stages of the switching process.
This provides more granular control than the simple onConnect or onWalletSelection props. The options are defined by the SwitchWalletOptions interface.
| Callback | Description |
|---|---|
onSelection | Fires every time a user picks a wallet in the modal. Receives { wallet, installed, connected: false }. |
shouldConnect | A predicate function that decides if the connection process should proceed after selection. |
onBeforeDisconnect | Fires just before the current wallet is disconnected. Receives (currentWallet, selectedWallet). |
onConnected | Fires after the new wallet is successfully connected. Receives the new wallet. |
onCancel | Fires if the user closes the modal without making a selection. |
Sources: src/lib/SuiModule/types.ts:233-249, src/lib/SuiModule/SuiModule.svelte:859-906
The following flowchart shows the logic inside the switchWallet function.
Reactive State Change Events
The kit is designed to be reactive, automatically updating its state when changes occur within the connected wallet extension.
Listening for Account and Network Changes
The SuiModule automatically listens for account and network changes from the connected wallet by leveraging the Wallet Standard standard:events feature. The attachWalletNetworkListener function is responsible for this.
When a wallet is connected, this function subscribes to the 'change' event on the wallet's adapter. The payload of this event, defined as WalletChangePayload, can contain new accounts or chains.
- If
chainsare present, the current account'schainsproperty is updated. - If
accountsare present, the internal_accountsSnapshotis updated, and the current account is set to the new active account.
This process ensures that the reactive stores (useCurrentAccount, useAccounts) always reflect the true state of the wallet extension.
Sources: src/lib/SuiModule/SuiModule.svelte:321-378, src/lib/SuiModule/types.ts:220-224
This sequence diagram shows how a change from the wallet extension propagates to the application.
Responding to State with Svelte Effects ($effect)
The recommended way to react to wallet state changes (like account or network switches) is by using Svelte 5's $effect rune. By deriving state from the kit's exported functions (useCurrentAccount, useSuiClient), an effect will automatically re-run whenever the underlying state changes.
For example, the demo page uses an $effect to fetch zkLogin info whenever the account changes.
<script lang="ts">
import { useCurrentAccount, getZkLoginInfo } from '$lib';
import type { ZkLoginInfo } from '$lib';
const account = $derived(useCurrentAccount());
let zkInfo = $state<ZkLoginInfo | null>(null);
$effect(() => {
// Fetch zkLogin info when account changes
if (account) {
getZkLoginInfo()
.then((info: ZkLoginInfo | null) => {
zkInfo = info;
})
.catch(() => {
zkInfo = null;
});
} else {
zkInfo = null;
}
});
</script>
Sources: src/routes/+page.svelte:153-167
Another effect in SuiModule automatically refreshes the SUI balance when the account or chain changes. This demonstrates how the library internally uses the same reactive patterns.
Sources: src/lib/SuiModule/SuiModule.svelte:1104-1112
Summary
The sui-svelte-wallet-kit offers a dual approach to event handling:
- Explicit Callbacks: For direct user interactions, props like
onConnectandonWalletSelection, and theSwitchWalletOptionscallbacks provide immediate hooks into the event lifecycle. - Reactive State: For changes originating from the wallet itself, the library automatically updates its internal state, which can be consumed reactively in your application using Svelte's runes like
$derivedand$effect.
This combination provides developers with both the fine-grained control needed for complex UX flows and the simplicity of a reactive system that stays in sync with the wallet's state.