butr
Discover and connect EVM, Solana, Sui, Bitcoin, and Polkadot wallets from one React hook surface. Bring your own chain library.
$ npm i @usebutr/react @usebutr/wallets zustand- licenseMIT
- walletsv2.0.1
- packages12
- react18+
Multi-chain
Connect MetaMask and Phantom at the same time. One pool, each platform tracked on its own.
See moreConnector-shaped
Injected, WalletConnect, Ledger, or your own: every wallet is a WalletAdapter on one seam.
See moreNo lock-in
getSigner() hands back the wallet's own provider, tagged by kind. Bridge it into viem, wagmi, gill, or @solana/kit.
See moreModular
Core has no React and no protocol code. Install only the chain packages you need.
See more
Overview
Wrap the tree once, read the discovered pool through hooks, and keep the picker UI yours. butr handles discovery and connection state across reloads; it ships no modal and no RPC stack.
// 1. Import the provider and hooks.
import {
WalletManagerProvider,
useConnect,
useDiscoveredWallets,
useIsHydrated,
} from "@usebutr/react";
import { autoDiscovery } from "@usebutr/wallets";
// 2. Discover the browser's wallets; config is read once.
const config = { sources: [autoDiscovery()] };
export const App = () => (
<WalletManagerProvider config={config}>
<WalletPicker />
</WalletManagerProvider>
);
// 3. Read the pool; UI stays yours.
const WalletPicker = () => {
const wallets = useDiscoveredWallets();
const { connect } = useConnect();
const isHydrated = useIsHydrated();
// Wait for persisted connections before showing the picker.
if (!isHydrated) return null;
return wallets.map(({ id, name }) => (
<button key={id} onClick={() => connect(id)} type="button">
Connect {name}
</button>
));
};Supported chains
One discovery seam across EVM networks, Solana, Sui, Bitcoin, and Polkadot: EIP-6963, the Wallet Standard, injected fallbacks, and injectedWeb3.
- Ethereum
- Solana
- Bitcoin
- Base
- Arbitrum
- Optimism
- Polygon
- BNB Chain
- Sui
- Polkadot
Hand the signer to your library.
getSigner() hands back the wallet's own provider, tagged by kind. Wrap it with viem, wagmi, gill, or @solana/kit and keep the stack you already have.
import {
useSelectedWallet,
useSigner,
} from "@usebutr/react";
import {
createWalletClient,
custom,
getAddress,
} from "viem";
import { sepolia } from "viem/chains";
export const useSelectedWalletClient = () => {
const wallet = useSelectedWallet("evm");
const { data: signer } = useSigner(wallet);
if (!wallet || signer?.kind !== "eip1193") return null;
return createWalletClient({
account: getAddress(wallet.account.walletAddress),
chain: sepolia,
transport: custom(signer.provider),
});
};Get started in a few lines.
Install, quickstart, core concepts, and the full API reference are in the docs.