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.
Overview
This guide shows you how to work with imported Bitcoin wallets for common operations. Once you’ve imported a private key, you can perform various wallet operations directly.
Prerequisites
Step 1: Check Wallet Balance
Check the Bitcoin balance of your imported wallet using a block explorer API:
const address = 'bc1q...your-imported-wallet-address';
// Using Blockstream API
const response = await fetch(
`https://blockstream.info/api/address/${address}`
);
const data = await response.json();
const balanceSats = data.chain_stats.funded_txo_sum - data.chain_stats.spent_txo_sum;
const balanceBtc = balanceSats / 100_000_000;
console.log('Balance:', balanceSats, 'satoshis');
console.log('Balance in BTC:', balanceBtc);
Step 2: Get UTXOs for Your Wallet
Before sending transactions, you need to fetch available UTXOs:
const address = 'bc1q...your-imported-wallet-address';
// Fetch UTXOs using Blockstream API
const response = await fetch(
`https://blockstream.info/api/address/${address}/utxo`
);
const utxos = await response.json();
console.log('Available UTXOs:', utxos);
// Output: [{ txid: '...', vout: 0, value: 50000, status: {...} }, ...]
Step 3: Sign Transactions with Imported Wallet
Use your imported wallet to sign Bitcoin transactions:
import * as bitcoin from 'bitcoinjs-lib';
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
const btcClient = await authenticatedBtcClient();
const walletAddress = 'bc1q...your-imported-wallet-address';
// Create PSBT with your UTXO
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin });
// Add input from your wallet
psbt.addInput({
hash: 'previous_txid',
index: 0,
witnessUtxo: {
script: bitcoin.address.toOutputScript(walletAddress, bitcoin.networks.bitcoin),
value: 50000, // satoshis
},
});
// Add output
psbt.addOutput({
address: 'bc1q...recipient-address',
value: 40000, // satoshis (minus fee)
});
// Sign with imported wallet
const signedPsbt = await btcClient.signTransaction({
transaction: psbt.toBase64(),
senderAddress: walletAddress,
network: BitcoinNetwork.MAINNET,
});
console.log('Signed PSBT (base64):', signedPsbt);
Step 4: Sign Messages with Imported Wallet
Sign messages for authentication or data integrity:
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
const message = 'Hello from my imported Bitcoin wallet!';
const signature = await btcClient.signMessage({
message,
accountAddress: 'bc1q...your-imported-wallet-address',
network: BitcoinNetwork.MAINNET,
});
// Returns BIP-322 signature in base64 format
console.log('Message signed (base64):', signature);
Complete Example: Sign and Send from Imported Wallet
import * as bitcoin from 'bitcoinjs-lib';
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
export const signAndSendFromImportedWallet = async ({
walletAddress,
recipientAddress,
amountSats,
feeSats,
}: {
walletAddress: string;
recipientAddress: string;
amountSats: number;
feeSats: number;
}) => {
const btcClient = await authenticatedBtcClient();
const network = bitcoin.networks.bitcoin;
// Step 1: Fetch UTXOs
const utxoResponse = await fetch(
`https://blockstream.info/api/address/${walletAddress}/utxo`
);
const utxos = await utxoResponse.json();
if (utxos.length === 0) {
throw new Error('No UTXOs available');
}
// Step 2: Select UTXOs (simple selection - use first one)
const utxo = utxos[0];
// Step 3: Create PSBT
const psbt = new bitcoin.Psbt({ network });
psbt.addInput({
hash: utxo.txid,
index: utxo.vout,
witnessUtxo: {
script: bitcoin.address.toOutputScript(walletAddress, network),
value: utxo.value,
},
});
// Add recipient output
psbt.addOutput({
address: recipientAddress,
value: amountSats,
});
// Add change output if needed
const change = utxo.value - amountSats - feeSats;
if (change > 546) { // Dust threshold
psbt.addOutput({
address: walletAddress,
value: change,
});
}
// Step 4: Sign
const signedPsbtBase64 = await btcClient.signTransaction({
transaction: psbt.toBase64(),
senderAddress: walletAddress,
network: BitcoinNetwork.MAINNET,
});
// Step 5: Finalize and extract
const signedPsbt = bitcoin.Psbt.fromBase64(signedPsbtBase64);
signedPsbt.finalizeAllInputs();
const rawTx = signedPsbt.extractTransaction().toHex();
// Step 6: Broadcast
const broadcastResponse = await fetch('https://blockstream.info/api/tx', {
method: 'POST',
body: rawTx,
});
const txid = await broadcastResponse.text();
console.log('Transaction broadcasted:', txid);
return txid;
};
List All Bitcoin Wallets
Get all Bitcoin wallets associated with your account:
const btcWallets = await btcClient.getBitcoinWallets();
console.log('Bitcoin wallets:', btcWallets.length);
btcWallets.forEach(wallet => {
console.log(`- ${wallet.accountAddress} (${wallet.chainName})`);
});
Best Practices
- Balance Checking: Verify sufficient balance before sending transactions
- UTXO Management: Select UTXOs efficiently to minimize fees
- Fee Estimation: Use current fee rates from mempool APIs
- Error Handling: Implement proper error handling for all wallet operations
- Security: Never expose sensitive information in server-side code
- Network Selection: Use testnet for development and testing
Fee Estimation
Estimate appropriate fees before sending:
// Fetch recommended fee rates
const feeResponse = await fetch('https://blockstream.info/api/fee-estimates');
const feeEstimates = await feeResponse.json();
// feeEstimates contains sat/vB for different confirmation targets
// e.g., { "1": 25, "3": 15, "6": 10 } means:
// - 25 sat/vB for ~1 block confirmation
// - 15 sat/vB for ~3 block confirmation
// - 10 sat/vB for ~6 block confirmation
// For Native SegWit P2WPKH: ~110 vBytes for 1-in-1-out tx
const estimatedFee = feeEstimates["3"] * 110; // sat for ~3 block confirmation
Next Steps