Add CLAUDE.md and blueprint.md (for development)
This commit is contained in:
@@ -91,6 +91,3 @@ settings.local.json
|
||||
# Local agent/tooling metadata
|
||||
.agents/
|
||||
.codex/
|
||||
CLAUDE.md
|
||||
|
||||
blueprint.md
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Cos'è questo progetto
|
||||
|
||||
Wallet desktop SPV (stile Sparrow) per la criptovaluta **Palladium (PLM)**, una catena UTXO derivata da Bitcoin. Solo Windows e Linux, niente mobile. **Lightning è esplicitamente escluso dal primo rilascio** (§11 del blueprint).
|
||||
|
||||
**La fonte di verità è [blueprint.md](blueprint.md)**: specifica completa con parametri di consenso verificati contro il nodo, algoritmi, protocollo di rete e sequenza di costruzione. Prima di implementare qualsiasi funzionalità, leggere la sezione corrispondente del blueprint. La sequenza di costruzione da seguire è quella del §16 (profilo rete → crypto/chiavi → persistenza → rete → SPV → transazioni → GUI → hardware/multisig).
|
||||
|
||||
## Stack
|
||||
|
||||
.NET 8 + Avalonia UI + NBitcoin (§19 del blueprint). Struttura della solution:
|
||||
|
||||
```
|
||||
PalladiumWallet.sln
|
||||
├─ src/Core/ Chain/ Crypto/ Wallet/ Spv/ Net/ Storage/ (nessuna dipendenza UI)
|
||||
├─ src/App/ Avalonia UI
|
||||
├─ src/Cli/ CLI sullo stesso Core
|
||||
└─ tests/ xUnit
|
||||
```
|
||||
|
||||
**Regola di dipendenza non negoziabile:** `App` e `Cli` dipendono solo da `Core`; la GUI parla solo con l'Application API, mai direttamente con rete o crittografia. `Core` non conosce la UI.
|
||||
|
||||
## Comandi
|
||||
|
||||
Il .NET 8 SDK è installato in `~/.dotnet` (via dotnet-install.sh, senza root): nelle shell non interattive serve `export PATH="$HOME/.dotnet:$PATH" DOTNET_ROOT="$HOME/.dotnet"` prima dei comandi `dotnet`.
|
||||
|
||||
- Build: `dotnet build`
|
||||
- Test (headless, è il livello principale di verifica): `dotnet test`
|
||||
- Singolo test: `dotnet test --filter "FullyQualifiedName~NomeTest"`
|
||||
- CLI contro testnet/regtest: `dotnet run --project src/Cli -- <comando>`
|
||||
- GUI con hot reload: `dotnet watch --project src/App`
|
||||
- Su questa macchina (WSL2 con WSLg) la finestra appare direttamente sul desktop Windows: niente X server o librerie da installare, è già tutto verificato funzionante.
|
||||
- Publish Windows: `dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained`
|
||||
- Publish Linux: `dotnet publish -r linux-x64 --self-contained` (poi AppImage via PupNet Deploy)
|
||||
|
||||
La logica core e la crypto si testano senza GUI né rete reale; la GUI serve solo per rifinire l'interfaccia (§19.7).
|
||||
|
||||
## Comandi CLI principali (src/Cli)
|
||||
|
||||
`create`/`restore`/`restore-xpub`/`info` per i wallet; `sync`/`send`/`reset-certs` contro il server di indicizzazione (`--server host:porta [--ssl]`); `newseed`/`addresses` come strumenti. Eseguire senza argomenti per l'usage completo. Il file wallet di default è `~/.palladium-wallet/<rete>/wallets/default.wallet.json` (sovrascrivibile con `--file`).
|
||||
|
||||
## Architettura — punti che richiedono più file per essere capiti
|
||||
|
||||
- **Livelli (§2):** GUI → Application API → Dominio wallet → SPV/Sync → Rete → Crittografia → Persistenza. Ogni livello dipende solo verso il basso.
|
||||
- **Profilo di rete (§3):** tutte le costanti di catena (prefissi indirizzi, header BIP32, HRP bech32, genesi, porte, coin_type 746) vanno **centralizzate in `Core/Chain`** via `NetworkBuilder` e selezionabili per rete (mainnet/testnet/regtest). Nessun magic number sparso nel codice.
|
||||
- **LWMA / skip PoW (§3, §7):** la catena usa difficoltà LWMA con blocchi da 2 minuti; un client SPV non può ricalcolarla, quindi `skip_pow_validation = true` e la fiducia è ancorata ai **checkpoint hardcoded** (§7.3). Questo strato è custom: NBitcoin assume il retargeting di Bitcoin.
|
||||
- **Cosa fornisce NBitcoin vs cosa è custom (§19.2):** NBitcoin copre rete custom, BIP32/39, indirizzi, transazioni, PSBT, firma, encoding, hashing — **non reimplementarli**. Va scritto a mano: client JSON-RPC del server di indicizzazione (protocollo ElectrumX-like, §10) con pool, TLS pinning TOFU e proxy/Tor; sincronizzazione SPV con verifica Merkle (§7.4); validazione header/checkpoint; coin selection e fee policy; file wallet JSON cifrato versionato.
|
||||
- **PSBT-centrico (§6.5):** ogni flusso di firma passa per PSBT (offline, air-gapped, multisig, hardware).
|
||||
- **Le porte di default (50001/50002) sono del server di indicizzazione**, non la porta P2P del nodo (2333): il wallet SPV parla solo col server di indicizzazione.
|
||||
- **Stato implementato (passi 1–7 del §16):** `Core/Chain` profili rete; `Core/Crypto` BIP39/32/SLIP-132/HdAccount; `Core/Storage` file wallet JSON v1 + AES-GCM (PBKDF2-SHA512) + percorsi dati; `Core/Net` ElectrumClient (JSON-RPC newline su TCP/TLS, TOFU in `server-certs.json`); `Core/Spv` scripthash, verifica Merkle obbligatoria su ogni tx confermata, sincronizzazione con gap limit; `Core/Wallet` TransactionFactory (RBF on, send-all, PSBT per watch-only) e WalletLoader (doc→account). GUI Avalonia a pannello unico in `MainWindowViewModel`. Mancano (TODO §16 passi 8-9): multisig, hardware wallet, coin control UI, fee ETA/mempool, RBF/CPFP UI, header chain completa su disco, pool multi-server, proxy/Tor.
|
||||
|
||||
## Regole di lavoro
|
||||
|
||||
- **Test cross-implementazione obbligatori (§16):** ad ogni passo confrontare indirizzi, txid e PSBT con un wallet di riferimento (golden vectors). Un indirizzo o txid diverso è un bug bloccante.
|
||||
- **Sicurezza (§17):** seed e chiavi private mai in chiaro su disco, mai nei log, mai in rete; ogni risposta dei server va validata con prove di Merkle + checkpoint; watch-only realmente read-only.
|
||||
- Le funzionalità marcate *(opzionale)* nel blueprint possono essere rimandate ma vanno comunque considerate nella progettazione.
|
||||
+670
@@ -0,0 +1,670 @@
|
||||
# Blueprint — Wallet desktop per criptovaluta UTXO/SPV
|
||||
|
||||
> Specifica **autonoma e indipendente dal linguaggio** per costruire da zero un wallet
|
||||
> **solo desktop** (Windows e Linux), orientato al power-user come Sparrow Wallet.
|
||||
>
|
||||
> Il documento è pensato per essere letto e implementato **passo per passo**: contiene
|
||||
> tutto il necessario — algoritmi, strutture dati, parametri, protocollo di rete e
|
||||
> sequenza di costruzione — senza presupporre un framework, un linguaggio o un codice
|
||||
> sorgente preesistente. Ogni funzionalità elencata va considerata **parte del prodotto
|
||||
> completo**; quelle marcate *(opzionale)* possono essere rimandate a release successive
|
||||
> ma sono comunque documentate.
|
||||
|
||||
---
|
||||
|
||||
## 0. Glossario rapido
|
||||
|
||||
| Termine | Significato |
|
||||
|---|---|
|
||||
| **SPV** | Simplified Payment Verification: il wallet non scarica la catena, verifica le transazioni tramite prove di Merkle sugli header dei blocchi. |
|
||||
| **UTXO** | Unspent Transaction Output: una "moneta" non spesa; il saldo è la somma degli UTXO controllati dal wallet. |
|
||||
| **HD** | Hierarchical Deterministic: tutte le chiavi derivano da un seed unico (BIP32). |
|
||||
| **PSBT** | Partially Signed Bitcoin Transaction: formato standard per transazioni firmate parzialmente (offline, multisig, hardware). |
|
||||
| **Watch-only** | Wallet che conosce solo le chiavi pubbliche: vede saldo e storico ma non può firmare. |
|
||||
| **Server di indicizzazione** | Server che indicizza la catena e risponde alle query del client (protocollo §10). |
|
||||
| **Scripthash** | SHA-256 dello scriptPubKey con byte invertiti: chiave con cui il server indicizza gli indirizzi. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Visione del prodotto
|
||||
|
||||
Un wallet **desktop nativo** con queste qualità target (modello Sparrow):
|
||||
|
||||
- **Solo desktop**: nessuna UI mobile. UX densa, orientata a trasparenza e controllo.
|
||||
- **Single-sig e multisig** di prima classe, con supporto hardware wallet.
|
||||
- **Controllo totale su monete e fee**: coin control (UTXO), selezione manuale, etichette,
|
||||
controllo fee, RBF/CPFP.
|
||||
- **PSBT-centrico**: ogni flusso di firma passa per PSBT, abilitando firma offline,
|
||||
air-gapped e collaborativa.
|
||||
- **Leggero (SPV)**: avvio immediato, nessun full node richiesto (ma con possibilità di
|
||||
collegare un server proprio).
|
||||
- **Privacy-aware**: coin selection che preserva la privacy, supporto proxy/Tor,
|
||||
possibilità di server privato.
|
||||
- **Eseguibile distribuibile**: binario per Windows e Linux, firma del codice, build
|
||||
riproducibili.
|
||||
|
||||
L'applicazione è strutturata in due grandi blocchi: un **core** (logica pura, senza UI) e
|
||||
una **GUI desktop** sopra di esso. Tutta la logica di seguito appartiene al core, tranne
|
||||
dove indicato.
|
||||
|
||||
---
|
||||
|
||||
## 2. Architettura a livelli (target)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ GUI desktop — viste, wizard, coin control, dialog di firma │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Application API — casi d'uso: crea/apri wallet, invia, ricevi, │
|
||||
│ firma, storico, gestione canali, ecc. │
|
||||
│ Esposta anche come CLI + RPC locale (§13). │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Dominio wallet — wallet, keystore, indirizzi, UTXO, contatti, │
|
||||
│ fatture, richieste, costruzione/firma tx, │
|
||||
│ coin selection, fee policy │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ SPV / Sincronizz. — synchronizer, verifier (Merkle), gestione │
|
||||
│ header/checkpoint, saldo e storico │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Rete — pool di connessioni, selezione server, TLS │
|
||||
│ con pinning, proxy, protocollo di query (§10) │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Crittografia — secp256k1, hash, BIP32/39/SLIP39, base58, │
|
||||
│ bech32, cifratura file wallet, ECIES │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Persistenza — file wallet JSON cifrato, config, percorsi │
|
||||
│ Lightning (⏳ poi) — sottosistema separato, fase successiva (§11) │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Regola di dipendenza:** ogni livello dipende solo verso il basso. La GUI parla solo con
|
||||
l'Application API, mai direttamente con rete o crittografia. Questo permette di avere
|
||||
CLI, test automatici e GUI sullo stesso core.
|
||||
|
||||
### Requisiti di componenti (astratti, non legati al linguaggio)
|
||||
Indipendentemente dallo stack scelto, servono librerie/moduli che forniscano:
|
||||
1. **Curva ellittica secp256k1** (firma/verifica ECDSA + Schnorr, tweak chiavi). *Non
|
||||
reimplementare a mano la matematica della curva: usare una libreria auditata.*
|
||||
2. **Funzioni hash**: SHA-256, doppio SHA-256, RIPEMD-160, HASH160 (SHA256→RIPEMD160),
|
||||
SHA-512, HMAC-SHA512, PBKDF2-HMAC-SHA512.
|
||||
3. **Encoding**: Base58Check, Bech32 e Bech32m.
|
||||
4. **Cifratura simmetrica** (AES-256) e **ECIES** per messaggi.
|
||||
5. **TLS** con accesso al certificato per il pinning.
|
||||
6. **JSON** per file wallet e protocollo.
|
||||
7. **Generatore di numeri casuali crittografico** per seed e nonce.
|
||||
|
||||
---
|
||||
|
||||
## 3. Profilo di rete / catena (parametri da definire PRIMA di tutto)
|
||||
|
||||
Un wallet è legato a una catena specifica tramite un insieme di costanti. **Vanno fissate
|
||||
all'inizio**: un valore sbagliato produce indirizzi non validi o fa rifiutare la catena.
|
||||
Definire un oggetto/struct di configurazione con i seguenti campi.
|
||||
|
||||
> I valori del profilo di riferimento qui sotto sono stati **verificati contro il sorgente
|
||||
> del nodo** (`chainparams.cpp` / `pow.cpp`): sono i parametri di consenso autoritativi.
|
||||
|
||||
| Campo | Descrizione | Esempio (profilo di riferimento mainnet) |
|
||||
|---|---|---|
|
||||
| `net_name` | nome rete / sottocartella dati | `mainnet` |
|
||||
| `coin_unit` | simbolo unità | `PLM` |
|
||||
| `wif_prefix` | prefisso chiavi private WIF | `0x80` |
|
||||
| `addr_p2pkh` | byte versione indirizzi legacy | `55` → indirizzi che iniziano con `P` |
|
||||
| `addr_p2sh` | byte versione indirizzi P2SH | `5` → iniziano con `3` |
|
||||
| `segwit_hrp` | prefisso human-readable bech32 | `plm` → indirizzi `plm1...` |
|
||||
| `bolt11_hrp` | prefisso fatture Lightning | `plm` |
|
||||
| `genesis_hash` | hash del blocco genesi (mainnet riusa la genesi di Bitcoin) | `000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f` |
|
||||
| `default_ports` | porte del **server di indicizzazione** usato dal wallet | `{tcp: 50001, ssl: 50002}` |
|
||||
| `bip44_coin_type` | coin type SLIP-0044 nel derivation path (*convenzione wallet, non parametro di consenso del nodo*) | `746` |
|
||||
| `uri_scheme` | schema URI pagamenti (BIP21) | `palladium:` |
|
||||
| `explorer_url` | block explorer di default | `https://explorer.palladium-coin.com/` |
|
||||
| `skip_pow_validation` | salta la verifica difficoltà — **obbligatorio**: la catena usa LWMA (vedi nota sotto) | `true` |
|
||||
|
||||
> **Nota sulle porte.** Le `default_ports` sopra sono quelle del **server di indicizzazione**
|
||||
> (es. ElectrumX-like) a cui si connette il wallet, **non** la porta P2P del nodo (che nel
|
||||
> sorgente è `2333` mainnet / `12333` testnet / `28444` regtest). Sono due cose distinte: il
|
||||
> wallet SPV parla solo col server di indicizzazione.
|
||||
>
|
||||
> **Nota sulla difficoltà (LWMA).** Il nodo calcola la difficoltà con **LWMA** (Linearly
|
||||
> Weighted Moving Average) e un **tempo di blocco di 2 minuti** (`nPowTargetSpacingV2 = 120s`;
|
||||
> il vecchio `nPowTargetTimespan` di 14 giorni è mantenuto solo per la validazione storica).
|
||||
> Un client SPV non è in grado di ricalcolare LWMA, quindi `skip_pow_validation` **deve**
|
||||
> essere `true` e la fiducia sulla catena va ancorata ai **checkpoint** (§7.3).
|
||||
|
||||
**Header chiavi estese BIP32** (mainnet di riferimento) — servono per serializzare/parsare
|
||||
xprv/xpub per ciascun tipo di indirizzo:
|
||||
|
||||
| Tipo indirizzo | prefisso priv | header priv | prefisso pub | header pub |
|
||||
|---|---|---|---|---|
|
||||
| standard (P2PKH) | xprv | `0x0488ade4` | xpub | `0x0488b21e` |
|
||||
| segwit wrapped (P2WPKH-P2SH) | yprv | `0x049d7878` | ypub | `0x049d7cb2` |
|
||||
| multisig wrapped (P2WSH-P2SH) | Yprv | `0x0295b005` | Ypub | `0x0295b43f` |
|
||||
| native segwit (P2WPKH) | zprv | `0x04b2430c` | zpub | `0x04b24746` |
|
||||
| native segwit multisig (P2WSH) | Zprv | `0x02aa7a99` | Zpub | `0x02aa7ed3` |
|
||||
|
||||
**Testnet** (profilo di riferimento): `wif_prefix=0xff`, `addr_p2pkh=127`, `addr_p2sh=115`,
|
||||
`segwit_hrp=tplm`, `bip44_coin_type=1`, header tprv/tpub `0x04358394`/`0x043587cf`, ecc.
|
||||
**Regtest**: `segwit_hrp=rplm`.
|
||||
|
||||
**Server iniziali** (bootstrap, profilo di riferimento): forniti come lista
|
||||
`host:porta_tcp:porta_ssl`; il pool li usa per il primo contatto e poi scopre altri peer
|
||||
via protocollo (`server.peers.subscribe`).
|
||||
|
||||
> Tutte le costanti devono essere **centralizzate** in un solo punto e selezionabili per
|
||||
> rete (mainnet/testnet/regtest), così da non disperdere magic number nel codice.
|
||||
|
||||
---
|
||||
|
||||
## 4. Crittografia, seed e gestione chiavi
|
||||
|
||||
### 4.1 Seed e mnemoniche — tutti gli schemi supportati
|
||||
Il wallet deve supportare **più schemi di seed** e saperli riconoscere automaticamente:
|
||||
|
||||
1. **Seed nativo versionato**: mnemonica con un prefisso di versione codificato via HMAC
|
||||
(distingue i sottotipi `standard`, `segwit`, `2fa`, `2fa-segwit`). In creazione si
|
||||
garantisce che la mnemonica generata **non** sia contemporaneamente un valido BIP39.
|
||||
2. **BIP39**: import/restore di seed standard a **12 o 24 parole**, con verifica del
|
||||
checksum.
|
||||
3. **SLIP39 (Shamir Secret Sharing)** *(opzionale)*: seed suddiviso in più *share*; servono
|
||||
K share su N per ricostruirlo.
|
||||
4. **Formato seed legacy** *(opzionale, retrocompatibilità)*: vecchio schema pre-BIP32.
|
||||
|
||||
**Wordlist multilingua**: inglese, spagnolo, giapponese, portoghese, cinese. Le parole
|
||||
vanno normalizzate (NFKD) prima della derivazione.
|
||||
|
||||
**Passphrase / extension word (opzionale ma obbligatoria da implementare):** parola/e
|
||||
aggiuntive combinate col seed tramite **PBKDF2-HMAC-SHA512, 2048 round**, con salt
|
||||
`"<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 (§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 <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.*
|
||||
Reference in New Issue
Block a user