butr
API reference

@usebutr/svm

Wallet Standard discovery, the adapter builder, and the Solana feature types.

Discovery

discoverSvmAdapters(onAdapter, loadModule?): () => void

Subscribes to Wallet Standard registrations and announces one adapter per wallet that advertises a solana: chain and standard:connect. Lazily imports @wallet-standard/app, an optional peer dependency; without it discovery logs one warning and does nothing. loadModule injects a registry for tests. It is a WalletSource as-is:

import type { WalletManagerConfig } from "@usebutr/core";
import { discoverSvmAdapters } from "@usebutr/svm";

const config: WalletManagerConfig = { sources: [discoverSvmAdapters] };

svmDiscoverer: PlatformDiscoverer

Wallet Standard only; Solana has no legacy injected path worth shimming.

Adapter builder

buildSvmAdapter(wallet, registerDisconnector?): SvmAdapter | null

Wraps a WalletStandardWallet, or returns null when it speaks no Solana. The id is slugify("svm", wallet.name), e.g. wallet-standard:svm-phantom. Each optional method exists only when the wallet advertises its feature:

MethodFeatureResolves
sendTxsolana:signAndSendTransactionThe base58 signature.
signMessagesolana:signMessage{ signature, signedMessage }.
signTransactionsolana:signTransactionThe signed transaction bytes.
signInsolana:signInSignInOutput.

disconnect needs standard:disconnect, and switchChain more than one advertised Solana cluster. There is no getBalance or getTransactionReceipt: they need an RPC client, which butr does not ship. See the Solana connector.

Signer

getSigner() resolves { kind: "wallet-standard", wallet }. Reach a feature with getFeature from @usebutr/wallet-standard-shared and the feature types below:

import type { SolanaSignInFeature } from "@usebutr/svm";
import { getFeature } from "@usebutr/wallet-standard-shared";

const signer = await wallet.connector.getSigner();
if (signer.kind === "wallet-standard") {
  const signIn = getFeature<SolanaSignInFeature>(signer.wallet, "solana:signIn", "signIn");
}

Transaction signing

prepareSolanaTransaction(tx, signer): SolanaSigningPayload

Import from @usebutr/svm/transaction to integrate a transport that returns a bare signature. This entry point loads no wallet discovery code.

tx is a serialized legacy or v0 transaction and signer its signer's base58 address. The helper validates the signature/header/key layout and rejects an account that is not a required signer. Instructions stay opaque. The result exposes message for device signing and withSignature(bytes), which inserts a 64-byte signature into the matching slot of a copy, preserving other signatures and the original input. Ledger and WalletConnect share this implementation.

Types

Solana feature shapes, narrowed to the fields butr reads:

  • SolanaSignMessageFeature, SolanaSignMessageInput, SolanaSignMessageOutput
  • SolanaSignAndSendTransactionFeature, SolanaSignAndSendTransactionInput, SolanaSignAndSendTransactionOutput
  • SolanaSignTransactionFeature, SolanaSignTransactionInput, SolanaSignTransactionOutput
  • SolanaSignInFeature, SolanaSignInInput, SolanaSignInOutput

The shared Wallet Standard types (WalletStandardWallet, WalletStandardWalletAccount, …) live in @usebutr/wallet-standard-shared. The Solana chain registry (SVM_CHAINS, SVM_CHAINS_LIST) lives in @usebutr/core.

Source: packages/svm/src/index.ts.