- 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>
114 lines
3.6 KiB
Markdown
114 lines
3.6 KiB
Markdown
---
|
|
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)
|