diff --git a/Plugins/BTCPayServer.Plugins.Breez/BTCPayServer.Plugins.Breez.csproj b/Plugins/BTCPayServer.Plugins.Breez/BTCPayServer.Plugins.Breez.csproj index 330664b..714b274 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BTCPayServer.Plugins.Breez.csproj +++ b/Plugins/BTCPayServer.Plugins.Breez/BTCPayServer.Plugins.Breez.csproj @@ -8,7 +8,7 @@ Breez / Greenlight - Lightwight lightning baby! + Lightweight lightning baby! 1.0.0 true @@ -34,7 +34,7 @@ - + diff --git a/Plugins/BTCPayServer.Plugins.Breez/BreezController.cs b/Plugins/BTCPayServer.Plugins.Breez/BreezController.cs index 354ae05..425891e 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BreezController.cs +++ b/Plugins/BTCPayServer.Plugins.Breez/BreezController.cs @@ -1,12 +1,18 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Compression; using System.Linq; using System.Threading.Tasks; using Breez.Sdk; using BTCPayServer.Abstractions.Constants; using BTCPayServer.Client; +using BTCPayServer.Data; using BTCPayServer.Lightning; using BTCPayServer.Models; +using BTCPayServer.Payments; +using BTCPayServer.Payments.Lightning; +using BTCPayServer.Services.Stores; using BTCPayServer.Services.Wallets; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -17,21 +23,22 @@ using NBXplorer.DerivationStrategy; namespace BTCPayServer.Plugins.Breez; [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] -[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] [Route("plugins/{storeId}/Breez")] public class BreezController : Controller { private readonly BTCPayNetworkProvider _btcPayNetworkProvider; private readonly BreezService _breezService; private readonly BTCPayWalletProvider _btcWalletProvider; + private readonly StoreRepository _storeRepository; public BreezController(BTCPayNetworkProvider btcPayNetworkProvider, BreezService breezService, - BTCPayWalletProvider btcWalletProvider) + BTCPayWalletProvider btcWalletProvider, StoreRepository storeRepository) { _btcPayNetworkProvider = btcPayNetworkProvider; _breezService = breezService; _btcWalletProvider = btcWalletProvider; + _storeRepository = storeRepository; } @@ -43,6 +50,7 @@ public class BreezController : Controller } [HttpGet("swapin")] + [Authorize(Policy = Policies.CanCreateInvoice, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task SwapIn(string storeId) { var client = _breezService.GetClient(storeId); @@ -55,6 +63,7 @@ public class BreezController : Controller } [HttpGet("info")] + [Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Info(string storeId) { var client = _breezService.GetClient(storeId); @@ -67,6 +76,7 @@ public class BreezController : Controller } [HttpGet("sweep")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Sweep(string storeId) { var client = _breezService.GetClient(storeId); @@ -79,6 +89,7 @@ public class BreezController : Controller } [HttpPost("sweep")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Sweep(string storeId, string address, uint satPerByte) { var client = _breezService.GetClient(storeId); @@ -98,7 +109,7 @@ public class BreezController : Controller try { - var response = client.Sdk.Sweep(new SweepRequest(address, satPerByte)); + var response = client.Sdk.RedeemOnchainFunds(new RedeemOnchainFundsRequest(address, satPerByte)); TempData[WellKnownTempData.SuccessMessage] = $"sweep successful: {response.txid}"; } @@ -112,6 +123,7 @@ public class BreezController : Controller } [HttpGet("send")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Send(string storeId) { var client = _breezService.GetClient(storeId); @@ -122,6 +134,7 @@ public class BreezController : Controller return View((object) storeId); } + [Authorize(Policy = Policies.CanCreateInvoice, AuthenticationSchemes = AuthenticationSchemes.Cookie)] [Route("receive")] public async Task Receive(string storeId, ulong? amount) { @@ -130,11 +143,20 @@ public class BreezController : Controller { return RedirectToAction(nameof(Configure), new {storeId}); } - if (amount is not null) + + try { - var invoice = await client.CreateInvoice(LightMoney.FromUnit(amount.Value, LightMoneyUnit.Satoshi).MilliSatoshi, null, TimeSpan.Zero); - TempData["bolt11"] = invoice.BOLT11; - return RedirectToAction("Payments", "Breez", new {storeId }); + if (amount is not null) + { + var invoice = await client.CreateInvoice(LightMoney.FromUnit(amount.Value, LightMoneyUnit.Satoshi).MilliSatoshi, null, TimeSpan.Zero); + TempData["bolt11"] = invoice.BOLT11; + return RedirectToAction("Payments", "Breez", new {storeId }); + } + + } + catch (Exception e) + { + TempData[WellKnownTempData.ErrorMessage] = $"{e.Message}"; } @@ -142,6 +164,7 @@ public class BreezController : Controller } [HttpPost("send")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Send(string storeId, string address, ulong? amount) { var client = _breezService.GetClient(storeId); @@ -203,6 +226,7 @@ public class BreezController : Controller [HttpGet("swapout")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task SwapOut(string storeId) { var client = _breezService.GetClient(storeId); @@ -215,6 +239,7 @@ public class BreezController : Controller } [HttpPost("swapout")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task SwapOut(string storeId, string address, ulong amount, uint satPerByte, string feesHash) { @@ -247,6 +272,7 @@ public class BreezController : Controller } [HttpGet("swapin/{address}/refund")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task SwapInRefund(string storeId, string address) { var client = _breezService.GetClient(storeId); @@ -259,6 +285,7 @@ public class BreezController : Controller } [HttpPost("swapin/{address}/refund")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task SwapInRefund(string storeId, string address, string refundAddress, uint satPerByte) { var client = _breezService.GetClient(storeId); @@ -280,27 +307,100 @@ public class BreezController : Controller return RedirectToAction(nameof(SwapIn), new {storeId}); } + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] [HttpGet("configure")] public async Task Configure(string storeId) { return View(await _breezService.Get(storeId)); } + + private static async Task ReadAsByteArrayAsync( Stream source) + { + // Optimization + if (source is MemoryStream memorySource) + return memorySource.ToArray(); + + using var memoryStream = new MemoryStream(); + await source.CopyToAsync(memoryStream); + return memoryStream.ToArray(); + } [HttpPost("configure")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Configure(string storeId, string command, BreezSettings settings) { + var store = HttpContext.GetStoreData(); + var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider).OfType() + .FirstOrDefault(method => + method.PaymentId.PaymentType == LightningPaymentType.Instance && + method.PaymentId.CryptoCode == "BTC"); + if (command == "clear") { await _breezService.Set(storeId, null); TempData[WellKnownTempData.SuccessMessage] = "Settings cleared successfully"; + var client = _breezService.GetClient(storeId); + var isStoreSetToThisMicro = existing?.GetExternalLightningUrl() == client?.ToString(); + if (client is not null && isStoreSetToThisMicro) + { + store.SetSupportedPaymentMethod(existing.PaymentId, null); + await _storeRepository.UpdateStore(store); + } return RedirectToAction(nameof(Configure), new {storeId}); } if (command == "save") { + try { - await _breezService.Set(storeId, settings); + if (string.IsNullOrEmpty(settings.Mnemonic)) + { + ModelState.AddModelError(nameof(settings.Mnemonic), "Mnemonic is required"); + return View(settings); + } + else + { + try + { + new Mnemonic(settings.Mnemonic); + } + catch (Exception e) + { + ModelState.AddModelError(nameof(settings.Mnemonic), "Invalid mnemonic"); + return View(settings); + } + } + + if (settings.GreenlightCredentials is not null) + { + await using var stream = settings.GreenlightCredentials .OpenReadStream(); + using var archive = new ZipArchive(stream); + var deviceClientArchiveEntry = archive.GetEntry("client.crt"); + var deviceKeyArchiveEntry = archive.GetEntry("client-key.pem"); + if(deviceClientArchiveEntry is null || deviceKeyArchiveEntry is null) + { + ModelState.AddModelError(nameof(settings.GreenlightCredentials), "Invalid zip file (does not have client.crt or client-key.pem)"); + return View(settings); + } + else + { + var deviceClient = await ReadAsByteArrayAsync(deviceClientArchiveEntry.Open()); + var deviceKey = await ReadAsByteArrayAsync(deviceKeyArchiveEntry.Open()); + var dir = _breezService.GetWorkDir(storeId); + Directory.CreateDirectory(dir); + await System.IO.File.WriteAllBytesAsync(Path.Combine(dir, "client.crt"), deviceClient); + await System.IO.File.WriteAllBytesAsync(Path.Combine(dir, "client-key.pem"), deviceKey); + + await _breezService.Set(storeId, settings); + } + + } + else + { + + await _breezService.Set(storeId, settings); + } } catch (Exception e) { @@ -308,14 +408,27 @@ public class BreezController : Controller return View(settings); } + if(existing is null) + { + existing = new LightningSupportedPaymentMethod() + { + CryptoCode = "BTC" + }; + var client = _breezService.GetClient(storeId); + existing.SetLightningUrl(client); + store.SetSupportedPaymentMethod(existing); + await _storeRepository.UpdateStore(store); + } + TempData[WellKnownTempData.SuccessMessage] = "Settings saved successfully"; - return RedirectToAction(nameof(Configure), new {storeId}); + return RedirectToAction(nameof(Info), new {storeId}); } return NotFound(); } [Route("payments")] + [Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task Payments(string storeId, PaymentsViewModel viewModel) { var client = _breezService.GetClient(storeId); @@ -326,7 +439,7 @@ public class BreezController : Controller viewModel ??= new PaymentsViewModel(); - viewModel.Payments = client.Sdk.ListPayments(new ListPaymentsRequest(null, null, null, true, + viewModel.Payments = client.Sdk.ListPayments(new ListPaymentsRequest(null, null, null,null,true, (uint?) viewModel.Skip, (uint?) viewModel.Count)); return View(viewModel); diff --git a/Plugins/BTCPayServer.Plugins.Breez/BreezLightningClient.cs b/Plugins/BTCPayServer.Plugins.Breez/BreezLightningClient.cs index 5e6a3c9..84e10dc 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BreezLightningClient.cs +++ b/Plugins/BTCPayServer.Plugins.Breez/BreezLightningClient.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -22,12 +23,21 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener public readonly string PaymentKey; public BreezLightningClient(string inviteCode, string apiKey, string workingDir, NBitcoin.Network network, - string mnemonic, string paymentKey) + Mnemonic mnemonic, string paymentKey) { + apiKey??= "99010c6f84541bf582899db6728f6098ba98ca95ea569f4c63f2c2c9205ace57"; _network = network; PaymentKey = paymentKey; + GreenlightCredentials glCreds = null; + if (File.Exists(Path.Combine(workingDir, "client.crt")) && File.Exists(Path.Combine(workingDir, "client-key.pem"))) + { + var deviceCert = File.ReadAllBytes(Path.Combine(workingDir, "client.crt")); + var deviceKey = File.ReadAllBytes(Path.Combine(workingDir, "client-key.pem")); + + glCreds = new GreenlightCredentials(deviceKey.ToList(), deviceCert.ToList()); + } var nodeConfig = new NodeConfig.Greenlight( - new GreenlightNodeConfig(null, inviteCode) + new GreenlightNodeConfig(glCreds, inviteCode) ); var config = BreezSdkMethods.DefaultConfig( network == NBitcoin.Network.Main ? EnvironmentType.PRODUCTION : EnvironmentType.STAGING, @@ -40,8 +50,8 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener network == NBitcoin.Network.TestNet ? Network.TESTNET : network == NBitcoin.Network.RegTest ? Network.REGTEST : Network.SIGNET }; - var seed = BreezSdkMethods.MnemonicToSeed(mnemonic); - Sdk = BreezSdkMethods.Connect(config, seed, this); + var seed = mnemonic.DeriveSeed(); + Sdk = BreezSdkMethods.Connect(config, seed.ToList(), this); } public BlockingBreezServices Sdk { get; } @@ -137,7 +147,7 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener CancellationToken cancellation = default) { return Sdk.ListPayments(new ListPaymentsRequest(new List(){PaymentTypeFilter.RECEIVED}, null, null, - request?.PendingOnly is not true, (uint?) request?.OffsetIndex, null)) + null, request?.PendingOnly is not true, (uint?) request?.OffsetIndex, null)) .Select(FromPayment).ToArray(); } @@ -155,7 +165,7 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener CancellationToken cancellation = default) { return Sdk.ListPayments(new ListPaymentsRequest(new List(){PaymentTypeFilter.RECEIVED}, null, null, null, - (uint?) request?.OffsetIndex, null)) + null, (uint?) request?.OffsetIndex, null)) .Select(ToLightningPayment).ToArray(); } @@ -164,6 +174,7 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener CancellationToken cancellation = default) { var expiryS = expiry == TimeSpan.Zero ? (uint?) null : Math.Max(0, (uint) expiry.TotalSeconds); + description??= "Invoice"; var p = Sdk.ReceivePayment(new ReceivePaymentRequest((ulong) amount.MilliSatoshi, description, null, null, false, expiryS)); return FromPR(p); @@ -207,10 +218,6 @@ public class BreezLightningClient : ILightningClient, IDisposable, EventListener { PeersCount = ni.connectedPeers.Count, Alias = $"greenlight {ni.id}", - NodeInfoList = - { - new NodeInfo(new PubKey(ni.id), "blockstrean.com", 69) - }, //we have to fake this as btcpay currently requires this to enable the payment method BlockHeight = (int) ni.blockHeight }; } diff --git a/Plugins/BTCPayServer.Plugins.Breez/BreezLightningConnectionStringHandler.cs b/Plugins/BTCPayServer.Plugins.Breez/BreezLightningConnectionStringHandler.cs index 39709e0..222fc36 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BreezLightningConnectionStringHandler.cs +++ b/Plugins/BTCPayServer.Plugins.Breez/BreezLightningConnectionStringHandler.cs @@ -20,6 +20,7 @@ public class BreezLightningConnectionStringHandler : ILightningConnectionStringH return null; } + if (!kv.TryGetValue("key", out var key)) { error = $"The key 'key' is mandatory for breez connection strings"; diff --git a/Plugins/BTCPayServer.Plugins.Breez/BreezService.cs b/Plugins/BTCPayServer.Plugins.Breez/BreezService.cs index 89e16c5..2fbafdf 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BreezService.cs +++ b/Plugins/BTCPayServer.Plugins.Breez/BreezService.cs @@ -56,10 +56,10 @@ public class BreezService:EventHostedServiceBase await base.ProcessEvent(evt, cancellationToken); } - private string GetWorkDir() + public string GetWorkDir(string storeId) { var dir = _dataDirectories.Value.DataDir; - return Path.Combine(dir, "Plugins", "Breez"); + return Path.Combine(dir, "Plugins", "Breez",storeId); } TaskCompletionSource tcs = new(); @@ -103,9 +103,11 @@ public class BreezService:EventHostedServiceBase try { var network = Network.Main; // _btcPayNetworkProvider.BTC.NBitcoinNetwork; - Directory.CreateDirectory(GetWorkDir()); - var client = new BreezLightningClient(settings.InviteCode, settings.ApiKey, GetWorkDir(), - network, settings.Mnemonic, settings.PaymentKey); + var dir = GetWorkDir(storeId); + Directory.CreateDirectory(dir); + settings.PaymentKey ??= Guid.NewGuid().ToString(); + var client = new BreezLightningClient(settings.InviteCode, settings.ApiKey, dir, + network, new Mnemonic(settings.Mnemonic), settings.PaymentKey); if (storeId is not null) { _clients.AddOrReplace(storeId, client); @@ -140,6 +142,7 @@ public class BreezService:EventHostedServiceBase data.SetSupportedPaymentMethod(new PaymentMethodId("BTC", LightningPaymentType.Instance), null ); await _storeRepository.UpdateStore(data); } + Directory.Delete(GetWorkDir(storeId), true); } else if(result is not null ) diff --git a/Plugins/BTCPayServer.Plugins.Breez/BreezSettings.cs b/Plugins/BTCPayServer.Plugins.Breez/BreezSettings.cs index 807d9ab..c571d15 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/BreezSettings.cs +++ b/Plugins/BTCPayServer.Plugins.Breez/BreezSettings.cs @@ -1,13 +1,20 @@ #nullable enable using System; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json; namespace BTCPayServer.Plugins.Breez; public class BreezSettings { - public string InviteCode { get; set; } - public string Mnemonic { get; set; } - public string ApiKey { get; set; } + public string? InviteCode { get; set; } + public string? Mnemonic { get; set; } + public string? ApiKey { get; set; } public string PaymentKey { get; set; } = Guid.NewGuid().ToString(); + + + + [JsonIgnore] + public IFormFile GreenlightCredentials { get; set; } } \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Configure.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Configure.cshtml index 51a61b5..199202e 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Configure.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Configure.cshtml @@ -6,8 +6,10 @@ @{ ViewData.SetActivePage("Breez", "Configure", "Configure"); var storeId = Context.GetCurrentStoreId(); + var showAdvancedOptions = !string.IsNullOrEmpty(Model?.ApiKey) || !string.IsNullOrEmpty(Model?.InviteCode); + var active = (await BreezService.Get(storeId)) is not null; } -
+
@@ -16,7 +18,7 @@
- @if (await BreezService.Get(storeId) is not null) + @if (active) { } @@ -25,21 +27,55 @@
- + + A Bitcoin 12-word mnemonic seed phrase.BACK THIS UP SAFELY! GENERATE IT RANDOMLY! SERVER ADMINS HAVE ACCESS TO THIS!
-
- - - + @if (!active) + { +
+
+
+ + + + Get Greenlight credentials directly from Blockstream +
+
+
+
+ + + -
-
- - - + Alternatively, you can use an invite code. +
+
+
+ } + + +
+
+ + + + +
+ @if (active) + { +
+ + + + +
+ }
diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Info.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Info.cshtml index 676024e..4ae40db 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Info.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Info.cshtml @@ -1,6 +1,6 @@ -@using BTCPayServer.Abstractions.Extensions -@using BTCPayServer.Models.StoreViewModels +@using BTCPayServer.Models.StoreViewModels @using BTCPayServer.Security +@using Microsoft.AspNetCore.Mvc.TagHelpers @model object @{ var storeId = Model switch @@ -8,8 +8,7 @@ string s => s, StoreDashboardViewModel dashboardModel => dashboardModel.StoreId, _ => Context.GetImplicitStoreId() - }; - ViewData.SetActivePage("Breez", "Create Swapin Refund", "Info"); - + }; + ViewData.SetActivePage("Breez", "Breez node info", "Info"); } \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Payments.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Payments.cshtml index 3e3a5b8..4029a79 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Payments.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/Payments.cshtml @@ -1,6 +1,10 @@ @using BTCPayServer.Components @using BTCPayServer @using BTCPayServer.Abstractions.Extensions +@using BTCPayServer.Client +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using BTCPayServer.Components.QRCode +@using BTCPayServer.Components.TruncateCenter @model BTCPayServer.Plugins.Breez.PaymentsViewModel @{ var storeId = Context.GetCurrentStoreId(); @@ -17,8 +21,8 @@
diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/SwapIn.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/SwapIn.cshtml index 793ed68..daef8c5 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/SwapIn.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/SwapIn.cshtml @@ -2,6 +2,7 @@ @using BTCPayServer @using BTCPayServer.Abstractions.Extensions @using BTCPayServer.Abstractions.Contracts +@using BTCPayServer.Client @using BTCPayServer.Components.QRCode @using BTCPayServer.Components.TruncateCenter @using BTCPayServer.Models.StoreViewModels @@ -9,6 +10,7 @@ @using BTCPayServer.Plugins.Breez @using BTCPayServer.Security @using BTCPayServer.Services +@using Microsoft.AspNetCore.Mvc.TagHelpers @using NBitcoin @inject BreezService BreezService @inject BTCPayNetworkProvider BtcPayNetworkProvider @@ -20,7 +22,7 @@ string s => s, StoreDashboardViewModel dashboardModel => dashboardModel.StoreId, _ => Context.GetImplicitStoreId() - }; + }; var sdk = BreezService.GetClient(storeId)?.Sdk; if (sdk is null) return; @@ -34,13 +36,12 @@ catch (Exception e) { } + var refundables = sdk.ListRefundables(); var deriv = Context.GetStoreData().GetDerivationSchemeSettings(BtcPayNetworkProvider, "BTC"); var ni = sdk.NodeInfo(); var f = sdk.RecommendedFees(); var pmi = new PaymentMethodId("BTC", PaymentTypes.BTCLike); - - } @@ -70,34 +71,35 @@
- Please send an amount between
@Money.Satoshis(inProgressSwap.minAllowedDeposit).ToDecimal(MoneyUnit.BTC) and @Money.Satoshis(inProgressSwap.maxAllowedDeposit).ToDecimal(MoneyUnit.BTC)BTC
- @if (deriv is not null) - { - var wallet = new WalletId(storeId, "BTC"); - Send using BTCPay Wallet - } - @{ - var onChainSats = ni.onchainBalanceMsat / 1000; - if (inProgressSwap.minAllowedDeposit <= (long) onChainSats) +
+ Please send an amount between
@Money.Satoshis(inProgressSwap.minAllowedDeposit).ToDecimal(MoneyUnit.BTC) and @Money.Satoshis(inProgressSwap.maxAllowedDeposit).ToDecimal(MoneyUnit.BTC)BTC
+ @if (deriv is not null) { -
- - - - -
+ var wallet = new WalletId(storeId, "BTC"); + Send using BTCPay Wallet } - - } + @{ + var onChainSats = ni.onchainBalanceMsat / 1000; + if (inProgressSwap.minAllowedDeposit <= (long) onChainSats) + { +
+
+ + +
+
+ } + } +
- @if (inProgressSwap.unconfirmedSats + inProgressSwap.confirmedSats + inProgressSwap.paidSats > 0) + @if (inProgressSwap.unconfirmedSats + inProgressSwap.confirmedSats + (inProgressSwap.paidMsat * 1000) > 0) {
@inProgressSwap.unconfirmedSats sats unconfirmed @inProgressSwap.confirmedSats sats confirmed - @inProgressSwap.paidSats sats paid + @(inProgressSwap.paidMsat * 1000) sats paid
} @if (inProgressSwap.unconfirmedTxIds.Any()) @@ -144,12 +146,12 @@ @DateTimeOffset.FromUnixTimeSeconds(refund.createdAt) @refund.bitcoinAddress - @if (refund.unconfirmedSats + refund.confirmedSats + refund.paidSats > 0) + @if (refund.unconfirmedSats + refund.confirmedSats + refund.paidMsat > 0) {
@refund.unconfirmedSats sats unconfirmed @refund.confirmedSats sats confirmed - @refund.paidSats sats paid + @(refund.paidMsat * 1000) sats paid
} @if (refund.unconfirmedTxIds.Any()) diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/_Nav.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/_Nav.cshtml index 3e7b8e3..6a74925 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/_Nav.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Breez/_Nav.cshtml @@ -1,7 +1,9 @@ @using BTCPayServer.Abstractions.Extensions +@using BTCPayServer.Client @using BTCPayServer.Models.StoreViewModels @using BTCPayServer.Plugins.Breez @using BTCPayServer.Security +@using Microsoft.AspNetCore.Mvc.TagHelpers @inject BreezService BreezService @{ @@ -22,12 +24,12 @@
\ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.Breez/Views/Shared/Breez/BreezNav.cshtml b/Plugins/BTCPayServer.Plugins.Breez/Views/Shared/Breez/BreezNav.cshtml index eb3c78c..0fcab48 100644 --- a/Plugins/BTCPayServer.Plugins.Breez/Views/Shared/Breez/BreezNav.cshtml +++ b/Plugins/BTCPayServer.Plugins.Breez/Views/Shared/Breez/BreezNav.cshtml @@ -9,7 +9,7 @@ @if (!string.IsNullOrEmpty(storeId)) {