Skip to main content

Overview

This guide shows you how to sign Bitcoin transactions using Dynamic’s Node SDK. Bitcoin uses PSBTs (Partially Signed Bitcoin Transactions) for signing. You create a PSBT, pass it to signTransaction() as a base64 string, and receive the signed PSBT back.

Prerequisites

Step 1: Install Dependencies

These examples use bitcoinjs-lib v7, where satoshi amounts are bigint values (for example 50_000n), not numbers.

Step 2: Create and Sign a PSBT

The approach for signing transactions depends on how you created your wallet: If you created your wallet with backUpToDynamic: true, you can sign directly without retrieving key shares. walletMetadata is the object returned by createWalletAccount (or importPrivateKey), and password is the one you set at creation:

Signing on Testnet

For testnet, use bitcoin.networks.testnet for the PSBT and BitcoinNetwork.TESTNET for network. Build the PSBT with the wallet’s testnet address (tb1q...), which you get from deriveAccountAddress with network: BitcoinNetwork.TESTNET, and keep passing the walletMetadata from createWalletAccount unchanged:
A missing or incorrect network can make signing fail with No inputs found that belong to the account address. See Working with testnet.

With Manual Backup

If you created your wallet with backUpToDynamic: false, you must retrieve and provide external key shares:
Password Handling Notes:
  • If your wallet was created without a password, omit the password parameter
  • If your wallet was created with a password, you must provide it for all operations
  • Wallets created with backUpToDynamic: true always have a password, because one is required at creation

Step 3: Finalize and Broadcast

After signing, finalize the PSBT and extract the raw transaction for broadcasting:

Complete Example: Send Bitcoin

Here’s a complete example of creating, signing, and broadcasting a Bitcoin transaction:

Taproot Transaction Signing

For Taproot addresses, the signing process is the same, but uses Schnorr signatures internally:
In @dynamic-labs-wallet/node-btc 1.1.52, signing a Taproot transaction fails with Uint8Array expected. Native SegWit wallets sign transactions correctly.

Multi-Input Transactions

The SDK only signs inputs that belong to the sender address. Other inputs remain unsigned:

Error Handling

Next Steps

Last modified on October 27, 2026