butr
Core concepts

Persistence

How connection state survives reloads, the storage driver interface, and why writes are silent by design.

butr persists the pool, the per-platform selection, the active connector id, and the session-scoped disconnect flag, so a reload restores the previous session (subject to hydration).

Storage keys

Keys are prefixed: {prefix}:pool, {prefix}:selection, {prefix}:active, {prefix}:userDisconnected. The default prefix is butr; set storageKeyPrefix to isolate multiple apps sharing one origin.

Storage drivers

A driver is a tiny get/set/remove interface. butr ships three and accepts any custom one (including async — React Native / IndexedDB).

type StorageDriver = {
  getItem(key: string): MaybePromise<string | null>;
  setItem(key: string, value: string): MaybePromise<void>;
  removeItem(key: string): MaybePromise<void>;
};
FactoryBacking store
createBrowserStorageDriver()localStorage (default)
createCookieStorageDriver(options)cookies (domain/path/SameSite/secure)
createMemoryStorageDriver()in-memory (no persistence)

Wrap a driver in WalletStorage and pass it as storage:

import { WalletStorage } from "@usebutr/core";

const storage = new WalletStorage({
  keyPrefix: "myapp",
  persistent: driver, // multi-session
  session: driver, // current session only
});

See the custom storage guide for the React Native / Expo AsyncStorage driver.

Writes are silent by design

butr's persistence layer is fire-and-forget. Any individual write can fail — quota exceeded, IndexedDB shutdown, cross-tab conflicts, cookie size limits — without corrupting the in-memory store. Each storage key is durable on its own; the writes race intentionally.

Because writes are unobserved, a failed write is invisible unless you ask. Set onStorageError to surface them. context is a short string naming the failed write (e.g. "failed to persist pool"). The default behaviour when no callback is set is console.warn.

import { WalletManagerProvider } from "@usebutr/react";
import { autoDiscovery } from "@usebutr/wallets";

const discovery = autoDiscovery();

<WalletManagerProvider
  discovery={discovery}
  onStorageError={(error, context) => {
    reportToSentry(error, { context });
  }}
>

Source: packages/core/src/storage, packages/core/src/store/wallet-store.ts.

On this page