Files
PalladiumWallet/blueprint.md
T

38 KiB
Raw Blame History

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 "<schema>" + 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'/<coin>'/account'/change/index
    • Segwit wrapped P2SH-P2WPKH: m/49'/<coin>'/account'/change/index
    • Native segwit P2WPKH: m/84'/<coin>'/account'/change/index
    • Multisig: m/48'/<coin>'/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 (§910): 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 19 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 (§910) 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 <rid> -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/Appnpm 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.