mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-17 07:34:24 +01:00
update breez
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<!-- Plugin specific properties -->
|
||||
<PropertyGroup>
|
||||
<Product>Breez / Greenlight</Product>
|
||||
<Description>Lightwight lightning baby!</Description>
|
||||
<Description>Lightweight lightning baby!</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
@@ -34,7 +34,7 @@
|
||||
<ProjectReference Include="..\..\submodules\btcpayserver\BTCPayServer\BTCPayServer.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Breez.Sdk" Version="0.2.10" />
|
||||
<PackageReference Include="Breez.Sdk" Version="0.3.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
|
||||
@@ -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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> Receive(string storeId, ulong? amount)
|
||||
{
|
||||
@@ -130,6 +143,9 @@ public class BreezController : Controller
|
||||
{
|
||||
return RedirectToAction(nameof(Configure), new {storeId});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (amount is not null)
|
||||
{
|
||||
var invoice = await client.CreateInvoice(LightMoney.FromUnit(amount.Value, LightMoneyUnit.Satoshi).MilliSatoshi, null, TimeSpan.Zero);
|
||||
@@ -137,11 +153,18 @@ public class BreezController : Controller
|
||||
return RedirectToAction("Payments", "Breez", new {storeId });
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"{e.Message}";
|
||||
}
|
||||
|
||||
|
||||
return View((object) storeId);
|
||||
}
|
||||
|
||||
[HttpPost("send")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> SwapInRefund(string storeId, string address, string refundAddress, uint satPerByte)
|
||||
{
|
||||
var client = _breezService.GetClient(storeId);
|
||||
@@ -280,42 +307,128 @@ public class BreezController : Controller
|
||||
return RedirectToAction(nameof(SwapIn), new {storeId});
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
[HttpGet("configure")]
|
||||
public async Task<IActionResult> Configure(string storeId)
|
||||
{
|
||||
return View(await _breezService.Get(storeId));
|
||||
}
|
||||
|
||||
private static async Task<byte[]> 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<IActionResult> Configure(string storeId, string command, BreezSettings settings)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider).OfType<LightningSupportedPaymentMethod>()
|
||||
.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
|
||||
{
|
||||
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)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"Couldnt use provided settings: {e.Message}";
|
||||
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<IActionResult> 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);
|
||||
|
||||
@@ -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>(){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>(){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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
<form method="post" asp-action="Configure" asp-controller="Breez" asp-route-storeId="@storeId">
|
||||
<form method="post" asp-action="Configure" asp-controller="Breez" asp-route-storeId="@storeId" enctype="multipart/form-data">
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
@@ -16,7 +18,7 @@
|
||||
</h3>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0">
|
||||
<button name="command" type="submit" value="save" class="btn btn-primary">Save</button>
|
||||
@if (await BreezService.Get(storeId) is not null)
|
||||
@if (active)
|
||||
{
|
||||
<button name="command" type="submit" value="clear" class="btn btn-danger">Clear</button>
|
||||
}
|
||||
@@ -25,22 +27,56 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="Mnemonic" class="form-label">Mnemonic</label>
|
||||
<input asp-for="Mnemonic" class="form-control"/>
|
||||
<input value="@Model?.Mnemonic" asp-for="Mnemonic" class="form-control" type="password" disabled="@active"/>
|
||||
<span asp-validation-for="Mnemonic" class="text-danger"></span>
|
||||
<span class="text-muted">A Bitcoin 12-word mnemonic seed phrase.<strong>BACK THIS UP SAFELY! GENERATE IT RANDOMLY! SERVER ADMINS HAVE ACCESS TO THIS!</strong></span>
|
||||
|
||||
</div>
|
||||
@if (!active)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey" class="form-label">ApiKey</label>
|
||||
<label asp-for="GreenlightCredentials" class="form-label">Greenlight credentials</label>
|
||||
<input asp-for="GreenlightCredentials" type="file" class="form-control">
|
||||
<span asp-validation-for="GreenlightCredentials" class="text-danger w-100 d-block"></span>
|
||||
<a href="https://greenlight.blockstream.com/" target="_blank">Get Greenlight credentials directly from Blockstream</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="InviteCode" class="form-label">Invite Code</label>
|
||||
<input asp-for="InviteCode" class="form-control"/>
|
||||
<span asp-validation-for="InviteCode" class="text-danger"></span>
|
||||
|
||||
<span class="text-muted">Alternatively, you can use an invite code.</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<button class="d-inline-flex align-items-center btn btn-link text-primary fw-semibold p-0 mb-3" type="button" id="AdvancedSettingsButton" data-bs-toggle="collapse" data-bs-target="#AdvancedSettings" aria-expanded="false" aria-controls="AdvancedSettings">
|
||||
<vc:icon symbol="caret-down"/>
|
||||
<span class="ms-1">Advanced settings</span>
|
||||
</button>
|
||||
<div id="AdvancedSettings" class="collapse @(showAdvancedOptions ? "show" : "")">
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey" class="form-label">Breez API Key</label>
|
||||
<input asp-for="ApiKey" class="form-control"/>
|
||||
<span asp-validation-for="ApiKey" class="text-danger"></span>
|
||||
|
||||
</div>
|
||||
@if (active)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="InviteCode" class="form-label">InviteCode</label>
|
||||
<label asp-for="InviteCode" class="form-label">Invite Code</label>
|
||||
<input asp-for="InviteCode" class="form-control"/>
|
||||
<span asp-validation-for="InviteCode" class="text-danger"></span>
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<input type="hidden" asp-for="PaymentKey"/>
|
||||
</div>
|
||||
|
||||
@@ -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
|
||||
@@ -9,7 +9,6 @@
|
||||
StoreDashboardViewModel dashboardModel => dashboardModel.StoreId,
|
||||
_ => Context.GetImplicitStoreId()
|
||||
};
|
||||
ViewData.SetActivePage("Breez", "Create Swapin Refund", "Info");
|
||||
|
||||
ViewData.SetActivePage("Breez", "Breez node info", "Info");
|
||||
}
|
||||
<partial name="Breez/BreezNodeInfo" model="@storeId"/>
|
||||
@@ -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 @@
|
||||
</h3>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0">
|
||||
|
||||
<a asp-action="Send" asp-controller="Breez" asp-route-storeId="@storeId" type="submit" class="btn btn-primary">Send</a>
|
||||
<a asp-action="Receive" asp-controller="Breez" asp-route-storeId="@storeId" type="submit" class="btn btn-primary">Receive</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" asp-action="Send" asp-controller="Breez" asp-route-storeId="@storeId" type="submit" class="btn btn-primary">Send</a>
|
||||
<a permission="@Policies.CanCreateInvoice" asp-action="Receive" asp-controller="Breez" asp-route-storeId="@storeId" type="submit" class="btn btn-primary">Receive</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
<datalist id="fees">
|
||||
@@ -70,11 +71,12 @@
|
||||
<vc:truncate-center text="@inProgressSwap.bitcoinAddress" padding="15" elastic="true" classes="form-control-plaintext" id="Address"/>
|
||||
<label for="Address">Address</label>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-muted">Please send an amount between <br/> @Money.Satoshis(inProgressSwap.minAllowedDeposit).ToDecimal(MoneyUnit.BTC) and @Money.Satoshis(inProgressSwap.maxAllowedDeposit).ToDecimal(MoneyUnit.BTC)BTC </span>
|
||||
@if (deriv is not null)
|
||||
{
|
||||
var wallet = new WalletId(storeId, "BTC");
|
||||
<a class="btn btn-link w-100" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@wallet" asp-route-defaultDestination="@inProgressSwap.bitcoinAddress">Send using BTCPay Wallet</a>
|
||||
<a class="btn btn-link w-100" permission="@Policies.CanModifyStoreSettings" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@wallet" asp-route-defaultDestination="@inProgressSwap.bitcoinAddress">Send using BTCPay Wallet</a>
|
||||
}
|
||||
@{
|
||||
var onChainSats = ni.onchainBalanceMsat / 1000;
|
||||
@@ -87,17 +89,17 @@
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@if (inProgressSwap.unconfirmedSats + inProgressSwap.confirmedSats + inProgressSwap.paidSats > 0)
|
||||
@if (inProgressSwap.unconfirmedSats + inProgressSwap.confirmedSats + (inProgressSwap.paidMsat * 1000) > 0)
|
||||
{
|
||||
<div class="card truncate-center-id">
|
||||
<span class="text-nowrap">@inProgressSwap.unconfirmedSats sats unconfirmed</span>
|
||||
<span class="text-nowrap">@inProgressSwap.confirmedSats sats confirmed</span>
|
||||
<span class="text-nowrap">@inProgressSwap.paidSats sats paid</span>
|
||||
<span class="text-nowrap">@(inProgressSwap.paidMsat * 1000) sats paid</span>
|
||||
</div>
|
||||
}
|
||||
@if (inProgressSwap.unconfirmedTxIds.Any())
|
||||
@@ -144,12 +146,12 @@
|
||||
<td>@DateTimeOffset.FromUnixTimeSeconds(refund.createdAt)</td>
|
||||
<td>@refund.bitcoinAddress</td>
|
||||
<td>
|
||||
@if (refund.unconfirmedSats + refund.confirmedSats + refund.paidSats > 0)
|
||||
@if (refund.unconfirmedSats + refund.confirmedSats + refund.paidMsat > 0)
|
||||
{
|
||||
<div class="card truncate-center-id">
|
||||
<span class="text-nowrap">@refund.unconfirmedSats sats unconfirmed</span>
|
||||
<span class="text-nowrap">@refund.confirmedSats sats confirmed</span>
|
||||
<span class="text-nowrap">@refund.paidSats sats paid</span>
|
||||
<span class="text-nowrap">@(refund.paidMsat * 1000) sats paid</span>
|
||||
</div>
|
||||
}
|
||||
@if (refund.unconfirmedTxIds.Any())
|
||||
|
||||
@@ -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 @@
|
||||
<div class="nav">
|
||||
@if (sdk is not null)
|
||||
{
|
||||
<a asp-action="Info" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Info")">Info</a>
|
||||
<a asp-action="Payments" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Payments")">Payments</a>
|
||||
<a asp-action="SwapIn" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "SwapIn")">Swap In</a>
|
||||
<a asp-action="SwapOut" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "SwapOut")">Swap Out</a>
|
||||
<a permission="@Policies.CanViewStoreSettings" asp-action="Info" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Info")">Info</a>
|
||||
<a permission="@Policies.CanViewStoreSettings" asp-action="Payments" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Payments")">Payments</a>
|
||||
<a permission="@Policies.CanCreateInvoice" asp-action="SwapIn" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "SwapIn")">Swap In</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" asp-action="SwapOut" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "SwapOut")">Swap Out</a>
|
||||
}
|
||||
<a asp-action="Configure" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Configure")">Configuration</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" asp-action="Configure" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez", null, "Configure")">Configuration</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -9,7 +9,7 @@
|
||||
@if (!string.IsNullOrEmpty(storeId))
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a permission="@Policies.CanModifyStoreSettings" asp-controller="Breez" asp-action="Index" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez")" id="Nav-Breez">
|
||||
<a permission="@Policies.CanViewStoreSettings" asp-controller="Breez" asp-action="Index" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("Breez")" id="Nav-Breez">
|
||||
|
||||
<svg style="width: 15px; margin-left: 3px; margin-right: 7px;" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="favicon-64-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@using BTCPayServer.Models.StoreViewModels
|
||||
@using BTCPayServer.Plugins.Breez
|
||||
@using BTCPayServer.Security
|
||||
@using BTCPayServer.Client
|
||||
@inject BreezService BreezService
|
||||
@{
|
||||
string storeId = null;
|
||||
@@ -42,7 +43,7 @@
|
||||
{
|
||||
<div class="d-flex w-100 align-items-center justify-content-start gap-3">
|
||||
<span class="btcpay-status btcpay-status--enabled"></span>
|
||||
<h6 class="text-truncate">@lspInfo.name connected</h6>
|
||||
<h6 class="text-truncate">@lspInfo.name LSP connected</h6>
|
||||
</div>
|
||||
}
|
||||
<div class="store-number">
|
||||
@@ -50,7 +51,7 @@
|
||||
<h6>On-Chain Balance</h6>
|
||||
@if (Model is StoreDashboardViewModel && nodeState.onchainBalanceMsat > 0)
|
||||
{
|
||||
<div>
|
||||
<div permission="@Policies.CanModifyStoreSettings">
|
||||
<a asp-action="Sweep" asp-controller="Breez" asp-route-storeId="@storeId">Sweep</a>
|
||||
</div>
|
||||
}
|
||||
@@ -66,7 +67,7 @@
|
||||
<h6>Lightning Balance</h6>
|
||||
@if (Model is StoreDashboardViewModel)
|
||||
{
|
||||
<div>
|
||||
<div permission="@Policies.CanModifyStoreSettings">
|
||||
<a asp-action="SwapIn" asp-controller="Breez" asp-route-storeId="@storeId">Swap in</a>
|
||||
@if (nodeState.channelsBalanceMsat > 0)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
if (sdk is null)
|
||||
return;
|
||||
|
||||
data = sdk.ListPayments(new ListPaymentsRequest(null, null, null, null, 0, 10));
|
||||
data = sdk.ListPayments(new ListPaymentsRequest(null, null, null, null, true, 0, 10));
|
||||
}
|
||||
|
||||
var isDashboard = Model is StoreDashboardViewModel;
|
||||
@@ -47,7 +47,7 @@
|
||||
<th class="w-125px">Id</th>
|
||||
<th class="w-125px">Timestamp</th>
|
||||
<th class="w-125px">Type</th>
|
||||
<th class="w-125px">Amount</th>
|
||||
<th class="w-125px">Amount</th>a
|
||||
<th class="text-nowrap">Fee</th>
|
||||
<th class="text-nowrap">Status</th>
|
||||
<th class="text-nowrap">Description</th>
|
||||
@@ -57,25 +57,25 @@
|
||||
@foreach (var payment in data)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<td class="smMaxWidth text-truncate">
|
||||
|
||||
<span class="text-break">@payment.id</span>
|
||||
<span >@payment.id</span>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">@DateTimeOffset.FromUnixTimeSeconds(payment.paymentTime).ToTimeAgo()</span>
|
||||
<span >@DateTimeOffset.FromUnixTimeSeconds(payment.paymentTime).ToTimeAgo()</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">>@payment.paymentType.ToString().ToLowerInvariant().Replace("_", " ")</span>
|
||||
<span >@payment.paymentType.ToString().ToLowerInvariant().Replace("_", " ")</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">>@LightMoney.MilliSatoshis(payment.amountMsat).ToDecimal(LightMoneyUnit.BTC) BTC</span>
|
||||
<span >@LightMoney.MilliSatoshis(payment.amountMsat).ToDecimal(LightMoneyUnit.BTC) BTC</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">>@LightMoney.MilliSatoshis(payment.feeMsat).ToDecimal(LightMoneyUnit.BTC) BTC</span>
|
||||
<span >@LightMoney.MilliSatoshis(payment.feeMsat).ToDecimal(LightMoneyUnit.BTC) BTC</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">@payment.status.ToString().ToLowerInvariant()</span>
|
||||
<span >@payment.status.ToString().ToLowerInvariant()</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-break">@payment.description</span>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@inject BreezService BreezService;
|
||||
@using BTCPayServer.Plugins.Breez
|
||||
@using BTCPayServer.Client
|
||||
@model BTCPayServer.Models.StoreViewModels.LightningNodeViewModel
|
||||
|
||||
@if (Model.CryptoCode != "BTC")
|
||||
@@ -9,5 +10,15 @@
|
||||
@{
|
||||
var client = BreezService.GetClient(Model.StoreId);
|
||||
}
|
||||
<input value="Custom" type="radio" id="LightningNodeType-Breez" data-bs-toggle="pill" data-bs-target="#BreezSetup" role="tab" aria-controls="BreezSetup" aria-selected="false" name="LightningNodeType" disabled="@(client is null)">
|
||||
<label for="LightningNodeType-Breez">Use Breez wallet</label>
|
||||
|
||||
@if (client is null)
|
||||
{
|
||||
<a asp-action="Configure" asp-controller="Breez" permission="@Policies.CanModifyStoreSettings" asp-route-storeId="@Model.StoreId" value="Custom" type="radio" id="LightningNodeType-Breez" role="tab" aria-controls="BreezSetup" aria-selected="false" name="LightningNodeType">
|
||||
<label for="LightningNodeType-Breez">Configure Breez</label>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input value="Custom" type="radio" id="LightningNodeType-Breez" data-bs-toggle="pill" data-bs-target="#BreezSetup" role="tab" aria-controls="BreezSetup" aria-selected="false" name="LightningNodeType" disabled="@(client is null)">
|
||||
<label for="LightningNodeType-Breez">Use Breez wallet</label>
|
||||
}
|
||||
Reference in New Issue
Block a user