@@ -209,7 +209,6 @@ async def run_remote_command(command, timeout=DEFAULT_SSH_TIMEOUT):
209209 logger .error (f"SSH Error (code { e .returncode } ): { err_msg } " )
210210 return None , f"⚠️ SSH Error (code { e .returncode } ): { err_msg } "
211211 except subprocess .TimeoutExpired :
212- logger .error ("Remote SSH Timeout." )
213212 return None , "⚠️ Remote SSH Timeout (node unresponsive)"
214213 except Exception as e :
215214 logger .error (f"Generic SSH error: { e } " )
@@ -529,8 +528,13 @@ async def monitor_lnd_task(app):
529528 newch = cur_ch - prev_channels
530529 closed = prev_channels - cur_ch
531530 for cp in newch :
531+ # CORREZIONE: Recupera l'alias del partner del canale
532+ remote_pubkey = next ((c .remote_pubkey for c in channels if c .channel_point == cp ), None )
533+ alias = get_alias_for_pubkey (client , remote_pubkey ) if remote_pubkey else None
534+ display_name = alias or remote_pubkey [:10 ] + '...'
535+
532536 logger .info (f"Channel Opened: { cp } " )
533- await send_alert (app , f"🔔 Channel Opened: **{ cp } **" )
537+ await send_alert (app , f"🔔 Channel Opened with **{ display_name } **" )
534538 for cp in closed :
535539 logger .info (f"Channel Closed: { cp } " )
536540 await send_alert (app , f"🔕 Channel Closed: **{ cp } **" )
@@ -542,15 +546,25 @@ async def monitor_lnd_task(app):
542546 try :
543547 invoices = client .list_invoices ().invoices
544548 cur_settled = set ()
549+ # CORREZIONE: Ottenere il valore in sats e formattare l'alert
545550 for inv in invoices :
546551 settled = getattr (inv , "settled" , False )
547552 if settled :
548- r = getattr (inv , "r_hash_str" , None ) or str (getattr (inv , "add_index" , "" ))
549- cur_settled .add (r )
550- new_settled = cur_settled - prev_settled_invoices
551- for r in new_settled :
552- logger .info (f"Invoice Settled: { r } " )
553- await send_alert (app , f"💰 Invoice Settled: **{ r } **" )
553+ # Usiamo r_hash_str come chiave per lo stato
554+ r_hash = getattr (inv , "r_hash_str" , None ) or str (getattr (inv , "add_index" , "" ))
555+ value_sats = getattr (inv , "value" , 0 )
556+ cur_settled .add ((r_hash , value_sats ))
557+
558+ # Calcola le nuove fatture saldate
559+ new_settled = [ (rh , val ) for rh , val in cur_settled if rh not in set (rh_prev for rh_prev , val_prev in prev_settled_invoices ) ]
560+ removed_settled = [ (rh , val ) for rh , val in prev_settled_invoices if rh not in set (rh_curr for rh_curr , val_curr in cur_settled ) ]
561+
562+ for rh , value_sats in new_settled :
563+ logger .info (f"Invoice Settled: { rh } for { value_sats } sats" )
564+ # INVIO ALERT CON VALORE CORRETTO E TRADOTTO
565+ await send_alert (app , f"💰 Invoice Settled: **{ value_sats :,} sats**" )
566+
567+ # Aggiorna lo stato dei pagamenti
554568 prev_settled_invoices = cur_settled
555569 except Exception as e :
556570 await send_alert (app , f"⚠️ LND invoices error: { e } " )
@@ -691,25 +705,25 @@ async def restartlnd_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
691705 await update .message .reply_text (final_msg , parse_mode = 'Markdown' )
692706
693707async def mempool_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
694- logger .info (f"Command /mempool received from { update .effective_user .id } " )
708+ logger .info (f"Comando /mempool ricevuto da { update .effective_user .id } " )
695709 fees , error = await crypto_utils .get_fee_data ()
696710
697711 if error :
698712 await update .message .reply_text (error )
699713 return
700714
701715 report = (
702- f"⛽ Mempool Fees (sat/vB):\n "
703- f"- Fast (Next block): **{ fees .get ('fastestFee' , 'n/a ' )} **\n "
704- f"- Medium (30 min): **{ fees .get ('halfHourFee' , 'n/a ' )} **\n "
705- f"- Low (1 hr): **{ fees .get ('hourFee' , 'n/a ' )} **"
716+ f"⛽ Tariffe Mempool Attuali (sat/vB):\n "
717+ f"- Veloce (Next block): **{ fees .get ('fastestFee' , 'n/d ' )} **\n "
718+ f"- Media (30 min): **{ fees .get ('halfHourFee' , 'n/d ' )} **\n "
719+ f"- Bassa (1 hr): **{ fees .get ('hourFee' , 'n/d ' )} **"
706720 )
707721
708722 await update .message .reply_text (report , parse_mode = 'Markdown' )
709723
710724
711725async def btcinfo_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
712- logger .info (f"Command /btcinfo received from { update .effective_user .id } " )
726+ logger .info (f"Comando /btcinfo ricevuto da { update .effective_user .id } " )
713727
714728 info , error = await crypto_utils .get_onchain_info ()
715729
@@ -724,31 +738,31 @@ async def btcinfo_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
724738 adj_date = time .strftime ('%d-%m-%Y %H:%M UTC' , time .localtime (ts ))
725739
726740 report = (
727- f"📊 **Bitcoin On-Chain Analysis **\n "
741+ f"📊 **Analisi On-Chain Bitcoin **\n "
728742 f"----------------------------------------\n "
729- f"⚒️ Current Difficulty : **{ formatted_difficulty :.2f} T**\n "
730- f"⚙️ Adjustment Progress : **{ info ['adjustment_progress' ]:.2f} %**\n "
731- f"🧱 Remaining Blocks : **{ info ['blocks_remaining' ]} **\n "
732- f"⏳ Estimated Next Adjustment : *{ adj_date } *\n "
743+ f"⚒️ Difficoltà Attuale : **{ formatted_difficulty :.2f} T**\n "
744+ f"⚙️ Progresso Aggiustamento : **{ info ['adjustment_progress' ]:.2f} %**\n "
745+ f"🧱 Blocchi Rimanenti : **{ info ['blocks_remaining' ]} **\n "
746+ f"⏳ Stima Prossimo Aggiustamento : *{ adj_date } *\n "
733747 )
734748
735749 if info ['adjustment_progress' ] > 80 :
736- report += "\n 🔔 *Note: Difficulty adjustment is imminent (over 80%).*"
750+ report += "\n 🔔 *Nota: L'aggiustamento della difficoltà è imminente (oltre l' 80%).*"
737751
738752 await update .message .reply_text (report , parse_mode = 'Markdown' )
739753
740754async def price_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
741- logger .info (f"Command /price received from { update .effective_user .id } " )
755+ logger .info (f"Comando /price ricevuto da { update .effective_user .id } " )
742756
743757 currency = context .args [0 ] if context .args else "EUR"
744758 prices , error = await crypto_utils .get_price_data (currency = currency )
745759
746760 if error or not prices :
747- await update .message .reply_text (f"⚠️ Error retrieving prices : { error or 'Data missing ' } " )
761+ await update .message .reply_text (f"⚠️ Errore nel recupero dei prezzi : { error or 'Dati mancanti ' } " )
748762 return
749763
750764 report = (
751- f"💸 Current Bitcoin Prices :\n "
765+ f"💸 Prezzi Attuali di Bitcoin :\n "
752766 f"- BTC/EUR: **€{ prices .get ('eur' , 0 ):,.2f} **\n "
753767 f"- BTC/USD: **${ prices .get ('usd' , 0 ):,.2f} **"
754768 )
@@ -757,7 +771,7 @@ async def price_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
757771
758772
759773async def peers_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
760- logger .info (f"Command /peers received from { update .effective_user .id } " )
774+ logger .info (f"Comando /peers ricevuto da { update .effective_user .id } " )
761775
762776 def escape_html (text ):
763777 if text is None :
@@ -770,7 +784,7 @@ def escape_html(text):
770784 client = get_lnd_client ()
771785 peers = client .list_peers ().peers
772786 if not peers :
773- await update .message .reply_text ("No connected peers " )
787+ await update .message .reply_text ("Nessun peer connesso " )
774788 return
775789
776790 lines = []
@@ -779,47 +793,47 @@ def escape_html(text):
779793 addr = getattr (p , "address" , "" )
780794 alias = get_alias_for_pubkey (client , pk )
781795
782- # Sanitize dynamic elements and use HTML <b> for bold
796+ # Sanifica tutti gli elementi dinamici e usa l' HTML per il grassetto ( <b>)
783797 display_alias = alias or pk [:10 ] + '...'
784798 safe_alias = escape_html (display_alias )
785799 safe_pk = escape_html (pk )
786800 safe_addr = escape_html (addr )
787801
788802 lines .append (f"- <b>{ safe_alias } </b> ({ safe_pk } ) { safe_addr } " )
789803
790- msg = "🔗 Active Peers:\n " + "\n " .join (lines )
804+ msg = "🔗 Peers attivi :\n " + "\n " .join (lines )
791805
792806 # Send in HTML mode
793807 await update .message .reply_text (msg , parse_mode = 'HTML' )
794808
795809 except Exception as e :
796- logger .error (f"Error executing /peers command : { e } " )
810+ logger .error (f"Errore comando /peers: { e } " )
797811 await update .message .reply_text (f"⚠️ LND error: { e } " )
798812
799813async def channels_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
800- logger .info (f"Command /channels received from { update .effective_user .id } " )
814+ logger .info (f"Comando /channels ricevuto da { update .effective_user .id } " )
801815 try :
802816 client = get_lnd_client ()
803817 channels = client .list_channels ().channels
804818 if not channels :
805- await update .message .reply_text ("No open channels " )
819+ await update .message .reply_text ("Nessun canale aperto " )
806820 return
807- msg = "🔔 Open Channels :\n " + "\n " .join (f"- **{ getattr (c ,'remote_pubkey' ,'?' )[:10 ] + '...' } ** ({ getattr (c ,'capacity' ,'?' )} sats)" for c in channels )
821+ msg = "🔔 Canali Aperti :\n " + "\n " .join (f"- **{ getattr (c ,'remote_pubkey' ,'?' )[:10 ] + '...' } ** ({ getattr (c ,'capacity' ,'?' )} sats)" for c in channels )
808822 await update .message .reply_text (msg , parse_mode = 'Markdown' )
809823 except Exception as e :
810- logger .error (f"Error executing /channels command : { e } " )
824+ logger .error (f"Errore comando /channels: { e } " )
811825 await update .message .reply_text (f"⚠️ LND error: { e } " )
812826
813827async def invoices_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
814- logger .info (f"Command /invoices received from { update .effective_user .id } " )
828+ logger .info (f"Comando /invoices ricevuto da { update .effective_user .id } " )
815829 try :
816830 client = get_lnd_client ()
817831 invoices = client .list_invoices ().invoices
818832 if not invoices :
819- await update .message .reply_text ("No invoices " )
833+ await update .message .reply_text ("Nessuna invoice " )
820834 return
821835 last = invoices [- 10 :]
822- msg = "💰 Last Invoices (max 10):\n "
836+ msg = "💰 Ultime Invoice (max 10):\n "
823837 for i in last :
824838 memo = getattr (i , "memo" , "" )
825839 value = getattr (i , "value" , 0 )
@@ -828,36 +842,36 @@ async def invoices_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
828842 msg += f"- *{ memo } * : **{ value } sats** - Status: { status_emoji } \n "
829843 await update .message .reply_text (msg , parse_mode = 'Markdown' )
830844 except Exception as e :
831- logger .error (f"Error executing /invoices command : { e } " )
845+ logger .error (f"Errore comando /invoices: { e } " )
832846 await update .message .reply_text (f"⚠️ LND error: { e } " )
833847
834848async def hardware_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
835- logger .info (f"Command /hardware received from { update .effective_user .id } " )
836- # Remote Hardware Status
849+ logger .info (f"Comando /hardware ricevuto da { update .effective_user .id } " )
850+ # Stato Hardware Remoto del NODO (CPU/RAM/Load)
837851 remote_data , remote_system_report = await get_remote_system_status ()
838852
839- # Remote Disk Status
853+ # Stato Dischi Remoto del NODO
840854 remote_disk_report , _ = await get_remote_disk_status (REMOTE_MOUNTS_TO_CHECK )
841855
842856 final_message = (
843- f"--- 💾 Hardware NODE (Remote ) ---\n "
857+ f"--- 💾 Hardware NODO Bitcoin (Remoto ) ---\n "
844858 f"{ remote_system_report } \n "
845- f"Disks :\n "
859+ f"Dischi :\n "
846860 f"{ remote_disk_report } "
847861 )
848862 await update .message .reply_text (final_message , parse_mode = 'Markdown' )
849863
850864
851865async def netscan_cmd (update : Update , context : ContextTypes .DEFAULT_TYPE ):
852- logger .info (f"Command /netscan received from { update .effective_user .id } " )
866+ logger .info (f"Comando /netscan ricevuto da { update .effective_user .id } " )
853867
854868 if not context .args or len (context .args ) < 1 :
855- await update .message .reply_text ("⚠️ Usage : /netscan <subnet_base> (E.g. : /netscan 10.21.10)" , parse_mode = 'Markdown' )
869+ await update .message .reply_text ("⚠️ Uso : /netscan <subnet_base> (Es : /netscan 10.21.10)" , parse_mode = 'Markdown' )
856870 return
857871
858872 subnet_base = context .args [0 ].strip ()
859873
860- await update .message .reply_text (f"⏳ Starting lightweight ping scan on subnet **{ subnet_base } .x** (May take up to 2 minutes )..." , parse_mode = 'Markdown' )
874+ await update .message .reply_text (f"⏳ Avvio scansione ping leggera sulla subnet **{ subnet_base } .x** (Potrebbe richiedere fino a 2 minuti )..." , parse_mode = 'Markdown' )
861875
862876 # SSH Scan Command (ping sweep from the remote node)
863877 SCAN_CMD = (
@@ -867,38 +881,38 @@ async def netscan_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
867881 output , error = await run_remote_command (SCAN_CMD , timeout = 120 )
868882
869883 if error :
870- report = f"❌ **SCAN FAILED !** Error during SSH execution : { error } "
884+ report = f"❌ **SCAN FALLITO !** Errore durante l'esecuzione SSH : { error } "
871885 elif not output :
872- report = f"🔍 **SCAN COMPLETE :** No active hosts detected on subnet **{ subnet_base } .x**."
886+ report = f"🔍 **SCAN COMPLETATO :** Nessun host attivo rilevato sulla subnet **{ subnet_base } .x**."
873887 else :
874888 active_hosts = output .replace ('Host up: ' , '- ' ).replace (':' , '' ).splitlines ()
875- report = f"✅ **SCAN COMPLETE :** Detected **{ len (active_hosts )} ** active hosts on **{ subnet_base } .x**:\n " + "\n " .join (active_hosts )
889+ report = f"✅ **SCAN COMPLETATO :** Rilevati **{ len (active_hosts )} ** host attivi su **{ subnet_base } .x**:\n " + "\n " .join (active_hosts )
876890
877891 await update .message .reply_text (report , parse_mode = 'Markdown' )
878892
879893
880894async def main ():
881895 app = ApplicationBuilder ().token (TELEGRAM_TOKEN ).build ()
882- logger .info ("Telegram Bot started ." )
896+ logger .info ("Bot Telegram avviato ." )
883897
884898 await app .bot .set_my_commands ([
885- BotCommand ("start" , "Start the bot" ),
886- BotCommand ("status" , "Show node status " ),
887- BotCommand ("peers" , "List active peers" ),
888- BotCommand ("channels" , "List open channels " ),
889- BotCommand ("invoices" , "Last invoices " ),
890- BotCommand ("hardware" , "Node hardware status " ),
899+ BotCommand ("start" , "Avvia il bot" ),
900+ BotCommand ("status" , "Mostra lo stato del nodo " ),
901+ BotCommand ("peers" , "Lista dei peers" ),
902+ BotCommand ("channels" , "Lista dei canali " ),
903+ BotCommand ("invoices" , "Ultime invoice " ),
904+ BotCommand ("hardware" , "Stato hardware del NODO " ),
891905
892- # MONITORING AND MARKET
893- BotCommand ("mempool" , "BTC transaction fees (sat/vB)" ),
894- BotCommand ("price" , "BTC price in fiat (e.g., /price USD)" ),
895- BotCommand ("btcinfo" , "Bitcoin Difficulty and Adjustment Analysis " ),
906+ # MONITORAGGIO E MERCATO
907+ BotCommand ("mempool" , "Tariffe transazione BTC (sat/vB)" ),
908+ BotCommand ("price" , "Prezzo BTC in EUR/USD (es. /price USD)" ),
909+ BotCommand ("btcinfo" , "Analisi Difficoltà e Aggiustamento Bitcoin " ),
896910
897- # DIAGNOSTICS AND REMOTE ACTIONS
898- BotCommand ("diagnose" , "Status of LND and Bitcoin Core services " ),
899- BotCommand ("restartlnd" , "Restart LND service (Admin Only )" ),
900- BotCommand ("restartbtc" , "Restart Bitcoin Core (Admin Only )" ),
901- BotCommand ("netscan" , "Perform local network scan " )
911+ # DIAGNOSI E AZIONI REMOTE
912+ BotCommand ("diagnose" , "Stato dei servizi LND e Bitcoin Core" ),
913+ BotCommand ("restartlnd" , "Riavvia il servizio LND (Solo Admin )" ),
914+ BotCommand ("restartbtc" , "Riavvia Bitcoin Core (Solo Admin )" ),
915+ BotCommand ("netscan" , "Scansione di rete locale " )
902916 ])
903917
904918 app .add_handler (CommandHandler ("start" , start_cmd ))
@@ -909,7 +923,7 @@ async def main():
909923 app .add_handler (CommandHandler ("hardware" , hardware_cmd ))
910924 app .add_handler (CommandHandler ("netscan" , netscan_cmd ))
911925
912- # REGISTER NEW HANDLERS
926+ # REGISTRAZIONE NUOVI HANDLER
913927 app .add_handler (CommandHandler ("mempool" , mempool_cmd ))
914928 app .add_handler (CommandHandler ("price" , price_cmd ))
915929 app .add_handler (CommandHandler ("btcinfo" , btcinfo_cmd ))
@@ -922,8 +936,8 @@ async def main():
922936 loop .create_task (monitor_lnd_task (app ))
923937 loop .create_task (crypto_utils .surveillance_task (app ))
924938
925- print ("=== NodeSentinel Live & Fully Operational ===" )
926- logger .info ("Starting polling..." )
939+ print ("=== NodeSentinel Live & Full Running ===" )
940+ logger .info ("Avvio del polling..." )
927941 await app .run_polling ()
928942
929943# ---------- Run ----------
@@ -939,4 +953,3 @@ async def main():
939953 loop .run_until_complete (main ())
940954 finally :
941955 pass
942-
0 commit comments