This commit is contained in:
2025-12-11 14:05:06 +01:00
parent 301ee5c839
commit fb99468852
14 changed files with 61 additions and 82 deletions

View File

@@ -5,7 +5,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<NoWarn>$(NoWarn);CS1591;CS0618</NoWarn>
</PropertyGroup>
<!-- Plugin specific properties -->

View File

@@ -435,8 +435,6 @@ public class BreezSparkController : Controller
var pmi = new PaymentMethodId("BTC-LN");
// In v2.2.1, payment methods are handled differently
// TODO: Implement proper v2.2.1 payment method handling
object? existing = null;
if (command == "clear")
{
await _breezService.Set(storeId, null);
@@ -461,7 +459,7 @@ public class BreezSparkController : Controller
{
new Mnemonic(settings.Mnemonic);
}
catch (Exception e)
catch (Exception)
{
ModelState.AddModelError(nameof(settings.Mnemonic), "Invalid mnemonic");
return View(settings);
@@ -503,8 +501,8 @@ public class BreezSparkController : Controller
assetFilter: new AssetFilter.Bitcoin(),
fromTimestamp: null,
toTimestamp: null,
offset: viewModel.Skip != null ? (uint?)viewModel.Skip : null,
limit: viewModel.Count != null ? (uint?)viewModel.Count : null,
offset: viewModel.Skip > 0 ? (uint?)viewModel.Skip : null,
limit: viewModel.Count > 0 ? (uint?)viewModel.Count : null,
sortAscending: false
);
var response = await client.Sdk.ListPayments(req);

View File

@@ -13,6 +13,11 @@ using Network = Breez.Sdk.Spark.Network;
namespace BTCPayServer.Plugins.BreezSpark;
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type
#pragma warning disable CS8602 // Dereference of a possibly null reference.
#pragma warning disable CS8603 // Possible null reference return.
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
public class EventLogEntry
{
public DateTimeOffset timestamp { get; set; }
@@ -950,3 +955,8 @@ public class NormalizedPayment
public LightMoney Fee { get; set; } = LightMoney.Zero;
public string? Description { get; set; }
}
#pragma warning restore CS8600
#pragma warning restore CS8602
#pragma warning restore CS8603
#pragma warning restore CS8625

View File

@@ -146,12 +146,12 @@ namespace BTCPayServer.Plugins.BreezSpark
public object ParsePaymentPromptDetails(JToken details)
{
return details.ToObject<LigthningPaymentPromptDetails>(Serializer);
return details.ToObject<LigthningPaymentPromptDetails>(Serializer) ?? new LigthningPaymentPromptDetails();
}
public LightningPaymentData ParsePaymentDetails(JToken details)
{
return details.ToObject<LightningPaymentData>(Serializer);
return details.ToObject<LightningPaymentData>(Serializer) ?? new LightningPaymentData();
}
object IPaymentMethodHandler.ParsePaymentDetails(JToken details)

View File

@@ -2,6 +2,7 @@
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Abstractions.Services;
using BTCPayServer;
using BTCPayServer.Configuration;
using BTCPayServer.Lightning;
using BTCPayServer.Payments;
@@ -44,10 +45,8 @@ namespace BTCPayServer.Plugins.BreezSpark
});
// Add UI extensions for lightning setup tab (like Boltz does)
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("BreezSpark/LNPaymentMethodSetupTab",
"ln-payment-method-setup-tab"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("BreezSpark/LNPaymentMethodSetupTabhead",
"ln-payment-method-setup-tabhead"));
applicationBuilder.AddUIExtension("ln-payment-method-setup-tab", "BreezSpark/LNPaymentMethodSetupTab");
applicationBuilder.AddUIExtension("ln-payment-method-setup-tabhead", "BreezSpark/LNPaymentMethodSetupTabhead");
// Surface BreezSpark navigation inside the store integrations nav, matching the plugin template pattern.
applicationBuilder.AddUIExtension("store-integrations-nav", "BreezSpark/BreezSparkNav");

View File

@@ -54,6 +54,7 @@ public class BreezSparkService:EventHostedServiceBase
public string GetWorkDir(string storeId)
{
ArgumentNullException.ThrowIfNull(storeId);
var dir = _dataDirectories.Value.DataDir;
return Path.Combine(dir, "Plugins", "BreezSpark",storeId);
}
@@ -87,6 +88,10 @@ public class BreezSparkService:EventHostedServiceBase
public async Task<BreezSparkLightningClient?> Handle(string? storeId, BreezSparkSettings? settings)
{
if (string.IsNullOrEmpty(storeId))
{
return null;
}
if (settings is null)
{
if (storeId is not null && _clients.Remove(storeId, out var client))
@@ -104,7 +109,7 @@ public class BreezSparkService:EventHostedServiceBase
settings.PaymentKey ??= Guid.NewGuid().ToString();
var client = await BreezSparkLightningClient.Create(
settings.ApiKey,
settings.ApiKey ?? string.Empty,
dir,
network,
new Mnemonic(settings.Mnemonic),
@@ -178,4 +183,4 @@ public class BreezSparkService:EventHostedServiceBase
var match = _settings.FirstOrDefault(pair => pair.Value.PaymentKey == paymentKey).Key;
return GetClient(match);
}
}
}

View File

@@ -92,9 +92,9 @@ else
@functions {
public class PaymentDetailsViewModel
{
public string Destination { get; set; }
public string Destination { get; set; } = string.Empty;
public long Amount { get; set; }
public long Fee { get; set; }
public string PrepareResponseJson { get; set; }
public string PrepareResponseJson { get; set; } = string.Empty;
}
}
}

View File

@@ -32,11 +32,6 @@
SwapInfo? currentSwap = null;
try
{
// Simplified logic - skip complex payment lookup for now
Payment? pendingReceive = null;
// Skip pending receive logic for SDK v0.4.1 compatibility
// If no pending swap, create a new one
if (currentSwap == null)
{
@@ -101,7 +96,6 @@
// Get explorer URL for transaction links
var network = BTCPayNetworkProvider.GetNetwork<BTCPayNetwork>("BTC");
var explorerUrl = network.BlockExplorerLink?.ToString() ?? "#";
}
@if (hasFeeRates)
@@ -209,4 +203,4 @@
}
*@
</div>
</div>
</div>

View File

@@ -9,8 +9,8 @@
@inject PaymentMethodHandlerDictionary PaymentMethodHandlerDictionary
@* @inject BTCPayNetworkProvider BTCPayNetworkProvider *@
@{
var storeId = Context.GetImplicitStoreId();
var address = Context.GetRouteValue("address").ToString();
var storeId = Context.GetImplicitStoreId() ?? string.Empty;
var address = Context.GetRouteValue("address") as string ?? string.Empty;
ViewData.SetActivePage("BreezSpark", "Create Swapin Refund", "SwapIn");
@* TODO: Fix for v2.2.1 - derivation settings check needed *@
@@ -70,4 +70,4 @@
<button type="submit" class="btn btn-primary">Process Refund</button>
</div>
</div>
</form>
</form>

View File

@@ -11,19 +11,12 @@
@{
Layout = "_Layout";
ViewData.SetActivePage("BreezSpark", "Swap Out", "SwapOut");
string storeId = null;
if (Model is string s)
var storeId = Model switch
{
storeId = s;
}
else if (Model is StoreDashboardViewModel dashboardModel)
{
storeId = dashboardModel.StoreId;
}
else
{
storeId = Context.GetImplicitStoreId();
}
string s => s,
StoreDashboardViewModel dashboardModel => dashboardModel.StoreId,
_ => Context.GetImplicitStoreId() ?? string.Empty
};
// Simplified fee structure for SDK v0.4.1 compatibility
var fastFee = 10;
@@ -80,4 +73,4 @@
<button type="submit" class="btn btn-primary">Initiate Swap-Out</button>
</div>
</div>
</form>
</form>

View File

@@ -10,19 +10,12 @@
@{
Layout = "_Layout";
ViewData.SetActivePage("BreezSpark", "Sweep", "Sweep");
string storeId = null;
if (Model is string s)
var storeId = Model switch
{
storeId = s;
}
else if (Model is StoreDashboardViewModel dashboardModel)
{
storeId = dashboardModel.StoreId;
}
else
{
storeId = Context.GetImplicitStoreId();
}
string s => s,
StoreDashboardViewModel dashboardModel => dashboardModel.StoreId,
_ => Context.GetImplicitStoreId() ?? string.Empty
};
var sdk = BreezService.GetClient(storeId)?.Sdk;
if (sdk is null)
return;
@@ -76,4 +69,4 @@
<button type="submit" class="btn btn-primary">Sweep Funds</button>
</div>
</div>
</form>
</form>

View File

@@ -5,19 +5,12 @@
@using BTCPayServer.Client
@inject BreezSparkService BreezService
@{
string storeId = null;
if (Model is string s)
var storeId = Model switch
{
storeId = s;
}
else if (Model is StoreDashboardViewModel dashboardModel)
{
storeId = dashboardModel.StoreId;
}
else
{
storeId = Context.GetImplicitStoreId();
}
string s => s,
StoreDashboardViewModel dashboardModel => dashboardModel.StoreId,
_ => Context.GetImplicitStoreId() ?? string.Empty
};
// In SDK v0.4.1, NodeState API has changed and async calls can't be made from partial views
// This widget needs to be refactored to receive data from controller
@@ -81,10 +74,10 @@
{
<div class="text-center p-3">
<p class="text-muted">BreezSpark node information not available</p>
@if (string.IsNullOrEmpty(storeId))
@if (!string.IsNullOrEmpty(storeId))
{
<a asp-action="Configure" asp-controller="BreezSpark" asp-route-storeId="@storeId">Configure BreezSpark</a>
}
</div>
}
</div>
</div>

View File

@@ -13,9 +13,9 @@
{
string s => s,
StoreDashboardViewModel dashboardModel => dashboardModel.StoreId,
_ => Context.GetImplicitStoreId()
_ => Context.GetImplicitStoreId() ?? string.Empty
};
var active = @ViewData.IsActivePage("BreezSpark");
var active = ViewData.ActivePageClass("BreezSpark");
var client = string.IsNullOrEmpty(active) ? null : BreezService.GetClient(storeId);
var sdk = client?.Sdk;
}
@@ -42,19 +42,19 @@
{
<li class="nav-item nav-item-sub">
<a permission="@Policies.CanViewStoreSettings" asp-action="Info" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("BreezSpark", null, "Info")">Info</a>
<a permission="@Policies.CanViewStoreSettings" asp-action="Info" asp-route-storeId="@storeId" class="nav-link @ViewData.ActivePageClass("BreezSpark", null, "Info")">Info</a>
</li>
<li class="nav-item nav-item-sub">
<a permission="@Policies.CanViewStoreSettings" asp-action="Payments" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("BreezSpark", null, "Payments")">Payments</a>
<a permission="@Policies.CanViewStoreSettings" asp-action="Payments" asp-route-storeId="@storeId" class="nav-link @ViewData.ActivePageClass("BreezSpark", null, "Payments")">Payments</a>
</li>
<li class="nav-item nav-item-sub">
<a permission="@Policies.CanModifyStoreSettings" asp-action="Configure" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("BreezSpark", null, "Configure")">Configuration</a>
<a permission="@Policies.CanModifyStoreSettings" asp-action="Configure" asp-route-storeId="@storeId" class="nav-link @ViewData.ActivePageClass("BreezSpark", null, "Configure")">Configuration</a>
</li>
@if (client.Events.Any())
@if (client?.Events?.Any() == true)
{
<li class="nav-item nav-item-sub">
<a permission="@Policies.CanViewStoreSettings" asp-action="Logs" asp-route-storeId="@storeId" class="nav-link @ViewData.IsActivePage("BreezSpark", null, "Logs")">Logs</a>
<a permission="@Policies.CanViewStoreSettings" asp-action="Logs" asp-route-storeId="@storeId" class="nav-link @ViewData.ActivePageClass("BreezSpark", null, "Logs")">Logs</a>
</li>
}
}
}
}

View File

@@ -6,13 +6,7 @@
@model List<NormalizedPayment>
@{
var data = Model ?? new List<NormalizedPayment>();
var storeId = Context.GetImplicitStoreId();
if (data is null)
{
if (string.IsNullOrEmpty(storeId))
return;
}
var storeId = Context.GetImplicitStoreId() ?? string.Empty;
var isDashboard = false;
}
@if (isDashboard)