Handle Accounts
A user can authorize multiple accounts when connecting their KEA Wallet. After the initial connection, your app receives an array of accounts and a default selected account. This guide covers how to access account data, switch the active account, and react to account changes — in both React and vanilla JavaScript.
- You have connected the wallet — see Connect Wallet
- You know which package to use — see Integration Options
The WalletAccount Object
Every account returned by the SDK is a WalletAccount with three fields:
interface WalletAccount {
address: string; // Thru-format wallet address
label: string; // User-friendly account name
accountType: AddressType; // Address type — currently always "thru"
}
| Field | Type | Description |
|---|---|---|
address | string | The account's on-chain address in Thru format |
label | string | A human-readable name the user assigned in KEA Wallet |
accountType | AddressType | The address type — currently only "thru" is supported |
Accessing Accounts
After connecting, accounts are available immediately. The SDK provides both the full list and the currently selected (active) account:
- React
- Vanilla JS
import { useWallet } from '@kea-wallet/react-sdk';
function MyComponent() {
const { accounts, selectedAccount } = useWallet();
// accounts: WalletAccount[] — all authorized accounts
// selectedAccount: WalletAccount | null — the currently active account
}
const accounts = sdk.getAccounts(); // WalletAccount[]
const selected = sdk.getSelectedAccount(); // WalletAccount | null
See BrowserSDK for all available methods.
React Integration
For React apps, KEA Wallet provides a pre-built component and two hooks. Choose the approach that matches your UI requirements.
Option A: Pre-built Account Switcher
The fastest path — a single component that handles account listing, switching, and disconnecting:
import { KeaAccountSwitcher } from '@kea-wallet/react-ui';
function Toolbar() {
return <KeaAccountSwitcher />;
}
The component handles two states:
| State | Renders | Behavior |
|---|---|---|
| Disconnected | "Connect Wallet" button | Click opens the wallet modal |
| Connected | Selected address with dropdown | Lists all accounts + disconnect action |
Selecting a different account in the dropdown calls selectAccount() internally and updates the UI.
<KeaAccountSwitcher /> uses dark-themed inline styles that are not customizable via CSS and currently lacks ARIA attributes. For branded, styled, or accessible account selectors, use Option B below.
See KeaAccountSwitcher API reference.
Option B: Custom UI with useWallet()
For full control over styling and behavior, use the useWallet() hook:
import { useWallet } from '@kea-wallet/react-sdk';
function AccountList() {
const { accounts, selectedAccount, selectAccount } = useWallet();
return (
<ul>
{accounts.map((acc) => (
<li
key={acc.address}
onClick={() => selectAccount(acc)}
style={{ fontWeight: selectedAccount?.address === acc.address ? 'bold' : 'normal' }}
>
{acc.label} — {acc.address}
{selectedAccount?.address === acc.address && ' (active)'}
</li>
))}
</ul>
);
}
Key points:
selectAccount()takes aWalletAccountobject — pass the account from theaccountsarray directly.- Clicking the already-selected account is a no-op — no event fires, no state changes.
accountsdoes not change when switching — onlyselectedAccountupdates.
See UseWalletReturn for all available properties.
Read-Only Hook: useAccounts()
Use useAccounts() in components that display account information but don't need to connect, disconnect, or switch accounts:
import { useAccounts } from '@kea-wallet/react-sdk';
function AccountStatus() {
const { accounts, selectedAccount, isConnected } = useAccounts({
onAccountSelect: (account) => {
console.log('Account switched to:', account.address);
},
});
if (!isConnected) return <p>Not connected</p>;
return (
<div>
<p>Active: {selectedAccount?.address}</p>
<p>Total accounts: {accounts.length}</p>
</div>
);
}
The onAccountSelect callback fires whenever the selected account changes — whether from this component or any other part of your app.
useWallet vs useAccounts:
| Capability | useWallet() | useAccounts() |
|---|---|---|
accounts | Yes | Yes |
selectedAccount | Yes | Yes |
isConnected / isConnecting | Yes | Yes |
selectAccount() | Yes | — |
connect() / disconnect() | Yes | — |
onAccountSelect callback | — | Yes |
wallet (chain adapter) | Yes | — |
Use useAccounts() for display-only components (dashboards, headers) and useWallet() when you need to trigger actions.
See UseAccountsOptions and UseAccountsReturn for the full API.
Vanilla JavaScript
For non-React apps, use BrowserSDK directly:
import { BrowserSDK } from '@kea-wallet/browser-sdk';
const sdk = new BrowserSDK({
rpcUrl: 'https://grpc-web.alphanet.thruput.org',
autoConnect: true,
});
await sdk.initialize();
await sdk.connect({ metadata: { appName: 'My App' } });
// Get all authorized accounts
const accounts = sdk.getAccounts();
const selected = sdk.getSelectedAccount();
console.log('Active account:', selected?.address);
// Switch to a different account
if (accounts.length > 1) {
const newSelected = await sdk.selectAccount(accounts[1].address);
console.log('Switched to:', newSelected.address);
}
In React, selectAccount() takes a WalletAccount object. In vanilla JS, selectAccount() takes a publicKey string and returns Promise<WalletAccount>.
If you pass an invalid address, selectAccount() throws an ACCOUNT_NOT_FOUND error. See the Error Handling guide.
The selected account does not persist across page reloads — it resets to accounts[0] when the session is restored via autoConnect. If your app needs persistence, store the selected address in localStorage and call selectAccount() after reconnection.
Listening for Account Changes
The accountChanged event fires whenever the active account is switched via selectAccount(). The payload is the new WalletAccount.
- React (useAccounts)
- React (useKea)
- Vanilla JS
The simplest way in React — use the onAccountSelect callback:
const { accounts, selectedAccount } = useAccounts({
onAccountSelect: (account) => {
console.log('Switched to:', account.address);
},
});
For direct SDK event access, use the useKea() hook:
import { useEffect } from 'react';
import { useKea } from '@kea-wallet/react-sdk';
function AccountWatcher() {
const { sdk } = useKea();
useEffect(() => {
if (!sdk) return;
const handler = (account) => {
console.log('Account changed:', account.address);
};
sdk.on('accountChanged', handler);
return () => sdk.off('accountChanged', handler);
}, [sdk]);
}
sdk.on('accountChanged', (account) => {
console.log('Switched to:', account.address, account.label);
});
Account-related events:
| Event | Payload | When it fires |
|---|---|---|
accountChanged | WalletAccount | selectAccount() completes successfully |
connect | ConnectResult | Initial connection (includes the accounts array) |
reconnecting | { isReconnecting: boolean } | Auto-reconnect starts or ends |
For the full event reference, see the SDK Events guide.
UX Best Practices
- Show the account label alongside the address —
labelgives users a recognizable name instead of a raw address string. - Truncate addresses in the UI — display
address.slice(0, 6)...address.slice(-4)for readability. - Highlight the active account — use a border, badge, or checkmark so users can see which account is selected at a glance.
- Handle the single-account case — if only one account is authorized, you can skip the switcher or show it as informational without a dropdown.
- Handle the empty state —
accountsis an empty array until the wallet is connected. Show a connect prompt instead of an empty list.
What's Next
- Sign Transactions — Build and sign transactions with the active account
- SDK Events — Full event reference including accountChanged, connect, disconnect
- Error Handling — Handle ACCOUNT_NOT_FOUND and other errors