Skip to main content

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.

Prerequisites

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"
}
FieldTypeDescription
addressstringThe account's on-chain address in Thru format
labelstringA human-readable name the user assigned in KEA Wallet
accountTypeAddressTypeThe 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:

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
}

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:

StateRendersBehavior
Disconnected"Connect Wallet" buttonClick opens the wallet modal
ConnectedSelected address with dropdownLists all accounts + disconnect action

Selecting a different account in the dropdown calls selectAccount() internally and updates the UI.

warning

<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 a WalletAccount object — pass the account from the accounts array directly.
  • Clicking the already-selected account is a no-op — no event fires, no state changes.
  • accounts does not change when switching — only selectedAccount updates.

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:

CapabilityuseWallet()useAccounts()
accountsYesYes
selectedAccountYesYes
isConnected / isConnectingYesYes
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);
}
API difference

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.

Account persistence

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.

The simplest way in React — use the onAccountSelect callback:

const { accounts, selectedAccount } = useAccounts({
onAccountSelect: (account) => {
console.log('Switched to:', account.address);
},
});

Account-related events:

EventPayloadWhen it fires
accountChangedWalletAccountselectAccount() completes successfully
connectConnectResultInitial 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 — label gives 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 — accounts is 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