Overview
Every connector reaches butr through config.sources, discovered or built, and defines only the methods that work for it.
A connector is a WalletAdapter. Every one reaches the manager through
config.sources, in one of two ways:
- Discovered: browser wallets announce themselves.
@usebutr/evmlistens for EIP-6963;@usebutr/svm,@usebutr/suiand@usebutr/bitcoinlisten for the Wallet Standard;@usebutr/bitcoinalso probes injected providers such aswindow.unisat;@usebutr/polkadotreadswindow.injectedWeb3.autoDiscovery()from@usebutr/walletscomposes all of them, and eachdiscover*Adaptersexport is a source on its own. - Built: WalletConnect and Ledger are not injected into the page. Their
factories resolve adapters, and
fromAdaptersfrom@usebutr/coreturns an adapter, a list of them, or a promise of either into a source.
Both kinds land in useDiscoveredWallets() and connect the same way.
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";
const config: WalletManagerConfig = {
sources: [
autoDiscovery(),
fromAdapters(
createWalletConnectAdapters({
namespaces: { evm: [] },
onPairingUri: showQr,
projectId: "<your Reown project id>",
}),
),
fromAdapters(createLedgerAdapter({ platform: "evm" })),
],
};
export const Providers = ({ children }: { children: React.ReactNode }) => (
<WalletManagerProvider config={config}>{children}</WalletManagerProvider>
);Give each factory its own fromAdapters: a rejected promise is logged and
contributes nothing, so one factory that fails never hides the others. The
first adapter announced for an id wins.
| Connector | Package | Platforms | Reaches butr through | Signer kind |
|---|---|---|---|---|
| Injected EVM | @usebutr/evm | evm | EIP-6963, window.ethereum fallback | eip1193 |
| Solana Wallet Standard | @usebutr/svm | svm | Wallet Standard | wallet-standard |
| Sui Wallet Standard | @usebutr/sui | sui | Wallet Standard | wallet-standard |
| Bitcoin | @usebutr/bitcoin | bitcoin | Wallet Standard, injected fallbacks | wallet-standard, unisat, sats-connect |
| Polkadot | @usebutr/polkadot | polkadot | injectedWeb3, Wallet Standard fallback | polkadot-injected, wallet-standard |
| WalletConnect | @usebutr/walletconnect | evm svm sui bitcoin | fromAdapters | eip1193 (EVM), walletconnect |
| Ledger | @usebutr/ledger | evm svm sui bitcoin | fromAdapters | ledger-evm, ledger-svm, ledger-sui, ledger-bitcoin |
What each connector defines
A method exists only when calling it can succeed for that wallet, so check it before calling. ✓ means always, a feature name means only when the wallet advertises it.
| Method | Injected EVM | Wallet Standard (SVM, Sui, BTC) | Unisat-style | Xverse | Polkadot injected | WalletConnect EVM | WalletConnect SVM, Sui, BTC | Ledger |
|---|---|---|---|---|---|---|---|---|
signMessage | ✓ | its feature | ✓ | ✓ | after connect, with signRaw | ✓ | ✓ | not on Sui |
sendTx | ✓ | its feature | with sendBitcoin | ✓ | ✓ | ✓ | ||
signTransaction | its feature | ✓ | ✓ | ✓ | not on EVM | |||
signIn | solana:signIn | |||||||
switchChain | ✓ | 2+ chains advertised | with switchNetwork | ✓ | ✓ | 2+ chains configured | ||
requestAccounts | ✓ | |||||||
getBalance | ✓ | ✓ | ||||||
getTransactionReceipt | ✓ | ✓ | ||||||
subscribe | ✓ | ✓ | with on | ✓ | after connect, with accounts.subscribe | ✓ | ✓ | |
disconnect | ✓ | standard:disconnect | ✓ | ✓ | ✓ | ✓ | ✓ |
Polkadot's Wallet Standard adapters follow the Wallet Standard column, with
signMessage behind polkadot:signMessage and never sendTx or
signTransaction.
Chains and accounts
sendTx and signTransaction take { account, chain }. What a transport
does with a chain that is not its current one depends on what the wallet
can do:
| Transport | A different chain | switchChain |
|---|---|---|
| Injected EVM, WalletConnect EVM | Switches the wallet's network first (wallet_switchEthereumChain), then sends. | Switches the wallet's network. |
| Wallet Standard | Routes that one call; the wallet must advertise the chain. | Re-points butr's view; the wallet is not asked. |
| WalletConnect SVM, Sui, BTC | Routes that one call; the session must have approved the chain. | Re-points butr's view to another approved chain. |
| Unisat, Xverse | Switches the wallet's network first, or rejects with ChainMismatch when it cannot. | Switches the wallet's network, where the provider can. |
| Ledger | Rejects with ChainMismatch: build one adapter per chain. | None. |
| Polkadot | Not applicable: no sendTx, and signMessage takes no chain. | Wallet Standard only, with 2+ chains advertised. |
An account the wallet does not expose rejects everywhere. No adapter falls
back to its first account.