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.

Overview

BitcoinModule provides native Bitcoin operations: message signing, PSBT signing, sending Bitcoin, building PSBTs, broadcasting raw transactions, and balance queries. Access it via DynamicSDK.getInstance().bitcoin.

Prerequisites

Get a Bitcoin Wallet

There are two paths to a Bitcoin wallet: filter the user’s existing wallets, or create a new one explicitly.

Filter existing wallets

If Bitcoin is enabled and the user has a Bitcoin wallet (created automatically at signup), find it via userWallets:
val sdk = DynamicSDK.getInstance()

val btcWallet = sdk.wallets.userWallets.firstOrNull { it.chain == "BTC" }
  ?: error("No Bitcoin wallet found")

println("Bitcoin address: ${btcWallet.address}")

Create a new Bitcoin wallet

Call createWallet with EmbeddedWalletChain.BTC:
val wallet = sdk.wallets.embedded.createWallet(chain = EmbeddedWalletChain.BTC)
println("Created: ${wallet.address}")
Bitcoin wallets are derived as Native SegWit (bc1q…) by default. Mainnet is the only network supported today.

What is a satoshi?

A satoshi is the smallest unit of Bitcoin — 1 BTC = 100,000,000 satoshis. All amount fields in the Bitcoin module (sendBitcoin, buildPsbt, getBalance) are expressed in satoshis, not BTC.

What is a PSBT?

A Partially Signed Bitcoin Transaction (PSBT) is a standard for transactions that have not yet been fully signed. It lets different participants with different keys sign a transaction without sharing private keys, enabling safer multi-step or multi-sig flows.

Get Balance

Query the Bitcoin balance (in satoshis) for a wallet:
val sdk = DynamicSDK.getInstance()
val wallet = sdk.wallets.userWallets.first { it.chain == "BTC" }

val balance = sdk.bitcoin.getBalance(walletId = wallet.id)
println("Balance: $balance satoshis")

Sign a Message

Sign a message using ECDSA (default) or BIP-322:
val signature = sdk.bitcoin.signMessage(
  walletId = wallet.id,
  message = "Hello, Bitcoin!"
)
println("Signature: $signature")
For BIP-322 signing, pass the protocol and optional addressType:
val signature = sdk.bitcoin.signMessage(
  walletId = wallet.id,
  message = "Hello, Bitcoin!",
  protocol = "bip322-simple",
  addressType = "payment"
)

Send Bitcoin

Send BTC to a recipient. Returns the transaction ID.
val txId = sdk.bitcoin.sendBitcoin(
  walletId = wallet.id,
  recipientAddress = "bc1q...",
  amount = "10000",       // satoshis
  feePriority = "medium"  // optional: "high" | "medium" | "low"
)
println("TX ID: $txId")

Build a PSBT

Build an unsigned PSBT (base64-encoded) you can sign later or hand off to another signer:
val psbtBase64 = sdk.bitcoin.buildPsbt(
  walletId = wallet.id,
  recipientAddress = "bc1q...",
  amount = "10000",
  feePriority = "medium" // optional
)

Sign PSBTs

Sign a single PSBT, or batch-sign multiple PSBTs:
// Single
val signed = sdk.bitcoin.signPsbt(
  walletId = wallet.id,
  unsignedPsbtBase64 = psbtBase64
)

// Batch
val signedList = sdk.bitcoin.signPsbts(
  walletId = wallet.id,
  requests = listOf(
    buildJsonObject { put("unsignedPsbtBase64", psbtBase64) }
  )
)

Send a Raw Transaction

Broadcast a pre-signed transaction in hex form:
val txId = sdk.bitcoin.sendRawTransaction(
  walletId = wallet.id,
  rawTransactionHex = "0200000001..."
)

API Reference

MethodReturnsDescription
getBalanceStringGet wallet balance in satoshis
signMessageStringSign a message (ECDSA or BIP-322)
sendBitcoinStringSend BTC, returns transaction ID
buildPsbtStringBuild unsigned PSBT (base64)
signPsbtStringSign a single PSBT
signPsbtsList<String>Sign multiple PSBTs
sendRawTransactionStringBroadcast a raw transaction hex

Next Steps