Dorian 4e54b8bd4d feat: add YAML frontmatter, bitcoin-conventions skill, path rules, and Gitea CI
- Added YAML frontmatter to all 8 polish-* skills and sweep skill
  so Claude can auto-invoke them
- New bitcoin-conventions skill with PROUX UX methodology, sats display,
  address validation, Tor preferences, Lightning patterns
- Path-specific rules for containers (security hardening) and frontend
  (Vue/glassmorphism conventions)
- Gitea Actions: nightly security review and weekly dependency audit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:35:17 +00:00

3.6 KiB

name, description
name description
bitcoin-conventions 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

// 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

// 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

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)