Provider setup
One WalletManagerProvider and one config: auto-discovery, a single platform, built adapters, or all of them.
There is one provider: WalletManagerProvider from @usebutr/react. It takes
a config of type WalletManagerConfig from @usebutr/core, and an optional
initialState for server rendering.
The provider creates one manager per mount and reads config once, at that
moment. Define it at module scope: a config built during render is ignored on
every later render, and so are callbacks that close over component state.
Auto (batteries-included)
Put autoDiscovery() from @usebutr/wallets in sources. It discovers EVM
(EIP-6963), SVM, Sui, and Bitcoin (Wallet Standard), and Polkadot
(injectedWeb3) wallets. State persists to localStorage under
storageKeyPrefix.
import type { WalletManagerConfig } from "@usebutr/core";
import { WalletManagerProvider } from "@usebutr/react";
import { autoDiscovery } from "@usebutr/wallets";
import type { ReactNode } from "react";
const config: WalletManagerConfig = {
sources: [autoDiscovery()],
storageKeyPrefix: "butr-demo",
};
const WalletProvider = ({ children }: { children: ReactNode }) => (
<WalletManagerProvider config={config}>{children}</WalletManagerProvider>
);
export { WalletProvider };autoDiscovery takes an optional platform list and options:
autoDiscovery(["evm", "svm"]); // only these platforms
autoDiscovery(undefined, { fallbacks: false }); // skip window.ethereum, injected Bitcoin, Polkadot Wallet StandardPlatform-only bundles
Every discover*Adapters export is a wallet source as-is, so a single-platform
app passes it straight into sources and never imports @usebutr/wallets:
import type { WalletManagerConfig } from "@usebutr/core";
import { discoverEvmAdapters } from "@usebutr/evm";
const config: WalletManagerConfig = { sources: [discoverEvmAdapters] };Each has a complete path, including install, chains, and platform caveats:
Adding WalletConnect and Ledger
Some adapters are built rather than discovered. fromAdapters from
@usebutr/core turns one adapter, several, or a promise of either into a
source, so they sit
next to discovery in sources and show up in useDiscoveredWallets() like any
other wallet:
import type { WalletManagerConfig } from "@usebutr/core";
import { fromAdapters } from "@usebutr/core";
import { createLedgerAdapter } from "@usebutr/ledger";
import { WalletManagerProvider } from "@usebutr/react";
import { autoDiscovery } from "@usebutr/wallets";
import { createWalletConnectAdapters } from "@usebutr/walletconnect";
import type { ReactNode } from "react";
import { showPairingQr } from "./pairing";
const config: WalletManagerConfig = {
sources: [
autoDiscovery(),
fromAdapters(
createWalletConnectAdapters({
metadata: { name: "My dapp", url: "https://my-dapp.example" },
namespaces: { evm: ["eip155:1"], svm: [] },
onPairingUri: showPairingQr,
projectId: "<your Reown project id>",
}),
),
fromAdapters(createLedgerAdapter({ id: "ledger-evm", platform: "evm" })),
],
storageKeyPrefix: "my-app",
};
const WalletProvider = ({ children }: { children: ReactNode }) => (
<WalletManagerProvider config={config}>{children}</WalletManagerProvider>
);
export { WalletProvider };A promise that rejects is logged and contributes nothing, so a missing peer dependency or project id leaves the rest of the picker intact. If two sources announce the same id, the first one wins.
See WalletConnect and Ledger for their options.
Other config fields
| Field | Default | Purpose |
|---|---|---|
sources | [] | where adapters come from |
storageKeyPrefix | "butr" | namespaces the default storage keys |
storage | localStorage + sessionStorage | a custom WalletPersistence |
onConnect, onConnectError, onDisconnect, onHydrated, onSlowConnect, onStorageError | — | lifecycle callbacks |
slowConnectThresholdMs | 5000 | when onSlowConnect fires |
Without React
The provider is a thin binding over createWalletManager. Anything else calls
it directly with the same config:
import { createWalletManager } from "@usebutr/core";
const manager = createWalletManager(config);
const stop = manager.start(); // discovery, hydration, wallet eventsSource: apps/demo-vite/src/wallet-provider.tsx (auto discovery plus WalletConnect and
Ledger) in the butr
repository.