Bitcoin FAQ for Agents
Frequently asked questions about Bitcoin for AI agents. Common queries, troubleshooting, and best practices.
Bitcoin FAQ for Agents
Common questions and answers for AI agents working with Bitcoin.
General Questions
What is the minimum amount I can send?
The practical minimum is the dust threshold plus fees:
- P2WPKH dust: 294 sats
- Minimum transaction: ~400-500 sats (dust + minimum fee)
At 10 sat/vB fees, a simple P2WPKH transaction costs 1,400 sats ($1.40 at $100k/BTC).
How long until my transaction confirms?
Depends on fee rate and network congestion:
| Fee Rate | Typical Wait |
|---|---|
| fastestFee | ~10 minutes (next block) |
| halfHourFee | ~30 minutes (1-3 blocks) |
| hourFee | ~1 hour (6 blocks) |
| economyFee | Hours to days |
Check current rates: https://mempool.space/api/v1/fees/recommended
How many confirmations should I wait for?
| Transaction Value | Recommended Confirmations |
|---|---|
| < $100 | 1 confirmation |
| $100 - $1,000 | 2-3 confirmations |
| $1,000 - $10,000 | 6 confirmations |
| > $10,000 | 6+ confirmations |
For high-value transactions, 6 confirmations (~1 hour) is industry standard.
Can I cancel a Bitcoin transaction?
Unconfirmed: Yes, with RBF or CPFP
- RBF: Replace with same inputs, higher fee, different output (send to yourself)
- CPFP: Spend the output back to yourself with high fee
Confirmed: No. Bitcoin transactions are irreversible.
What if I send to the wrong address?
- Valid address you don’t control: Funds are lost unless owner returns them
- Invalid address: Transaction won’t broadcast (checksum fails)
- Valid but unspendable (OP_RETURN, script hash without script): Funds are lost
Prevention: Always validate addresses before sending.
Technical Questions
Which address format should I use?
Recommendation: Native SegWit (bc1q) for most use cases.
| Format | Use When |
|---|---|
| P2WPKH (bc1q) | Default choice, lowest fees |
| P2TR (bc1p) | Privacy important, advanced scripts |
| P2SH (3…) | Compatibility with old systems |
| P2PKH (1…) | Legacy system requirement |
How do I validate a Bitcoin address?
- Check prefix matches network (mainnet: 1, 3, bc1)
- Verify checksum (Base58Check or Bech32)
- Confirm length is correct for type
import re
def validate_address(address):
patterns = {
'p2pkh': r'^1[a-km-zA-HJ-NP-Z1-9]{25,34}$',
'p2sh': r'^3[a-km-zA-HJ-NP-Z1-9]{33}$',
'p2wpkh': r'^bc1q[a-z0-9]{38,39}$',
'p2tr': r'^bc1p[a-z0-9]{58}$'
}
for addr_type, pattern in patterns.items():
if re.match(pattern, address):
return {'valid': True, 'type': addr_type}
return {'valid': False}
Why is my transaction stuck?
Common causes:
- Fee too low: Network congestion, your fee rate below mempool minimum
- RBF not enabled: Can’t bump fee
- Inputs unconfirmed: Parent transaction also stuck
Solutions:
- If RBF enabled: Broadcast replacement with higher fee
- If you’re the recipient: Use CPFP
- Wait: Transactions eventually drop from mempool (~2 weeks)
How do I estimate transaction size?
Base: ~10.5 vB
Per P2WPKH input: ~68 vB
Per P2TR input: ~57.5 vB
Per output: ~31-34 vB
Example (1 input, 2 outputs, P2WPKH):
10.5 + 68 + (31 × 2) = ~141 vB
What’s the difference between txid and wtxid?
- txid: Hash of transaction without witness data
- wtxid: Hash including witness data
For non-SegWit transactions, txid = wtxid.
Use txid for transaction identification and references.
Security Questions
How should I store private keys?
| Security Level | Method |
|---|---|
| Testing | Environment variable |
| Low value | Encrypted file (AES-256) |
| Medium value | Hardware wallet, HSM |
| High value | Multi-sig, cold storage |
Never:
- Log private keys
- Store in source code
- Use predictable generation
Is it safe to reuse addresses?
Not recommended:
- Reduces privacy (links transactions)
- Potential cryptographic concerns (key reuse)
- Complicates UTXO tracking
Best practice: Generate new address for each transaction.
How do I verify a payment was received?
- Check address has new UTXO
- Verify UTXO value matches expected amount
- Wait for required confirmations
- Confirm transaction is in a block on the longest chain
def verify_payment(address, expected_amount, min_confirmations=1):
utxos = requests.get(f"https://mempool.space/api/address/{address}/utxo").json()
tip = int(requests.get("https://mempool.space/api/blocks/tip/height").text)
for utxo in utxos:
if utxo['value'] >= expected_amount:
if utxo['status']['confirmed']:
confirmations = tip - utxo['status']['block_height'] + 1
if confirmations >= min_confirmations:
return {'verified': True, 'txid': utxo['txid'], 'confirmations': confirmations}
return {'verified': False}
API Questions
Which API should I use?
| API | Best For |
|---|---|
| mempool.space | General purpose, free, reliable |
| blockstream.info | Alternative, similar features |
| Bitcoin Core RPC | Full node access, complete data |
| Electrum | Lightweight, wallet-focused |
Recommendation: Start with mempool.space API.
How do I handle API rate limits?
- Cache responses (addresses, transactions rarely change)
- Batch requests when possible
- Implement exponential backoff on 429 errors
- Run your own node for high volume
import time
def api_request_with_retry(url, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
wait_time = 2 ** attempt
time.sleep(wait_time)
else:
response.raise_for_status()
raise Exception("Max retries exceeded")
How do I broadcast a transaction?
curl -X POST https://mempool.space/api/tx \
-H "Content-Type: text/plain" \
-d "0200000001..."
Returns txid on success, error message on failure.
Common errors:
bad-txns-inputs-missingorspent: Input already spentinsufficient fee: Fee below minimumnon-mandatory-script-verify-flag: Invalid signature
Wallet Questions
Should I use a custodial or non-custodial wallet?
| Custodial | Non-Custodial |
|---|---|
| Quick setup | Full control |
| No key management | Key responsibility |
| Counterparty risk | No counterparty risk |
| Compliance friendly | Privacy friendly |
For agents: Non-custodial preferred for autonomy. Custodial for compliance requirements.
How do I generate a new wallet?
const bip39 = require('bip39');
const { BIP32Factory } = require('bip32');
const ecc = require('tiny-secp256k1');
// Generate mnemonic
const mnemonic = bip39.generateMnemonic(256);
// Derive seed and master key
const seed = bip39.mnemonicToSeedSync(mnemonic);
const bip32 = BIP32Factory(ecc);
const root = bip32.fromSeed(seed);
// Get xpub for account 0
const account = root.derivePath("m/84'/0'/0'");
const xpub = account.neutered().toBase58();
console.log('Mnemonic (SECURE!):', mnemonic);
console.log('xpub (safe to share):', xpub);
What’s the gap limit?
HD wallets scan sequential addresses until finding N consecutive unused addresses (gap limit). Default is typically 20.
If you generate addresses non-sequentially, wallet may not find all funds.
Network Questions
What’s the difference between mainnet, testnet, and signet?
| Network | Purpose | Coins |
|---|---|---|
| Mainnet | Production | Real BTC |
| Testnet | Testing | Free (faucets) |
| Signet | Testing | Free, more stable |
| Regtest | Local testing | Self-generated |
For development: Use testnet or signet. Never test with real BTC.
Where can I get testnet coins?
- https://coinfaucet.eu/en/btc-testnet/
- https://testnet-faucet.mempool.co/
- https://bitcoinfaucet.uo1.net/
Signet:
Machine-Readable Summary
{
"topic": "bitcoin-faq",
"question_count": 25,
"categories": ["general", "technical", "security", "api", "wallet", "network"],
"key_recommendations": {
"address_format": "p2wpkh",
"api": "mempool.space",
"confirmations": "6 for high value",
"wallet_type": "non-custodial"
}
}