diff --git a/.gitignore b/.gitignore index f55cc5f..5f6286c 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,3 @@ settings.local.json # Local agent/tooling metadata .agents/ .codex/ -CLAUDE.md - -blueprint.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d23d67f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Cos'è questo progetto + +Wallet desktop SPV (stile Sparrow) per la criptovaluta **Palladium (PLM)**, una catena UTXO derivata da Bitcoin. Solo Windows e Linux, niente mobile. **Lightning è esplicitamente escluso dal primo rilascio** (§11 del blueprint). + +**La fonte di verità è [blueprint.md](blueprint.md)**: specifica completa con parametri di consenso verificati contro il nodo, algoritmi, protocollo di rete e sequenza di costruzione. Prima di implementare qualsiasi funzionalità, leggere la sezione corrispondente del blueprint. La sequenza di costruzione da seguire è quella del §16 (profilo rete → crypto/chiavi → persistenza → rete → SPV → transazioni → GUI → hardware/multisig). + +## Stack + +.NET 8 + Avalonia UI + NBitcoin (§19 del blueprint). Struttura della solution: + +``` +PalladiumWallet.sln +├─ src/Core/ Chain/ Crypto/ Wallet/ Spv/ Net/ Storage/ (nessuna dipendenza UI) +├─ src/App/ Avalonia UI +├─ src/Cli/ CLI sullo stesso Core +└─ tests/ xUnit +``` + +**Regola di dipendenza non negoziabile:** `App` e `Cli` dipendono solo da `Core`; la GUI parla solo con l'Application API, mai direttamente con rete o crittografia. `Core` non conosce la UI. + +## Comandi + +Il .NET 8 SDK è installato in `~/.dotnet` (via dotnet-install.sh, senza root): nelle shell non interattive serve `export PATH="$HOME/.dotnet:$PATH" DOTNET_ROOT="$HOME/.dotnet"` prima dei comandi `dotnet`. + +- Build: `dotnet build` +- Test (headless, è il livello principale di verifica): `dotnet test` +- Singolo test: `dotnet test --filter "FullyQualifiedName~NomeTest"` +- CLI contro testnet/regtest: `dotnet run --project src/Cli -- ` +- GUI con hot reload: `dotnet watch --project src/App` + - Su questa macchina (WSL2 con WSLg) la finestra appare direttamente sul desktop Windows: niente X server o librerie da installare, è già tutto verificato funzionante. +- Publish Windows: `dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained` +- Publish Linux: `dotnet publish -r linux-x64 --self-contained` (poi AppImage via PupNet Deploy) + +La logica core e la crypto si testano senza GUI né rete reale; la GUI serve solo per rifinire l'interfaccia (§19.7). + +## Comandi CLI principali (src/Cli) + +`create`/`restore`/`restore-xpub`/`info` per i wallet; `sync`/`send`/`reset-certs` contro il server di indicizzazione (`--server host:porta [--ssl]`); `newseed`/`addresses` come strumenti. Eseguire senza argomenti per l'usage completo. Il file wallet di default è `~/.palladium-wallet//wallets/default.wallet.json` (sovrascrivibile con `--file`). + +## Architettura — punti che richiedono più file per essere capiti + +- **Livelli (§2):** GUI → Application API → Dominio wallet → SPV/Sync → Rete → Crittografia → Persistenza. Ogni livello dipende solo verso il basso. +- **Profilo di rete (§3):** tutte le costanti di catena (prefissi indirizzi, header BIP32, HRP bech32, genesi, porte, coin_type 746) vanno **centralizzate in `Core/Chain`** via `NetworkBuilder` e selezionabili per rete (mainnet/testnet/regtest). Nessun magic number sparso nel codice. +- **LWMA / skip PoW (§3, §7):** la catena usa difficoltà LWMA con blocchi da 2 minuti; un client SPV non può ricalcolarla, quindi `skip_pow_validation = true` e la fiducia è ancorata ai **checkpoint hardcoded** (§7.3). Questo strato è custom: NBitcoin assume il retargeting di Bitcoin. +- **Cosa fornisce NBitcoin vs cosa è custom (§19.2):** NBitcoin copre rete custom, BIP32/39, indirizzi, transazioni, PSBT, firma, encoding, hashing — **non reimplementarli**. Va scritto a mano: client JSON-RPC del server di indicizzazione (protocollo ElectrumX-like, §10) con pool, TLS pinning TOFU e proxy/Tor; sincronizzazione SPV con verifica Merkle (§7.4); validazione header/checkpoint; coin selection e fee policy; file wallet JSON cifrato versionato. +- **PSBT-centrico (§6.5):** ogni flusso di firma passa per PSBT (offline, air-gapped, multisig, hardware). +- **Le porte di default (50001/50002) sono del server di indicizzazione**, non la porta P2P del nodo (2333): il wallet SPV parla solo col server di indicizzazione. +- **Stato implementato (passi 1–7 del §16):** `Core/Chain` profili rete; `Core/Crypto` BIP39/32/SLIP-132/HdAccount; `Core/Storage` file wallet JSON v1 + AES-GCM (PBKDF2-SHA512) + percorsi dati; `Core/Net` ElectrumClient (JSON-RPC newline su TCP/TLS, TOFU in `server-certs.json`); `Core/Spv` scripthash, verifica Merkle obbligatoria su ogni tx confermata, sincronizzazione con gap limit; `Core/Wallet` TransactionFactory (RBF on, send-all, PSBT per watch-only) e WalletLoader (doc→account). GUI Avalonia a pannello unico in `MainWindowViewModel`. Mancano (TODO §16 passi 8-9): multisig, hardware wallet, coin control UI, fee ETA/mempool, RBF/CPFP UI, header chain completa su disco, pool multi-server, proxy/Tor. + +## Regole di lavoro + +- **Test cross-implementazione obbligatori (§16):** ad ogni passo confrontare indirizzi, txid e PSBT con un wallet di riferimento (golden vectors). Un indirizzo o txid diverso è un bug bloccante. +- **Sicurezza (§17):** seed e chiavi private mai in chiaro su disco, mai nei log, mai in rete; ogni risposta dei server va validata con prove di Merkle + checkpoint; watch-only realmente read-only. +- Le funzionalità marcate *(opzionale)* nel blueprint possono essere rimandate ma vanno comunque considerate nella progettazione. diff --git a/blueprint.md b/blueprint.md new file mode 100644 index 0000000..68848c8 --- /dev/null +++ b/blueprint.md @@ -0,0 +1,670 @@ +# Blueprint — Wallet desktop per criptovaluta UTXO/SPV + +> Specifica **autonoma e indipendente dal linguaggio** per costruire da zero un wallet +> **solo desktop** (Windows e Linux), orientato al power-user come Sparrow Wallet. +> +> Il documento è pensato per essere letto e implementato **passo per passo**: contiene +> tutto il necessario — algoritmi, strutture dati, parametri, protocollo di rete e +> sequenza di costruzione — senza presupporre un framework, un linguaggio o un codice +> sorgente preesistente. Ogni funzionalità elencata va considerata **parte del prodotto +> completo**; quelle marcate *(opzionale)* possono essere rimandate a release successive +> ma sono comunque documentate. + +--- + +## 0. Glossario rapido + +| Termine | Significato | +|---|---| +| **SPV** | Simplified Payment Verification: il wallet non scarica la catena, verifica le transazioni tramite prove di Merkle sugli header dei blocchi. | +| **UTXO** | Unspent Transaction Output: una "moneta" non spesa; il saldo è la somma degli UTXO controllati dal wallet. | +| **HD** | Hierarchical Deterministic: tutte le chiavi derivano da un seed unico (BIP32). | +| **PSBT** | Partially Signed Bitcoin Transaction: formato standard per transazioni firmate parzialmente (offline, multisig, hardware). | +| **Watch-only** | Wallet che conosce solo le chiavi pubbliche: vede saldo e storico ma non può firmare. | +| **Server di indicizzazione** | Server che indicizza la catena e risponde alle query del client (protocollo §10). | +| **Scripthash** | SHA-256 dello scriptPubKey con byte invertiti: chiave con cui il server indicizza gli indirizzi. | + +--- + +## 1. Visione del prodotto + +Un wallet **desktop nativo** con queste qualità target (modello Sparrow): + +- **Solo desktop**: nessuna UI mobile. UX densa, orientata a trasparenza e controllo. +- **Single-sig e multisig** di prima classe, con supporto hardware wallet. +- **Controllo totale su monete e fee**: coin control (UTXO), selezione manuale, etichette, + controllo fee, RBF/CPFP. +- **PSBT-centrico**: ogni flusso di firma passa per PSBT, abilitando firma offline, + air-gapped e collaborativa. +- **Leggero (SPV)**: avvio immediato, nessun full node richiesto (ma con possibilità di + collegare un server proprio). +- **Privacy-aware**: coin selection che preserva la privacy, supporto proxy/Tor, + possibilità di server privato. +- **Eseguibile distribuibile**: binario per Windows e Linux, firma del codice, build + riproducibili. + +L'applicazione è strutturata in due grandi blocchi: un **core** (logica pura, senza UI) e +una **GUI desktop** sopra di esso. Tutta la logica di seguito appartiene al core, tranne +dove indicato. + +--- + +## 2. Architettura a livelli (target) + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ GUI desktop — viste, wizard, coin control, dialog di firma │ +├─────────────────────────────────────────────────────────────────────┤ +│ Application API — casi d'uso: crea/apri wallet, invia, ricevi, │ +│ firma, storico, gestione canali, ecc. │ +│ Esposta anche come CLI + RPC locale (§13). │ +├─────────────────────────────────────────────────────────────────────┤ +│ Dominio wallet — wallet, keystore, indirizzi, UTXO, contatti, │ +│ fatture, richieste, costruzione/firma tx, │ +│ coin selection, fee policy │ +├─────────────────────────────────────────────────────────────────────┤ +│ SPV / Sincronizz. — synchronizer, verifier (Merkle), gestione │ +│ header/checkpoint, saldo e storico │ +├─────────────────────────────────────────────────────────────────────┤ +│ Rete — pool di connessioni, selezione server, TLS │ +│ con pinning, proxy, protocollo di query (§10) │ +├─────────────────────────────────────────────────────────────────────┤ +│ Crittografia — secp256k1, hash, BIP32/39/SLIP39, base58, │ +│ bech32, cifratura file wallet, ECIES │ +├─────────────────────────────────────────────────────────────────────┤ +│ Persistenza — file wallet JSON cifrato, config, percorsi │ +│ Lightning (⏳ poi) — sottosistema separato, fase successiva (§11) │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +**Regola di dipendenza:** ogni livello dipende solo verso il basso. La GUI parla solo con +l'Application API, mai direttamente con rete o crittografia. Questo permette di avere +CLI, test automatici e GUI sullo stesso core. + +### Requisiti di componenti (astratti, non legati al linguaggio) +Indipendentemente dallo stack scelto, servono librerie/moduli che forniscano: +1. **Curva ellittica secp256k1** (firma/verifica ECDSA + Schnorr, tweak chiavi). *Non + reimplementare a mano la matematica della curva: usare una libreria auditata.* +2. **Funzioni hash**: SHA-256, doppio SHA-256, RIPEMD-160, HASH160 (SHA256→RIPEMD160), + SHA-512, HMAC-SHA512, PBKDF2-HMAC-SHA512. +3. **Encoding**: Base58Check, Bech32 e Bech32m. +4. **Cifratura simmetrica** (AES-256) e **ECIES** per messaggi. +5. **TLS** con accesso al certificato per il pinning. +6. **JSON** per file wallet e protocollo. +7. **Generatore di numeri casuali crittografico** per seed e nonce. + +--- + +## 3. Profilo di rete / catena (parametri da definire PRIMA di tutto) + +Un wallet è legato a una catena specifica tramite un insieme di costanti. **Vanno fissate +all'inizio**: un valore sbagliato produce indirizzi non validi o fa rifiutare la catena. +Definire un oggetto/struct di configurazione con i seguenti campi. + +> I valori del profilo di riferimento qui sotto sono stati **verificati contro il sorgente +> del nodo** (`chainparams.cpp` / `pow.cpp`): sono i parametri di consenso autoritativi. + +| Campo | Descrizione | Esempio (profilo di riferimento mainnet) | +|---|---|---| +| `net_name` | nome rete / sottocartella dati | `mainnet` | +| `coin_unit` | simbolo unità | `PLM` | +| `wif_prefix` | prefisso chiavi private WIF | `0x80` | +| `addr_p2pkh` | byte versione indirizzi legacy | `55` → indirizzi che iniziano con `P` | +| `addr_p2sh` | byte versione indirizzi P2SH | `5` → iniziano con `3` | +| `segwit_hrp` | prefisso human-readable bech32 | `plm` → indirizzi `plm1...` | +| `bolt11_hrp` | prefisso fatture Lightning | `plm` | +| `genesis_hash` | hash del blocco genesi (mainnet riusa la genesi di Bitcoin) | `000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f` | +| `default_ports` | porte del **server di indicizzazione** usato dal wallet | `{tcp: 50001, ssl: 50002}` | +| `bip44_coin_type` | coin type SLIP-0044 nel derivation path (*convenzione wallet, non parametro di consenso del nodo*) | `746` | +| `uri_scheme` | schema URI pagamenti (BIP21) | `palladium:` | +| `explorer_url` | block explorer di default | `https://explorer.palladium-coin.com/` | +| `skip_pow_validation` | salta la verifica difficoltà — **obbligatorio**: la catena usa LWMA (vedi nota sotto) | `true` | + +> **Nota sulle porte.** Le `default_ports` sopra sono quelle del **server di indicizzazione** +> (es. ElectrumX-like) a cui si connette il wallet, **non** la porta P2P del nodo (che nel +> sorgente è `2333` mainnet / `12333` testnet / `28444` regtest). Sono due cose distinte: il +> wallet SPV parla solo col server di indicizzazione. +> +> **Nota sulla difficoltà (LWMA).** Il nodo calcola la difficoltà con **LWMA** (Linearly +> Weighted Moving Average) e un **tempo di blocco di 2 minuti** (`nPowTargetSpacingV2 = 120s`; +> il vecchio `nPowTargetTimespan` di 14 giorni è mantenuto solo per la validazione storica). +> Un client SPV non è in grado di ricalcolare LWMA, quindi `skip_pow_validation` **deve** +> essere `true` e la fiducia sulla catena va ancorata ai **checkpoint** (§7.3). + +**Header chiavi estese BIP32** (mainnet di riferimento) — servono per serializzare/parsare +xprv/xpub per ciascun tipo di indirizzo: + +| Tipo indirizzo | prefisso priv | header priv | prefisso pub | header pub | +|---|---|---|---|---| +| standard (P2PKH) | xprv | `0x0488ade4` | xpub | `0x0488b21e` | +| segwit wrapped (P2WPKH-P2SH) | yprv | `0x049d7878` | ypub | `0x049d7cb2` | +| multisig wrapped (P2WSH-P2SH) | Yprv | `0x0295b005` | Ypub | `0x0295b43f` | +| native segwit (P2WPKH) | zprv | `0x04b2430c` | zpub | `0x04b24746` | +| native segwit multisig (P2WSH) | Zprv | `0x02aa7a99` | Zpub | `0x02aa7ed3` | + +**Testnet** (profilo di riferimento): `wif_prefix=0xff`, `addr_p2pkh=127`, `addr_p2sh=115`, +`segwit_hrp=tplm`, `bip44_coin_type=1`, header tprv/tpub `0x04358394`/`0x043587cf`, ecc. +**Regtest**: `segwit_hrp=rplm`. + +**Server iniziali** (bootstrap, profilo di riferimento): forniti come lista +`host:porta_tcp:porta_ssl`; il pool li usa per il primo contatto e poi scopre altri peer +via protocollo (`server.peers.subscribe`). + +> Tutte le costanti devono essere **centralizzate** in un solo punto e selezionabili per +> rete (mainnet/testnet/regtest), così da non disperdere magic number nel codice. + +--- + +## 4. Crittografia, seed e gestione chiavi + +### 4.1 Seed e mnemoniche — tutti gli schemi supportati +Il wallet deve supportare **più schemi di seed** e saperli riconoscere automaticamente: + +1. **Seed nativo versionato**: mnemonica con un prefisso di versione codificato via HMAC + (distingue i sottotipi `standard`, `segwit`, `2fa`, `2fa-segwit`). In creazione si + garantisce che la mnemonica generata **non** sia contemporaneamente un valido BIP39. +2. **BIP39**: import/restore di seed standard a **12 o 24 parole**, con verifica del + checksum. +3. **SLIP39 (Shamir Secret Sharing)** *(opzionale)*: seed suddiviso in più *share*; servono + K share su N per ricostruirlo. +4. **Formato seed legacy** *(opzionale, retrocompatibilità)*: vecchio schema pre-BIP32. + +**Wordlist multilingua**: inglese, spagnolo, giapponese, portoghese, cinese. Le parole +vanno normalizzate (NFKD) prima della derivazione. + +**Passphrase / extension word (opzionale ma obbligatoria da implementare):** parola/e +aggiuntive combinate col seed tramite **PBKDF2-HMAC-SHA512, 2048 round**, con salt +`"" + passphrase` (per il seed nativo il prefisso del salt è una costante dello +schema; per BIP39 è `"mnemonic" + passphrase`). Cambia completamente il wallet derivato. +Avvisi UI obbligatori: se persa, i fondi sono **irrecuperabili**; va annotata separatamente +dal seed; è case-sensitive e gli spazi contano. + +### 4.2 Derivazione gerarchica (BIP32/BIP44/49/84) +- Da seed → **root key** (BIP32). Da root → chiavi estese per account. +- Path standard con il `coin_type` del profilo: + - Legacy P2PKH: `m/44'/'/account'/change/index` + - Segwit wrapped P2SH-P2WPKH: `m/49'/'/account'/change/index` + - Native segwit P2WPKH: `m/84'/'/account'/change/index` + - Multisig: `m/48'/'/account'/script_type'/...` +- Supportare **derivation path personalizzati** (Sparrow-like): l'utente può specificare il + path manualmente in import. +- Catena `change=0` (receiving) e `change=1` (change). Derivazione per indice on-demand. + +### 4.3 Tipi di indirizzo (tutti) +| Tipo | script | prefisso (profilo rif.) | uso | +|---|---|---|---| +| Native SegWit | P2WPKH | `plm1...` | **default consigliato**: fee minime | +| Legacy | P2PKH | `P...` | massima compatibilità | +| SegWit wrapped | P2SH-P2WPKH | `3...` | compatibilità intermedia | +| Multisig native | P2WSH | `plm1...` | M-di-N moderno | +| Multisig wrapped | P2SH / P2SH-P2WSH | `3...` | M-di-N legacy | + +### 4.4 Tipi di keystore (sorgenti di chiavi) +- **HD da seed** (caso principale): seed → root → xprv/xpub. +- **HD da master key importata**: import di xprv/xpub (o y/z varianti). Solo xpub = watch-only. +- **Chiavi private importate**: lista di chiavi WIF singole. +- **Hardware wallet**: la chiave privata non lascia mai il dispositivo (vedi §4.6). +- **Keystore "split/2FA"** *(opzionale)*: parte della firma delegata a un servizio remoto. +- **Keystore legacy** *(opzionale)*. + +### 4.5 Tipi di wallet +- **Standard** (single-sig HD) — caso d'uso principale. +- **Multisig M-di-N** — combinazione di più keystore (seed/xpub/hardware misti). +- **Importato** — indirizzi o chiavi private importate; può essere watch-only o spendibile. +- **Watch-only** — solo chiavi pubbliche; costruisce ma non firma (esporta PSBT). + +Una factory legge il tipo dal file wallet e istanzia la classe corretta. + +### 4.6 Hardware wallet (tutti i modelli supportati) +Integrazione con dispositivi hardware via il loro protocollo USB/HID/seriale. Modelli da +supportare: **Trezor, Ledger, KeepKey, Coldcard, BitBox02, Digital BitBox, Safe-T, Jade**. +Funzioni: import dell'xpub dal dispositivo, conferma indirizzo sullo schermo del device, +firma PSBT sul device (la chiave privata non viene mai esposta), gestione PIN/passphrase. +Per i dispositivi air-gapped (es. Coldcard): scambio PSBT via file/QR/microSD. + +### 4.7 Backup e sicurezza delle chiavi +- **Cifratura del file wallet** con password (vedi §8); cambio password. +- **Cifratura/decifratura messaggi** e firma/verifica messaggi con una chiave. +- **Export**: seed, master private key, master public key, chiavi private (per indirizzo o + per path), in modo protetto (richiesta password). +- **Backup su carta con visual one-time-pad** *(opzionale, "revealer")*: genera un foglio + cifrato che, sovrapposto a una griglia segreta stampata, rivela il seed. +- **Recupero a timelock** *(opzionale)*: predisposizione di transazioni di recupero che + diventano spendibili dopo un timelock, per ereditarietà/dead-man-switch. + +--- + +## 5. Ricezione fondi + +- **Generazione indirizzi**: prossimo indirizzo non usato; lista indirizzi receiving e + change; rispetto del **gap limit** (numero massimo di indirizzi vuoti consecutivi + scansionati; configurabile, con comando per aumentarlo). +- **Richieste di pagamento**: creare una richiesta con importo, scadenza, descrizione; + elencarle, eliminarle, segnarne lo stato (in attesa/pagata/scaduta). +- **URI BIP21**: generare e parsare `«scheme»:«indirizzo»?amount=...&label=...&message=...`. +- **QR code**: generazione per indirizzi/URI/richieste; scansione da webcam o immagine. +- **Risoluzione nomi**: OpenAlias/DNS, LNURL, e richieste firmate BIP70 *(opzionale)*. +- **Etichette** sugli indirizzi e sulle richieste. + +--- + +## 6. Invio fondi e costruzione transazioni + +### 6.1 Composizione +- **Pay-to** singolo e **pay-to-many** (più output in una sola transazione). +- Input destinatario: indirizzo, URI, nome OpenAlias/LNURL, o richiesta scansionata. +- Importo in unità coin o in fiat (con conversione al tasso corrente). +- Opzione **"invia tutto"** (max), con sottrazione fee dall'importo. +- **Locktime** e **sequence** impostabili (per RBF/timelock). +- Etichetta della transazione. + +### 6.2 Coin control (cuore di un wallet desktop) +- Vista UTXO completa con importi, indirizzo, conferme, etichetta. +- **Selezione manuale** degli UTXO da spendere (coin control). +- **Freeze/unfreeze** di indirizzi e di singoli UTXO (esclusi dalla spesa automatica). +- Visualizzazione del *change* previsto e dell'indirizzo di change. + +### 6.3 Strategie di selezione monete (coin selection) +Implementare almeno due strategie selezionabili: +- **Privacy-preserving**: raggruppa gli UTXO per indirizzo (evita di unire monete di + indirizzi diversi), riduce la perdita di privacy futura e il bloat di UTXO. +- **Random**: selezione casuale con arrotondamento del change per offuscare gli importi. +Obiettivi comuni: minimizzare fee, evitare output *dust*, gestire il change correttamente. + +### 6.4 Politiche di fee (tutte) +Modalità di calcolo fee, selezionabili: +- **Fissa** (importo assoluto). +- **Fee rate fisso** (sat/vByte). +- **Dinamica ETA-based**: stima dal server per un target di conferma (es. 1, 2, 5, 10, 25, + 144, 1008 blocchi). +- **Dinamica mempool-based**: in base allo stato della mempool. +Mostrare sempre fee totale, fee rate effettivo e dimensione virtuale stimata. Avviso se la +fee è anomala (troppo alta/bassa). + +### 6.5 Firma e modello PSBT +Ogni transazione non banale passa per **PSBT**: +- **Crea** PSBT (non firmata) dal wallet. +- **Firma** con: keystore software, hardware wallet, o firma offline su altra macchina. +- **Combina** PSBT parzialmente firmate (multisig: ogni cosigner firma e si uniscono). +- **Finalizza** ed estrai la transazione grezza. +- **Import/export PSBT** via: file, **QR code** (anche animato per PSBT grandi), + **scambio su rete decentralizzata per cosigning** *(opzionale)*, **trasmissione audio** + *(opzionale, "audio modem")*. +- Flusso **watch-only / air-gapped**: la macchina online crea la PSBT, quella offline firma, + la online trasmette. + +### 6.6 Gestione post-invio +- **Broadcast** della transazione (e broadcast di un *pacchetto* di transazioni correlate). +- **RBF (Replace-By-Fee)**: bump della fee di una tx non confermata; **cancellazione** + (invio a sé stessi con fee più alta). +- **CPFP (Child-Pays-For-Parent)**: accelerare una tx in entrata spendendola con fee alta. +- **Rimozione di tx locali** non confermate. +- **Sweep**: spazzare tutti i fondi di una chiave privata esterna verso il wallet. +- **Aggiunta manuale di una tx** (incolla raw/hex) e firma con chiave fornita. + +### 6.7 Reportistica +- **Plusvalenze/minusvalenze on-chain** (capital gains) per anno fiscale. +- Esportazione storico (CSV/JSON) con etichette. +- Timestamp di inizio/fine anno per i report. + +--- + +## 7. Blockchain, sincronizzazione e validazione (SPV) + +### 7.1 Modello SPV +Il wallet **non scarica la catena completa**. Mantiene solo gli **header dei blocchi** e +verifica le transazioni che lo riguardano con **prove di Merkle** contro tali header. + +### 7.2 Validazione header +- Header a lunghezza fissa (campi: versione, prev_hash, merkle_root, timestamp, bits, nonce). +- Verifica del **collegamento** (prev_hash) e dell'**hash atteso** di ogni header. +- **Proof-of-Work**: confronto `hash <= target` e coerenza dei `bits`. +- **Difficoltà**: la catena di riferimento usa **LWMA** (retargeting per-blocco, tempo di + blocco 2 minuti — confermato dal nodo). Un client SPV non ricalcola LWMA, quindi il flag + `skip_pow_validation` del profilo (§3) **disattiva** il controllo bits/target; in tal caso + la fiducia è ancorata ai **checkpoint** (sotto). Implementare entrambe le modalità (PoW + classico stile Bitcoin e modalità "skip" per catene LWMA). +- Header organizzati in **chunk** (es. 2016) salvati su file locale; gestione di **fork** + (più rami concorrenti) con scelta del ramo a maggior lavoro. + +### 7.3 Checkpoint +Lista hardcoded di `[hash, target]` a intervalli regolari, usata per: +- accelerare la validazione iniziale (non riverificare dall'origine), +- ancorare la validità della catena quando la verifica PoW è disattivata. +Fornire un meccanismo per aggiornare/spedire i checkpoint con le release. + +### 7.4 Sincronizzazione wallet +1. Per ogni indirizzo: calcola lo **scripthash**, sottoscrivi al server. +2. Alla notifica di cambiamento: richiedi lo **storico** (lista txid + altezza). +3. Scarica le transazioni mancanti. +4. **Verifica** ciascuna con prova di Merkle contro l'header all'altezza indicata. +5. Aggiorna saldo (confermato/non confermato), UTXO e storico. +6. Estendi la scansione finché si raggiunge il gap limit di indirizzi vuoti. + +--- + +## 8. Persistenza e configurazione + +- **File wallet**: un file (JSON) contenente keystore, indirizzi, storico, etichette, + contatti, richieste, fatture, (e stato canali Lightning se attivo). **Cifrato** con AES + quando è impostata una password (la password protegge il file su disco; **non** sblocca + il seed). Schema **versionato** con migrazioni automatiche all'apertura. +- **Configurazione globale** separata dal wallet: rete selezionata, server, proxy, unità, + lingua, politiche fee di default, block explorer. +- **Percorsi dati** per piattaforma + **modalità portable** (dati accanto all'eseguibile, + utile per chiavette USB). +- **Multi-wallet**: aprire/chiudere più wallet, elencarli, passare dall'uno all'altro. + +--- + +## 9. Rete e connettività + +- **Pool di connessioni**: più server contemporaneamente per ridondanza; un server + "primario" per gli header; fan-out delle query. +- **Selezione server**: automatica o manuale; scoperta di nuovi peer dal protocollo. +- **TLS con pinning (TOFU)**: al primo contatto il certificato del server viene salvato; ai + successivi viene confrontato. Se cambia → connessione rifiutata. Fornire un comando + **"reset certificati SSL"** per i server self-signed (caso tipico: il server rinnova il + certificato e il client va sbloccato manualmente). +- **Proxy / Tor**: supporto SOCKS5 per instradare tutto il traffico. +- **Stima fee** dal server; **relay fee** minima. +- **Stato connessione** visibile in UI; riconnessione automatica. + +--- + +## 10. Protocollo client ↔ server (query di indicizzazione) + +Il client comunica via **JSON-RPC** (su TCP, opzionalmente TLS). Implementare richieste e +parsing per i seguenti metodi (gli indirizzi sono indicizzati per **scripthash**): + +``` +# Negoziazione / server +server.version server.banner server.features +server.ping server.peers.subscribe server.donation_address + +# Header / catena +blockchain.headers.subscribe blockchain.block.header blockchain.block.headers +blockchain.estimatefee blockchain.relayfee + +# Indirizzi (per scripthash) +blockchain.scripthash.subscribe blockchain.scripthash.get_balance +blockchain.scripthash.get_history blockchain.scripthash.listunspent + +# Transazioni +blockchain.transaction.get blockchain.transaction.get_merkle +blockchain.transaction.broadcast blockchain.transaction.broadcast_package +blockchain.transaction.id_from_pos +``` + +--- + +## 11. Lightning Network — ⏳ DA FARE IN SEGUITO (fase successiva, fuori dal primo rilascio) + +> **Non incluso nel primo rilascio.** Coerentemente con il modello Sparrow (on-chain only), +> il wallet parte **senza Lightning**. Questo capitolo resta documentato come specifica per +> una **fase successiva**: va affrontato solo dopo che tutte le funzioni on-chain (§4–§10) +> sono complete e stabili. Va progettato come **sottosistema separato e disattivabile**, in +> modo da non bloccare né complicare il primo rilascio. + +Quando verrà affrontato, è un grande sottosistema a sé. Funzionalità da implementare: + +- **Canali**: apertura, chiusura cooperativa e forzata, lista canali e peer. +- **Pagamenti**: invio/ricezione su BOLT11, **MPP** (multi-part payments), **trampoline + routing**, onion routing, gossip/routing della rete. +- **Fatture**: creazione/decodifica BOLT11; **hold invoice** (trattenute fino a conferma). +- **Backup canali**: export/import dei backup di stato (critici per non perdere fondi). +- **Watchtower**: locale e remoto, per punire chiusure fraudolente quando offline. +- **Submarine swap**: scambio on-chain ↔ Lightning, con provider/server di swap; + rebalance dei canali. +- **LNURL** e indirizzi Lightning (lightning-address). +- **Nostr Wallet Connect (NWC)** *(opzionale)*: controllo remoto del wallet Lightning. +- **Payserver** *(opzionale)*: endpoint per ricevere pagamenti. + +> **Promemoria:** per il primo rilascio Lightning è escluso. Le funzioni base (§4–§10) non +> dipendono in alcun modo da questo capitolo; affrontarlo solo come iterazione successiva. + +--- + +## 12. Contatti, etichette e dati ausiliari + +- **Rubrica contatti**: nome ↔ indirizzo, con ricerca. +- **Etichette** su indirizzi, transazioni, UTXO, richieste. +- **Sincronizzazione etichette** *(opzionale)*: cifrate, condivise tra istanze del wallet + via un servizio. +- **Lista fatture** (uscite) e **lista richieste** (entrate) con stato. + +--- + +## 13. Interfacce non grafiche + +- **CLI**: ogni caso d'uso del core esposto come comando da riga di comando (utile per + scripting e per i test automatici). +- **RPC locale / daemon** *(opzionale)*: un processo in background che espone l'API su + socket locale autenticato, così la GUI e strumenti esterni parlano con lo stesso core. + +Famiglie di comandi da prevedere (elenco rappresentativo della superficie API completa): +creazione/restore/apertura/chiusura wallet, generazione indirizzi, saldo e storico, +pay-to / pay-to-many, firma/broadcast, gestione PSBT (deserialize/combine/finalize), +freeze/unfreeze UTXO, bumpfee/cancel, sweep, import/export chiavi e xkey, conversione xkey, +firma/verifica messaggi, gestione richieste e fatture, contatti, conversione fiat, +stato sincronizzazione, gestione server/config. *(Comandi Lightning — apertura/chiusura +canali, pagamenti, swap, backup canali — solo nella fase successiva, vedi §11.)* + +--- + +## 14. Funzioni di supporto e infrastruttura + +- **Tassi di cambio / fiat**: integrazione con più provider di prezzo; conversione importi + in valuta locale; **prezzi storici** per la reportistica; aggiornamento periodico. +- **Internazionalizzazione (i18n)**: UI multilingua, con rilevamento lingua di sistema. +- **Crash reporter**: raccolta e invio (con consenso) dei crash. +- **Sistema di plugin** *(opzionale)*: caricamento di estensioni (hardware wallet, swap + server, watchtower, label sync, ecc.) come moduli separati. +- **Hardening memoria** *(opzionale)*: blocco in RAM (no swap su disco) dei segreti dove il + SO lo consente; azzeramento dei buffer sensibili dopo l'uso. +- **Block explorer**: apertura di tx/indirizzi nell'explorer configurato. + +--- + +## 15. Wizard di creazione/restore (flusso UI) + +1. Avvio: **crea nuovo wallet** / **apri esistente** / **importa**. +2. Tipo wallet: **Standard** / **Multisig (M-di-N)** / **Importa indirizzi o chiavi** / + **Hardware**. +3. Per Standard: **nuovo seed** / **ho già un seed** / **usa master key** / **usa device hardware**. +4. Nuovo seed → mostra le parole → **conferma** reinserendole. +5. **Passphrase** opzionale (extension word) con avvisi (§4.1). +6. Scelta **tipo di indirizzo** (default: native segwit). +7. **Password** di cifratura del file wallet. +8. Sincronizzazione e comparsa di saldo/storico. + +Per multisig: raccolta di N cosigner (seed/xpub/hardware), scelta soglia M, derivation path +e tipo di script; generazione del descrittore del wallet e verifica incrociata degli xpub +tra i partecipanti. + +--- + +## 16. Sequenza di costruzione consigliata (passo per passo) + +Costruire e **testare** in quest'ordine; ad ogni passo verificare con vettori noti. + +1. **Profilo di rete (§3)**: centralizzare tutte le costanti; selettore mainnet/testnet/regtest. +2. **Crittografia e chiavi (§4)**: hash, secp256k1, base58/bech32, BIP32/39, generazione + indirizzi. *Test:* dato un seed → produrre gli indirizzi attesi (golden vectors). +3. **Persistenza (§8)**: definire e versionare lo schema del file wallet (JSON) + cifratura. +4. **Rete + protocollo (§9–10)**: connessione, TLS+pinning, query base. +5. **SPV + sincronizzazione (§7)**: header, checkpoint, Merkle, saldo/storico su un wallet + **watch-only**. *Test:* stesso xpub → stesso saldo di un wallet di riferimento. +6. **Transazioni (§6)**: costruzione, coin selection, fee, PSBT, firma, broadcast su testnet. +7. **GUI desktop (§15 + viste)**: wizard, dashboard saldo/storico, invia (con coin control), + ricevi, UTXO, contatti, impostazioni. +8. **Hardware wallet (§4.6)** e **multisig (§4.5)**: firma collaborativa via PSBT. +9. **Estensioni**: fiat/exchange rate, label sync, reportistica. +10. **⏳ Fase successiva (post-rilascio)**: **Lightning (§11)** come sottosistema separato, + da iniziare solo quando i passi 1–9 sono completi e stabili. + +**Test cross-implementazione (obbligatorio per un wallet):** ad ogni passo confrontare gli +output (indirizzi, txid, PSBT) con un wallet di riferimento usando gli stessi input. Un +indirizzo o un txid diverso è un bug bloccante. + +--- + +## 17. Requisiti di sicurezza (non negoziabili) + +- Seed e chiavi private **mai** in chiaro su disco non cifrato, **mai** nei log, **mai** + inviati in rete. +- Cifratura del file wallet con derivazione robusta della chiave dalla password. +- Validare **ogni** dato proveniente dalla rete: le risposte dei server **non sono fidate**; + verificare sempre con prove di Merkle + checkpoint. +- Watch-only realmente read-only: nessuna chiave privata derivabile dalle sole pubbliche. +- TLS con pinning del certificato e reset esplicito controllato dall'utente. +- Azzeramento dei segreti in memoria dopo l'uso; ove possibile blocco anti-swap. +- **Firma del codice** dei binari Windows/Linux e **build riproducibili** per consentire la + verifica indipendente. + +--- + +## 18. Packaging e distribuzione desktop + +- **Windows**: eseguibile installabile e versione **portable** (dati accanto all'exe). + Firma Authenticode. +- **Linux**: formato portabile autoconsistente (es. immagine eseguibile singola) e/o + pacchetto nativo; firma GPG dei rilasci. +- **Build riproducibili** (ambiente di build isolato/containerizzato) e pubblicazione degli + hash + firme dei binari. +- File di associazione per lo schema URI dei pagamenti (`uri_scheme` del profilo) così che i + link di pagamento aprano il wallet. + +--- + +## 19. Stack tecnologico raccomandato (.NET 8 + Avalonia + NBitcoin) + +> I capitoli §1–§18 sono **indipendenti dal linguaggio** e restano il riferimento. Questa +> sezione propone una **realizzazione concreta** scelta per tre vincoli: sviluppo assistito +> da IA, **semplicità**, e **un solo sorgente** che produca sia `.exe` (Windows) sia +> AppImage (Linux). Lo stack non è obbligatorio: è la via più liscia per *questo* prodotto. + +### 19.1 Perché questo stack +- **`NBitcoin` (C#)** modella reti altcoin custom via `NetworkBuilder` (prefissi + P2PKH/P2SH, WIF, header BIP32 xpub/xprv, HRP bech32, genesi): mappatura **diretta** della + §3. Fornisce già HD/BIP32/39, indirizzi (legacy/segwit/wrapped), costruzione e + serializzazione transazioni, **PSBT**, firma, base58/bech32, hashing → è la libreria che + fa scrivere **meno crittografia a mano** per un altcoin. +- **Avalonia UI** è cross-platform nativo: un solo sorgente per Windows e Linux. +- **C#/.NET** ha tooling maturo e un enorme corpus → l'IA produce codice idiomatico con + poche frizioni; alto livello e GC = sviluppo rapido. +- Posizione di **sicurezza accettabile** sulle chiavi senza la curva di apprendimento di + Rust e senza i rischi di Electron (chiavi in JS, footprint, supply-chain npm). + +*Alternative scartate:* **Rust + BDK + Tauri** (binari minimi e memory-safe, ma curva +ripida e customizzazione altcoin più laboriosa → contro "semplicità"); **Electron + TS** +(packaging e UI rapidissimi, ma gestione chiavi più fragile → sconsigliato per un wallet); +**Java/JavaFX** (è lo stack di Sparrow e produce già `.exe`+AppImage, ma nessun vantaggio +netto su .NET per questo caso). + +### 19.2 Cosa è coperto dalla libreria e cosa va scritto a mano +**Coperto da NBitcoin** (non reimplementare): rete custom, BIP32/39, indirizzi, +transazioni, PSBT, firma, base58/bech32, hashing. + +**Da implementare a mano** (NBitcoin non lo include — è il grosso del lavoro originale): +1. **Client del protocollo del server di indicizzazione** (§10): JSON-RPC su TCP/TLS, + pool di connessioni, TLS pinning/TOFU, reset certificati, proxy/Tor. +2. **Sincronizzazione SPV** (§7.4): scripthash, storico, verifica prove di Merkle. +3. **Validazione header + checkpoint con modalità "skip PoW"** per LWMA (§3/§7): + NBitcoin assume il retargeting di Bitcoin, quindi questo strato è **custom**. +4. **Coin selection** privacy-preserving e **fee policy** (fissa/rate/ETA/mempool), + RBF/CPFP (§6): logica di dominio sopra le primitive NBitcoin. +5. **File wallet cifrato** (schema JSON versionato + AES) e **config** (§8). + +### 19.3 Mappatura strato del blueprint → componente concreto +| Strato (§2) | Realizzazione | +|---|---| +| Crittografia (§4) | NBitcoin (`Network` custom, `ExtKey`, `Mnemonic`, `BitcoinAddress`, `PSBT`) | +| Profilo rete (§3) | `NetworkBuilder` con i valori §3, centralizzato in `Core/Chain` | +| SPV/Sync (§7) | codice custom in `Core/Spv` | +| Rete/protocollo (§9–10) | client custom in `Core/Net` | +| Dominio wallet (§4–§6) | `Core/Wallet` sopra NBitcoin | +| Persistenza (§8) | `System.Text.Json` + AES in `Core/Storage` | +| Application API (§13) | progetti `Cli` e API condivisa | +| GUI desktop (§15) | Avalonia in `App` | + +### 19.4 Struttura del progetto (una sola solution .NET) +``` +PalladiumWallet.sln +├─ src/Core/ (libreria, nessuna dipendenza UI) +│ ├─ Chain/ profilo rete (NetworkBuilder), costanti §3, checkpoint +│ ├─ Crypto/ wrapper NBitcoin: seed, BIP32/39, indirizzi, keystore +│ ├─ Wallet/ wallet, UTXO, coin selection, fee policy, PSBT, firma +│ ├─ Spv/ header store, verifier (Merkle), sync +│ ├─ Net/ client protocollo, pool, TLS pinning, proxy +│ └─ Storage/ file wallet JSON cifrato, config +├─ src/App/ (Avalonia UI: wizard, dashboard, invia/ricevi, coin control) +├─ src/Cli/ (riga di comando sullo stesso Core — utile ai test) +└─ tests/ (xUnit: golden vectors indirizzi/txid, test SPV) +``` +Regola di dipendenza (§2): `App` e `Cli` dipendono da `Core`; `Core` non conosce la UI. + +### 19.5 Ambiente di sviluppo e build — tutto su Ubuntu, senza Wine +- **Dev**: `.NET 8 SDK` (repo Microsoft / `apt`), VS Code + estensione C# o Rider. + Avalonia gira ed è eseguibile nativamente su Ubuntu. +- **Architetture host**: si sviluppa sia su **x86_64** sia su **arm64** (il .NET SDK è + nativo su `linux-x64` e `linux-arm64`; NBitcoin è C# puro gestito, nessuna dipendenza + nativa legata all'arch). +- **Build cross dei binari da Linux, senza Wine** (.NET cross-targeta nativamente): + - Windows: `dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained` → `.exe`. + - Linux: `dotnet publish -r linux-x64 --self-contained`. +- **Docker** consigliato: un solo `Dockerfile` su `mcr.microsoft.com/dotnet/sdk:8.0` + produce i target in modo riproducibile. +- Wine **non** serve per compilare. Servirebbe solo per costruire un *installer* Windows + con Inno Setup su Linux (evitabile distribuendo l'`.exe` single-file **portable**) o per + *testare* l'`.exe` su Linux (test, non build). Firma Authenticode fattibile da Linux con + `osslsigncode`. + +### 19.6 Packaging "un sorgente → .exe + AppImage" (multi-architettura) +Da una macchina **Ubuntu x86_64** si producono tutti e quattro i target: + +| Target | RID | Output | Da x86_64 | +|---|---|---|---| +| Windows x64 | `win-x64` | `.exe` | ✅ diretto (no Wine) | +| Windows arm64 | `win-arm64` | `.exe` | ✅ diretto (no Wine) | +| Linux x64 | `linux-x64` | AppImage | ✅ nativo | +| Linux arm64 | `linux-arm64` | AppImage | ✅ via `docker buildx` + QEMU | + +- **Binari**: `dotnet publish -r -p:PublishSingleFile=true --self-contained` per + ciascun RID. Il `.exe` Windows (x64 e arm64) esce direttamente; niente Wine. +- **AppImage Linux x64**: `dotnet publish -r linux-x64` + **PupNet Deploy** su Ubuntu. +- **AppImage Linux arm64**: il `dotnet publish -r linux-arm64` cross-compila i binari da + x86_64, ma l'assemblaggio dell'AppImage (appimagetool/runtime) è arch-specifico → si fa + con **`docker buildx` multi-arch + emulazione QEMU** (`--platform linux/arm64`) nella + stessa pipeline, così l'AppImage arm64 viene impacchettato in ambiente arm64 emulato. +- Associazione dello schema URI `palladium:`; build riproducibili in Docker; firma codice. + +### 19.7 Flusso di test (non serve compilare e lanciare l'app per testare) +Tre livelli, tutti su Ubuntu, il grosso **headless**: +1. **`dotnet test`** — logica del `Core` senza GUI né rete reale: golden vector + seed→indirizzi del profilo (confronto 1:1 col wallet di riferimento), costruzione/firma + tx, PSBT, coin selection, parsing protocollo e verifica Merkle con server mockato. +2. **CLI** (`dotnet run --project src/Cli -- ...`) contro **regtest/testnet**: sync, saldo + su xpub watch-only, costruzione tx — flussi reali senza aprire la UI. +3. **GUI** solo per rifinire l'interfaccia: `dotnet run` compila+lancia in un comando, con + **Hot Reload** Avalonia e previewer XAML (niente ciclo build-lancia manuale). + +**Dev-loop (equivalente di `npm run dev`) — nativo anche su Debian arm64:** +- `dotnet watch --project src/App` ≈ `npm run dev`: ricompila e applica **Hot Reload** a + ogni salvataggio, con la finestra Avalonia aggiornata dal vivo; `dotnet run` per il lancio + singolo; previewer XAML nell'IDE per le viste. +- Su **arm64 si sviluppa e si vede la grafica nativamente** (.NET SDK `linux-arm64`, + Avalonia rende con Skia, fallback software se manca l'accelerazione GPU). **QEMU non serve + per sviluppare/testare** — l'emulazione riguarda solo l'impacchettamento di AppImage di + un'altra architettura (§19.6). +- Prerequisiti runtime su Debian/Ubuntu: ambiente grafico (X11/Wayland) e librerie native di + Avalonia, es. `apt install libx11-6 libice6 libsm6 libfontconfig1 libglib2.0-0 libgl1` + (più mesa). Per logica/crypto non serve GUI: `dotnet test` e la CLI girano headless. + +--- + +*Questo blueprint è una specifica completa e indipendente dal linguaggio. I parametri del +profilo di rete (§3) e la logica di validazione header/checkpoint (§7) sono gli elementi +critici e specifici della catena; tutto il resto è l'ingegneria standard di un wallet SPV +desktop. Implementando i capitoli nell'ordine del §16 si ottiene un wallet desktop completo +in stile Sparrow.*