--- name: bitcoin-conventions description: Bitcoin development conventions for Archipelago. Covers sats display (integers, never float), address type detection, Tor/onion endpoint preference, Bitcoin RPC error handling, and Lightning patterns. Use when working with Bitcoin amounts, addresses, RPC calls, Lightning channels, or onion services. --- # Bitcoin Development Conventions ## Critical Rules - **NEVER use floating point for Bitcoin amounts.** Sats are always `u64` (Rust) or `BigInt`/integer (TypeScript). - **NEVER log private keys, seeds, or mnemonics.** Not even at debug/trace level. - **Prefer Tor/onion endpoints** for all Bitcoin network services when available. ## Amount Display ### Rust ```rust // Amount is always in sats as u64 pub fn format_sats(sats: u64) -> String { if sats >= 100_000_000 { let btc = sats / 100_000_000; let remainder = sats % 100_000_000; if remainder == 0 { format!("{} BTC", btc) } else { format!("{}.{:08} BTC", btc, remainder) } } else { format!("{} sats", sats) } } ``` ### TypeScript ```typescript // Never: amount * 0.00000001 // Always: integer arithmetic or BigInt function formatSats(sats: number): string { if (sats >= 100_000_000) { const btc = Math.floor(sats / 100_000_000) const remainder = sats % 100_000_000 return remainder === 0 ? `${btc} BTC` : `${btc}.${String(remainder).padStart(8, '0')} BTC` } return `${sats.toLocaleString()} sats` } ``` ## Address Types Detect and display address type: - `1...` — P2PKH (Legacy) - `3...` — P2SH (SegWit-compatible) - `bc1q...` — P2WPKH (Native SegWit) - `bc1p...` — P2TR (Taproot) Always validate addresses before any operation. Use network-appropriate validation (mainnet `bc1`, testnet `tb1`, regtest `bcrt1`). ## Bitcoin RPC Error Handling ```rust match rpc_response.error { Some(err) => { // Standard Bitcoin Core RPC error codes match err.code { -1 => /* miscellaneous error */, -5 => /* invalid address or key */, -6 => /* insufficient funds */, -25 => /* transaction verification failed */, -26 => /* transaction rejected by policy */, -27 => /* transaction already in chain */, -28 => /* client still warming up */, _ => /* unknown error */, } } None => { /* success */ } } ``` Always set explicit timeouts on RPC calls (10s default, 30s for heavy operations like `rescanblockchain`). ## Tor/Onion Preferences When configuring Bitcoin services: 1. Check for Tor SOCKS proxy (default: `127.0.0.1:9050`) 2. If available, route Bitcoin P2P and RPC through Tor 3. Prefer `.onion` endpoints for block explorers, electrum servers 4. Set `proxy=127.0.0.1:9050` in `bitcoin.conf` 5. Set `onlynet=onion` for maximum privacy (if full Tor mode) ## Lightning (LND/CLN) Patterns ### BOLT11 Invoice handling - Always validate invoice before displaying to user - Show: amount, description, expiry, destination pubkey - Never auto-pay without user confirmation ### Channel States Display human-readable channel state: - `PENDING_OPEN` → "Opening..." - `OPEN` → "Active" - `PENDING_CLOSE` / `FORCE_CLOSING` → "Closing..." - `CLOSED` → "Closed" ### Macaroon handling - Never log macaroon contents - Store with restrictive permissions (0600) - Use read-only macaroon for queries, admin macaroon only for mutations ## Container Images for Bitcoin Services - **Always pin by SHA256 digest**, never by tag alone - Example: `docker.io/lnzap/lnd@sha256:abc123...` not `lnzap/lnd:latest` - Verify image signatures when available (cosign/notary)