Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

Bitcoin is exposed as a first-class module on the headless React Native client — dynamicClient.bitcoin — alongside dynamicClient.wallets, dynamicClient.auth, and the chain extensions. There is no separate BitcoinExtension to install: the module ships with @dynamic-labs/client and routes all calls through the embedded WebView, which already includes the Bitcoin wallet connectors and a BitcoinController that handles the bridge messages.

Checking if a wallet is a Bitcoin wallet

React Native
import { dynamicClient } from '<path to client file>';

const wallet = dynamicClient.wallets.primary;
if (!wallet || wallet.chain !== 'BTC') {
  throw new Error('This wallet is not a Bitcoin wallet');
}
wallet.chain returns one of 'EVM' | 'SOL' | 'BTC' | 'SUI' | 'TON', so you can branch on it generically. To list every Bitcoin wallet the user has connected:
React Native
const btcWallets = dynamicClient.wallets.userWallets.filter(
  (w) => w.chain === 'BTC',
);

Configuring the client

Bitcoin support is enabled the moment you create the client; no extension is required. You may optionally pass bitcoinNetworks to override the dashboard network list (custom entries win on chainId conflicts).
import { createClient } from '@dynamic-labs/client';
import { ReactNativeExtension } from '@dynamic-labs/react-native-extension';
import { WebExtension } from '@dynamic-labs/web-extension';

export const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
  appName: 'Your App',
  appLogoUrl: 'https://your-domain.com/logo.png',
})
  .extend(ReactNativeExtension({ appOrigin: 'https://your-domain.com' }))
  .extend(WebExtension({}));

The dynamicClient.bitcoin module

Every method takes a walletId (string) — typically read from wallet.id of a wallet you’ve already filtered by chain === 'BTC'.
MethodPurpose
signMessageSign a message using ECDSA or BIP-322.
signPsbtSign a single PSBT (BIP-174).
signPsbtsSign a batch of PSBTs in one call.
sendBitcoinHigh-level transfer (build, sign, broadcast in one step).
buildPsbtBuild an unsigned PSBT for a transfer; sign and broadcast yourself.
sendRawTransactionBroadcast an already-signed raw transaction hex.
getBalanceReturns the wallet’s balance in satoshis (as a string).

Sign a message

signMessage accepts a protocol ('ecdsa' | 'bip322-simple') and an addressType ('payment' | 'ordinals'). When omitted, the connector chooses sensible defaults.
React Native
const wallet = dynamicClient.wallets.userWallets.find((w) => w.chain === 'BTC');
if (!wallet) throw new Error('No Bitcoin wallet');

const { signature } = await dynamicClient.bitcoin.signMessage({
  walletId: wallet.id,
  message: 'Hello, Bitcoin!',
  protocol: 'bip322-simple',
  addressType: 'payment',
});

Get balance

React Native
const wallet = dynamicClient.wallets.userWallets.find((w) => w.chain === 'BTC');
if (!wallet) throw new Error('No Bitcoin wallet');

const { balance } = await dynamicClient.bitcoin.getBalance({
  walletId: wallet.id,
});

// balance is a satoshi-denominated string. Convert to BTC for display:
const btc = Number(balance) / 1e8;

Embedded vs external Bitcoin wallets

Connecting a Bitcoin wallet works the same as any other chain — once you’ve enabled Bitcoin connectors in the dashboard, users see them in the auth flow. You do not need to install or import @dynamic-labs/bitcoin in the React Native app; the connectors live inside the WebView SDK.
  • Embedded (MPC) Bitcoin wallets — derived from the same root entropy as the user’s other embedded wallets, but with a Bitcoin-specific derived key. The private key is never reconstructed in your app; signing happens through the MPC ceremony.
  • External Bitcoin wallets — Phantom, Unisat, Xverse (sats-connect), OKX, OneKey, MagicEden, Bitget, Binance, Oyl, plus a fallback connector. The signing protocol depends on the connector — signMessage’s protocol parameter respects what the underlying wallet supports.
A single user session can hold multiple wallets across chains. Filter by wallet.chain to find the right one.

Examples

  • Send Bitcoin — high-level transfer using dynamicClient.bitcoin.sendBitcoin.
  • Sign and broadcast a PSBT — work with PSBTs directly via buildPsbt, signPsbt, signPsbts, and sendRawTransaction.