use-truapi
Accounts

useAccounts

Wallet state plus connect, disconnect and select in one hook

useAccounts returns the current wallet state (accounts, selectedAccount, status, error) together with the connect, disconnect and select actions. Every account hook reads the same shared store, so this hook, useSelectedAccount and useSigner update together the moment anything changes.

status walks "disconnected" → "connecting" → "connected" (or "error"); isConnected and isConnecting are derived from it so you can render without string comparisons. connect() picks the provider automatically: the host provider when running inside a Polkadot host container, dev accounts standalone. It is safe to call from several components at once; concurrent callers share one attempt, and a failure evicts it so the next click retries.

select(address) switches the selected account and throws if the address is not in accounts. The selection feeds every downstream consumer, including transaction hooks like useTx.

Usage

import { useAccounts } from "@use-truapi/react";

function ConnectWallet() {
  const {
    accounts,
    selectedAccount,
    isConnected,
    isConnecting,
    error,
    connect,
    disconnect,
    select,
  } = useAccounts();

  if (!isConnected) {
    return (
      <>
        <button
          type="button"
          onClick={() => void connect().catch(() => {})}
          disabled={isConnecting}
        >
          {isConnecting ? "Connecting…" : "Connect wallet"}
        </button>
        {error && <p role="alert">{error.message}</p>}
      </>
    );
  }

  return (
    <>
      <ul>
        {accounts.map((account) => (
          <li key={account.address}>
            <button type="button" onClick={() => select(account.address)}>
              {account.name ?? account.address}
              {account.address === selectedAccount?.address && " ✓"}
            </button>
          </li>
        ))}
      </ul>
      <button type="button" onClick={disconnect}>Disconnect</button>
    </>
  );
}
<script setup lang="ts">
import { useAccounts } from "@use-truapi/vue";

const {
  accounts,
  selectedAccount,
  isConnected,
  isConnecting,
  error,
  connect,
  disconnect,
  select,
} = useAccounts();

function onConnect() {
  void connect().catch(() => {});
}
</script>

<template>
  <template v-if="!isConnected">
    <button type="button" :disabled="isConnecting" @click="onConnect">
      {{ isConnecting ? "Connecting…" : "Connect wallet" }}
    </button>
    <p v-if="error" role="alert">{{ error.message }}</p>
  </template>
  <template v-else>
    <ul>
      <li v-for="account in accounts" :key="account.address">
        <button type="button" @click="select(account.address)">
          {{ account.name ?? account.address }}
          <template v-if="account.address === selectedAccount?.address"> ✓</template>
        </button>
      </li>
    </ul>
    <button type="button" @click="disconnect">Disconnect</button>
  </template>
</template>

In Vue every state field is a ComputedRef: use .value in script, they unwrap automatically in templates. The actions (connect, disconnect, select) are plain functions.

To force a provider instead of auto-detecting, pass "host" or "dev":

const accounts = await connect("dev");

With autoConnect: true in your config the runtime calls connect() on startup, so components usually only need to render the resulting state.

See also

  • useConnect is the same connect with per-call state (isPending, error, data).
  • useSelectedAccount returns just the selected account, for components that only read.
  • useSigner returns the PolkadotSigner of the selected account.

API reference

React

function useAccounts(): AccountsResult;

Wallet state + connect/disconnect/select, backed by the shared SignerManager.

Returns

AccountsResult

Properties

accounts

accounts: readonly SignerAccount[];

connect

connect: (provider?) => Promise<SignerAccount[]>;
Parameters
ParameterType
provider?ProviderType
Returns

Promise<SignerAccount[]>


disconnect

disconnect: () => void;
Returns

void


error

error: SignerError | null;

isConnected

isConnected: boolean;

isConnecting

isConnecting: boolean;

select

select: (address) => SignerAccount;
Parameters
ParameterType
addressstring
Returns

SignerAccount


selectedAccount

selectedAccount: SignerAccount | null;

status

status: ConnectionStatus;

Vue

function useAccounts(): AccountsResult;

Wallet state + connect/disconnect/select, backed by the shared SignerManager.

Returns

AccountsResult

Properties

accounts

accounts: ComputedRef<readonly SignerAccount[]>;

connect

connect: (provider?) => Promise<SignerAccount[]>;
Parameters
ParameterType
provider?ProviderType
Returns

Promise<SignerAccount[]>


disconnect

disconnect: () => void;
Returns

void


error

error: ComputedRef<SignerError | null>;

isConnected

isConnected: ComputedRef<boolean>;

isConnecting

isConnecting: ComputedRef<boolean>;

select

select: (address) => SignerAccount;
Parameters
ParameterType
addressstring
Returns

SignerAccount


selectedAccount

selectedAccount: ComputedRef<SignerAccount | null>;

status

status: ComputedRef<ConnectionStatus>;

On this page