Ho costruito con l’AI un software per le tasse crypto: ecco com’è andata
Le tasse sulle crypto mi hanno sempre messo ansia.
Non perché abbia chissà quali patrimoni da dichiarare — parliamo di piccole cifre, roba da investitore curioso più che da trader. Il problema è che ogni anno arrivo a primavera con la stessa sensazione: devo capire cosa fare con il Quadro RW e il Quadro RT per la dichiarazione delle criptovalute, e non ho idea da dove partire.
Quest’anno ho deciso di fare le cose diversamente. Invece di cercare tutorial su YouTube o sperare che il commercialista capisse qualcosa di crypto, ho provato a costruire uno strumento con l’AI. Qualcosa di mio, locale, che non manda i miei dati in giro e che — idealmente — mi tira fuori i numeri già pronti.
Ho usato Google AI Studio con Gemini. E ci ho passato molto più tempo del previsto.
Prima il contesto, poi il codice
La prima cosa che ho fatto non è stata chiedere di scrivere codice. Ho caricato nella chat i documenti sulla tassazione delle criptovalute in Italia — la normativa TUIR, le novità della Legge di Bilancio 2024, 2025 e 2026, le istruzioni ministeriali per la compilazione dei quadri fiscali.
Il ragionamento era semplice: se voglio che l’AI mi aiuti a costruire qualcosa di fiscalmente corretto, deve prima capire le regole del gioco. Non puoi chiedere a qualcuno di compilare un modulo se non sa cosa significa ogni campo.
Questa fase ha funzionato bene. Gemini ha assorbito i documenti e da quel momento sapeva di cosa stavamo parlando quando dicevo “Colonna 7 del Quadro RW” o “franchigia 2.000 euro per il 2024”. Non ho dovuto spiegare ogni volta da capo.
L’idea era semplice. L’esecuzione un po’ meno.
L’obiettivo tecnico era chiaro: dato in input il mio wallet Bitcoin — o meglio, la chiave pubblica estesa (xPub, yPub o zPub) che permette di derivare tutti gli indirizzi senza esporre le chiavi private — il software doveva recuperare la cronologia delle transazioni dalla blockchain, valorizzarle in euro alla data storica, e calcolare quello che serve per RW e RT.
Per farlo abbiamo usato Python con Streamlit per l’interfaccia, l’API pubblica di mempool.space per i dati on-chain, e yfinance per i prezzi storici di BTC/EUR.
Sulla carta funziona tutto. In pratica ci siamo scontrati con una serie di ostacoli in sequenza che, ogni volta che ne superavamo uno, ne scoprivano un altro.
Primo problema: le chiavi zPub. Alcuni wallet — Electrum tra questi — esportano le chiavi con un livello crittografico “sbagliato” rispetto a quello che si aspetta la libreria bip_utils. La libreria le rifiutava senza pietà. Abbiamo dovuto scrivere un decodificatore custom che intercetta la chiave, corregge il byte di profondità al volo, sostituisce il prefisso con uno standard, ricalcola il checksum e la “riformatta” prima di passarla alla libreria. Artigianale, ma funziona.
Secondo problema: un bug nel decodificatore stesso. Mentre scrivevamo quel decodificatore, un errore nel conteggio degli zeri iniziali in Base58 rompeva la firma di sicurezza della chiave. Risultato: tutto sembrava andare bene finché non controllavi i dati e vedevi che erano sbagliati. Quel tipo di bug silenzioso che ti fa perdere un’ora prima di trovarlo.
Terzo problema: i blocchi API. Appena abbiamo aumentato il numero di indirizzi da scansionare — necessario per coprire l’intero wallet — mempool.space ha iniziato a bloccarci con errori 429. Prima soluzione: un sistema di retry con pause crescenti. Funzionava, ma era lento.
Il secondo giro: quando “funziona” non basta
A questo punto il software girava. Ma girava lentamente — scansionare decine di indirizzi richiedeva minuti. Così abbiamo deciso di renderlo asincrono: più richieste in parallelo invece di una alla volta.
Prima scelta: aiohttp, la libreria Python standard per le chiamate asincrone. Risultato: mempool.space ci ha bloccati quasi istantaneamente. Eravamo troppo veloci, e il server ci ha presi per un attacco.
Seconda scelta: aiohttp con semafori e pause forzate tra una richiesta e l’altra. Funzionava meglio, ma su Windows aiohttp ha un bug noto nella risoluzione DNS che si manifestava in modo intermittente. L’applicazione diventava inaffidabile.
Soluzione finale, e la più elegante di tutte: abbandonare aiohttp e tornare alla libreria requests — quella vecchia, solida, che non dà mai problemi — ma “avvolgerla” dentro asyncio.to_thread. In pratica: le chiamate restano sincrone e stabili, ma girano in thread paralleli gestiti da un event loop asincrono. Il meglio dei due mondi. Veloce e affidabile.
I dettagli fiscali che fanno la differenza
Mentre sistemavamo l’architettura, sono emersi alcuni casi limite fiscali che all’inizio non avevamo considerato.
Il più interessante: se apri un wallet durante l’anno, il valore iniziale per il Quadro RW non è zero — è il controvalore in euro del primo versamento ricevuto. Sembra ovvio a dirlo, ma il codice originale metteva zero e nessuno se ne era accorto. Abbiamo riscritto il motore RW con un “contatore giornaliero esatto” che gestisce correttamente sia l’apertura che la chiusura di un wallet in corso d’anno.
Per il Quadro RT, il software applica il metodo LIFO — l’ultimo bitcoin entrato è il primo a uscire ai fini fiscali — con le aliquote aggiornate: 26% con franchigia di 2.000 euro per il 2024, 26% senza franchigia per il 2025, 33% dal 2026. E se yfinance non risponde e i prezzi storici non sono disponibili, il software si blocca e segnala l’errore invece di continuare i calcoli con prezzi a zero. Meglio un errore esplicito che un CSV sbagliato da consegnare al commercialista.
Cosa produce alla fine
Il risultato si chiama BTC IT Tax Calculator — il codice è su GitHub, se vuoi darci un’occhiata o usarlo tu stesso. Gira in locale, non invia nulla da nessuna parte, e produce due output: i dati per il Quadro RW (patrimonio al 1° gennaio e al 31 dicembre, giorni di possesso) e un CSV con le plusvalenze calcolate per il Quadro RT, pronto da portare al commercialista.
C’è anche una checkbox obbligatoria all’avvio che ti fa accettare un disclaimer prima di procedere. Perché il software fa i calcoli, ma non è un consulente fiscale — e questa distinzione va resa esplicita.
Il limite principale rimane uno: il software non sa distinguere una vendita da un giroconto tra wallet propri. Se sposti bitcoin da un wallet a un exchange, tecnicamente è un’uscita — ma non è una cessione tassabile. Quella cernita la fa ancora l’utente, a mano, sul CSV.
Cosa ho imparato
Gemini con Google AI Studio si è comportato bene come co-sviluppatore lungo tutto il percorso. Il fatto di aver caricato i documenti fiscali all’inizio ha fatto una differenza reale: le soluzioni proposte erano contestualizzate, non generiche.
Detto questo, non è stata una passeggiata. Ogni ostacolo tecnico richiedeva un bel po’ di avanti e indietro. E alcune delle lezioni più utili sono venute dagli errori: i bug silenziosi che restituiscono risultati sbagliati senza dire niente sono i peggiori — molto più fastidiosi di quelli che fanno crashare tutto, perché almeno quelli li vedi subito.
L’altra cosa che ho capito: quando scrapi API pubbliche gratuite, essere troppo veloci equivale a non funzionare. Il software finale è paradossalmente più performante di quello “ottimizzato” perché rispetta i limiti dell’API invece di ignorarli.
Per le prossime dichiarazioni, almeno, parto da qualcosa di concreto. E so esattamente cosa fa — e cosa non fa.
