butr
Integrations

wagmi

Adopt the wallet butr connected into @wagmi/core's own EIP-6963 connector, then use wagmi actions.

butr discovers and connects the wallet; @wagmi/core handles chain reads, signing, and transaction submission against that same wallet.

Build the wagmi config

wagmi runs its own EIP-6963 discovery, so the config needs no connectors. Keep the transport on plain RPC (http()) so reads do not hit the wallet.

import { createConfig, http } from "@wagmi/core";
import { sepolia } from "viem/chains";

export const wagmiConfig = createConfig({
  chains: [sepolia],
  transports: { [sepolia.id]: http() },
});

Adopt butr's wallet

An injected EVM adapter's id is the wallet's EIP-6963 rdns, which is also the id of wagmi's connector for that wallet. The wallet has already authorised the site through butr, so wagmi's reconnect adopts that authorisation silently; connect would prompt a second time.

import type { ConnectedWallet } from "@usebutr/core";
import { reconnect } from "@wagmi/core";

export const adoptWallet = async (wallet: ConnectedWallet<"evm">) => {
  const connector = wagmiConfig.connectors.find(({ id }) => id === wallet.connector.id);
  if (connector === undefined) {
    throw new Error(`wagmi found no connector for ${wallet.connector.name}`);
  }
  await reconnect(wagmiConfig, { connectors: [connector] });
};

Call it whenever useSelectedWallet("evm") changes.

Why not hand wagmi signer.provider? wagmi's injected({target}) types its provider as viem's fully typed EIP1193Provider, and butr's Eip1193Provider is deliberately looser, so it only fits with a cast. viem's custom() transport accepts it directly; see the viem integration.

Use wagmi actions

import { getBalance, sendTransaction, signMessage } from "@wagmi/core";
import { getAddress, parseEther } from "viem";

const balance = await getBalance(wagmiConfig, {
  address: getAddress(wallet.account.walletAddress),
});
const signature = await signMessage(wagmiConfig, { message: "Hello from butr + wagmi" });
const hash = await sendTransaction(wagmiConfig, {
  chainId: sepolia.id,
  to: BURN_ADDRESS,
  value: parseEther("0"),
});

Every signature and transaction goes to the wallet butr connected, not a mock.

Source: apps/demo-with-wagmi/src/app.tsx in the butr repository. Targets Sepolia. Run pnpm dev --filter=demo-with-wagmi → https://usebutr.demo-with-wagmi.localhost.