SVM-only setup
Ship @usebutr/react + @usebutr/svm with no @usebutr/evm or @usebutr/wallets in the bundle.
Pick this path when your app only touches Solana: a framework-kit, gill,
@solana/kit, @solana/wallet-adapter-react, or legacy @solana/web3.js app
with no EVM surface. You pass discoverSvmAdapters from @usebutr/svm as the
source instead of autoDiscovery() from @usebutr/wallets, and the EVM
packages never enter your bundle. The provider and hooks are identical to every
other setup.
Install
@usebutr/react gives you the provider and hooks, @usebutr/svm does Wallet Standard
discovery, and @usebutr/core has the config type and chain registries. No
@usebutr/wallets, no @usebutr/evm.
npm install @usebutr/react @usebutr/svm @usebutr/core zustand@usebutr/svm lazily imports @wallet-standard/app (an optional peer dependency).
Install it for discovery to work; if it is absent, SVM discovery logs a warning
once and does nothing rather than throwing.
npm install @wallet-standard/appProvider
discoverSvmAdapters is a wallet source as-is, so it goes straight into
sources. Define the config at module scope; the provider reads it once.
import type { WalletManagerConfig } from "@usebutr/core";
import { WalletManagerProvider } from "@usebutr/react";
import { discoverSvmAdapters } from "@usebutr/svm";
import type { ReactNode } from "react";
// SVM-only: no @usebutr/evm or @usebutr/wallets in the bundle.
const config: WalletManagerConfig = {
sources: [discoverSvmAdapters],
storageKeyPrefix: "butr-solana-web3js-demo",
};
const WalletProvider = ({ children }: { children: ReactNode }) => (
<WalletManagerProvider config={config}>{children}</WalletManagerProvider>
);
export { WalletProvider };demo-with-solana-framework-kit, demo-with-gill, demo-with-solana-kit,
demo-with-solana-wallet-adapter, and demo-with-solana-web3js all use this
pattern, each with its own storageKeyPrefix.
Every wallet in this app is an SVM wallet, so read it with
useSelectedWallet("svm"): it is typed ConnectedWallet<"svm">, and its
sendTx and signTransaction take transaction bytes with no narrowing.
The bundle guarantee
The isolation is not a flag; it is your import graph. @usebutr/svm depends only
on @usebutr/core and @usebutr/wallet-standard-shared; it carries no EVM or
EIP-6963 code. autoDiscovery() lives in @usebutr/wallets, which depends on
every platform package, so importing it would pull EVM in. Here you import
discoverSvmAdapters from @usebutr/svm directly, so @usebutr/evm and
@usebutr/wallets are never referenced and the bundler tree-shakes them out
("sideEffects": false is set on every package). See
Platforms.
Chains
Every chain registry lives in @usebutr/core as plain data, so importing only
the Solana list bundles only the Solana list:
import { SVM_CHAINS, SVM_CHAINS_LIST } from "@usebutr/core";SVM_CHAINS is keyed (mainnet, devnet, testnet) and SVM_CHAINS_LIST is
the same as an array. These use Wallet Standard shortnames (solana:mainnet,
not the strict CAIP-2 genesis-hash form) because that is what real wallets
(Phantom, Solflare, Backpack) advertise in wallet.chains. Pass one as
sendTx's chain to route a single transaction, for example to
SVM_CHAINS.devnet.
Capabilities and caveats
@usebutr/svm discovers wallets via the
Wallet Standard. Because it
lazily imports @wallet-standard/app, there is an asynchronous warmup: a
restored wallet can sit in pendingIds for a moment before it resolves; see
Hydration.
An SVM adapter defines each method only when the wallet advertises the matching feature:
| Method | Feature |
|---|---|
sendTx | solana:signAndSendTransaction |
signMessage | solana:signMessage |
signTransaction | solana:signTransaction |
signIn | solana:signIn |
switchChain | more than one Solana chain in wallet.chains |
There is no requestAccounts (Wallet Standard wallets expose every account at
once), no getBalance, and no getTransactionReceipt: read those with your
own RPC client. Check for a method before you call it; see
capabilities.
getSigner() on an SVM adapter resolves { kind: "wallet-standard", wallet };
reach any other feature with getFeature from @usebutr/wallet-standard-shared,
or bridge into a Solana library. See the integration pages for the full
build-and-send flow.
Next steps
- Solana Wallet Standard connector: the discovery and signer detail.
- framework-kit / gill / solana-kit / solana-wallet-adapter / solana-web3js (legacy): build and send transactions.
- Provider setup: auto discovery, single platforms, and WalletConnect or Ledger alongside.
Source: apps/demo-with-solana-web3js/src/wallet-provider.tsx,
apps/demo-with-solana-kit/src/wallet-provider.tsx, and
apps/demo-with-solana-wallet-adapter/src/wallet-provider.tsx in the butr
repository.