> ## 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.

# Sign and broadcast a PSBT

> Build, sign, and broadcast Bitcoin PSBTs (BIP-174) from React Native

For flows that need more control than [`sendBitcoin`](/react-native/wallets/using-wallets/bitcoin/send-bitcoin) — for example, inspecting outputs before signing, batching multiple PSBTs, or broadcasting a transaction signed offline — use the lower-level PSBT methods on `dynamicClient.bitcoin`.

## Build, sign, broadcast (three-step)

```ts React Native theme={"system"}
import { dynamicClient } from '<path to client file>';

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

// 1. Build an unsigned PSBT
const { psbtBase64 } = await dynamicClient.bitcoin.buildPsbt({
  walletId: wallet.id,
  recipientAddress: 'bc1q...',
  amount: '50000',
  feePriority: 'medium',
});

// 2. Sign the PSBT
const { signedPsbt } = await dynamicClient.bitcoin.signPsbt({
  walletId: wallet.id,
  request: {
    unsignedPsbtBase64: psbtBase64,
  },
});

// 3. Broadcast the signed transaction. signPsbt returns a signed PSBT;
//    if your flow finalizes and extracts the raw tx elsewhere, broadcast that.
const { txId } = await dynamicClient.bitcoin.sendRawTransaction({
  walletId: wallet.id,
  rawTransaction: signedPsbt, // pass the finalized hex when available
});
```

<Note>
  `signPsbt` returns a base64-encoded signed PSBT. Some wallets return a fully-finalized PSBT that can be extracted into a raw transaction; others return an intermediate PSBT that still needs finalization. If your application performs that step itself, finalize the PSBT before passing it to `sendRawTransaction`.
</Note>

## Sign with explicit signature requests

For inscriptions, RBF, or custom sighashes, pass a structured `request` to `signPsbt` with explicit signature entries:

```ts React Native theme={"system"}
const { signedPsbt } = await dynamicClient.bitcoin.signPsbt({
  walletId: wallet.id,
  request: {
    unsignedPsbtBase64: psbtBase64,
    allowedSighash: [1], // SIGHASH_ALL
    signature: [
      {
        address: 'bc1q...',         // your wallet's payment or ordinals address
        signingIndexes: [0, 1],     // which inputs to sign
        disableAddressValidation: false,
      },
    ],
  },
});
```

`allowedSighash` lists the sighash flags the wallet is allowed to use. `signature` describes per-address signing intent — useful when the PSBT references multiple inputs and you only want to sign a subset.

## Sign multiple PSBTs in one prompt

Some marketplaces and inscription flows produce several PSBTs that the user should approve together. `signPsbts` (plural) accepts a batch:

```ts React Native theme={"system"}
const { signedPsbts } = await dynamicClient.bitcoin.signPsbts({
  walletId: wallet.id,
  requests: [
    { allowedSighash: [1], unsignedPsbtBase64: 'psbt1...' },
    { allowedSighash: [1], unsignedPsbtBase64: 'psbt2...' },
  ],
});

// signedPsbts is an array in the same order as `requests`.
```

This shows a single confirmation in the WebView for the whole batch (where the underlying connector supports it; otherwise the SDK prompts sequentially).

## Broadcast a pre-signed transaction

If your app receives a fully-signed transaction hex from elsewhere (cold signer, partner backend, hardware wallet flow), broadcast it directly:

```ts React Native theme={"system"}
const { txId } = await dynamicClient.bitcoin.sendRawTransaction({
  walletId: wallet.id,
  rawTransaction: '02000000...',
});
```

The wallet's network determines which mempool the broadcast targets — make sure the signed transaction matches.

## Address types: payment vs ordinals

Bitcoin connectors typically maintain two addresses per wallet — one for plain BTC payments and one for ordinals/inscriptions. Methods that take an `addressType` (`'payment' | 'ordinals'`) let you choose; the default is `payment`. PSBTs that move ordinals should be built against the ordinals address and signed with `addressType: 'ordinals'` or by providing an explicit `signature[].address` matching that address.
