Files

671 lines
38 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/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.*