> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Bitcoin Wallets

> Sign messages, send Bitcoin, and work with PSBTs from a React Native client

> [card] Recommended: JavaScript SDK for React Native
>
> While this SDK is still supported, we recommend using newer [JavaScript SDK](https://docs.dynamic.xyz/docs/javascript/reference/react-native-quickstart.md), which is optimized for React Native, but also comes with a host of other benefits.

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/legacy-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

```ts React Native theme={"system"}
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:

```ts React Native theme={"system"}
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 Dynamic Console network list (custom entries win on `chainId` conflicts).

```ts dynamicClient.ts theme={"system"}
import { createClient } from '@dynamic-labs/legacy-client';
import { ReactNativeExtension } from '@dynamic-labs/legacy-react-native-extension';
import { WebExtension } from '@dynamic-labs/legacy-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({}));
```

```ts dynamicClient.ts (custom Bitcoin network) theme={"system"}
import { createClient } from '@dynamic-labs/legacy-client';
import { ReactNativeExtension } from '@dynamic-labs/legacy-react-native-extension';
import { WebExtension } from '@dynamic-labs/legacy-web-extension';

export const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
  bitcoinNetworks: [
    {
      chainId: 0,
      networkId: 0,
      name: 'Bitcoin Mainnet',
      rpcUrls: ['https://your-bitcoin-rpc.example.com'],
      nativeCurrency: { name: 'Bitcoin', symbol: 'BTC', decimals: 8 },
      blockExplorerUrls: ['https://mempool.space'],
    },
  ],
})
  .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'`.

| Method | Purpose |
| - | - |
| `signMessage` | Sign a message using ECDSA or BIP-322. |
| `signPsbt` | Sign a single PSBT (BIP-174). |
| `signPsbts` | Sign a batch of PSBTs in one call. |
| `sendBitcoin` | High-level transfer (build, sign, broadcast in one step). |
| `buildPsbt` | Build an unsigned PSBT for a transfer; sign and broadcast yourself. |
| `sendRawTransaction` | Broadcast an already-signed raw transaction hex. |
| `getBalance` | Returns 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.

```ts React Native theme={"system"}
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

```ts React Native theme={"system"}
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 Dynamic Console, 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](https://docs.dynamic.xyz/docs/react-native/wallets/using-wallets/bitcoin/send-bitcoin.md) — high-level transfer using `dynamicClient.bitcoin.sendBitcoin`.
* [Sign and broadcast a PSBT](https://docs.dynamic.xyz/docs/react-native/wallets/using-wallets/bitcoin/sign-psbt.md) — work with PSBTs directly via `buildPsbt`, `signPsbt`, `signPsbts`, and `sendRawTransaction`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.