using System.Globalization; namespace PalladiumWallet.Core.Wallet; /// /// Conversione satoshi ↔ unità coin (8 decimali) per visualizzazione e input. /// Si lavora sempre in satoshi internamente; la stringa è solo presentazione. /// public static class CoinAmount { public const long SatsPerCoin = 100_000_000; /// Unità di visualizzazione selezionabili (config §8). public static readonly string[] Units = ["PLM", "mPLM", "µPLM", "sat"]; /// (satoshi per unità, decimali mostrati) di ciascuna unità. private static (long Factor, int Decimals) Of(string unit) => unit switch { "PLM" => (SatsPerCoin, 8), "mPLM" => (100_000, 5), "µPLM" => (100, 2), "sat" => (1, 0), _ => throw new ArgumentException($"Unknown coin unit: {unit}", nameof(unit)), }; public static string Format(long sats, string unit = "") => (sats / (decimal)SatsPerCoin).ToString("0.00000000", CultureInfo.InvariantCulture) + (unit.Length > 0 ? " " + unit : ""); /// Formatta nell'unità scelta (es. 150000 sat → "1.50000 mPLM"). public static string FormatIn(long sats, string unit, bool withLabel = true) { var (factor, decimals) = Of(unit); var value = (sats / (decimal)factor).ToString( decimals == 0 ? "0" : "0." + new string('0', decimals), CultureInfo.InvariantCulture); return withLabel ? $"{value} {unit}" : value; } /// Parsa un importo espresso nell'unità scelta in satoshi. public static bool TryParseIn(string text, string unit, out long sats) { sats = 0; var (factor, _) = Of(unit); text = text.Trim().Replace(',', '.'); if (!decimal.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var value) || value < 0) return false; try { var satsDecimal = value * factor; if (satsDecimal % 1 != 0) return false; sats = (long)satsDecimal; } catch (OverflowException) { return false; } return true; } /// Parsa un importo in coin (punto o virgola decimale) in satoshi. public static bool TryParseCoins(string text, out long sats) { sats = 0; text = text.Trim().Replace(',', '.'); if (!decimal.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out var coins) || coins < 0) return false; try { var satsDecimal = coins * SatsPerCoin; if (satsDecimal % 1 != 0) return false; sats = (long)satsDecimal; } catch (OverflowException) { return false; } return true; } }