# 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.*