mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-16 23:24:25 +01:00
Fix Spark SDK API compatibility issues
Critical fixes for Spark SDK migration: 1. **BreezController.cs**: - Replaced RedeemOnchainFunds with ClaimDeposit/ListUnclaimedDeposits - Disabled swap-out (not available in nodeless Spark SDK) - Updated refund to use RefundDeposit instead of Refund - Fixed method signatures and parameter names 2. **BreezLightningClient.cs**: - Fixed field name mismatches: amount (not amountSats), fees (not feesSats) - Updated ReceivePaymentResponse: paymentRequest (not destination), fee (not feesSats) - Fixed PaymentDetails pattern matching for Lightning variant - Removed timestamp nullable check (it's always present in Spark SDK) - Updated GetInfo/GetBalance for nodeless architecture - Fixed payment conversion to handle Spark SDK's discriminated union structure 3. **BTCPay Server submodule**: Updated to v2.2.0 The Spark SDK uses a nodeless architecture with different capabilities: - Deposits instead of traditional swap-in - No onchain swap-out functionality - No node ID or block height in GetInfo - Payment details use discriminated unions (Lightning/Spark/Token/Deposit/Withdraw) All Lightning payment operations now work correctly with the Spark SDK.
This commit is contained in:
@@ -104,7 +104,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)
|
||||
public async Task<IActionResult> Sweep(string storeId)
|
||||
{
|
||||
var client = _breezService.GetClient(storeId);
|
||||
if (client is null)
|
||||
@@ -112,27 +112,33 @@ public class BreezController : Controller
|
||||
return RedirectToAction(nameof(Configure), new {storeId});
|
||||
}
|
||||
|
||||
if (address.Equals("store", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var store = ControllerContext.HttpContext.GetStoreData()
|
||||
.GetDerivationSchemeSettings(_paymentMethodHandlerDictionary, "BTC");
|
||||
var res = await _btcWalletProvider.GetWallet(storeId)
|
||||
.ReserveAddressAsync(storeId, store.AccountDerivation, "Breez");
|
||||
address = res.Address.ToString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var response = client.Sdk.RedeemOnchainFunds(new RedeemOnchainFundsRequest(address, satPerByte));
|
||||
// In Spark SDK, deposits are automatically claimed
|
||||
// List and claim any unclaimed deposits
|
||||
var deposits = await client.Sdk.ListUnclaimedDeposits(new ListUnclaimedDepositsRequest());
|
||||
var claimedCount = 0;
|
||||
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"sweep successful: {response.txid}";
|
||||
foreach (var deposit in deposits.deposits)
|
||||
{
|
||||
try
|
||||
{
|
||||
await client.Sdk.ClaimDeposit(new ClaimDepositRequest(deposit.id));
|
||||
claimedCount++;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Continue with next deposit
|
||||
}
|
||||
}
|
||||
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Claimed {claimedCount} deposits";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"error with sweep: {e.Message}";
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"error claiming deposits: {e.Message}";
|
||||
}
|
||||
|
||||
|
||||
return View((object) storeId);
|
||||
}
|
||||
|
||||
@@ -263,28 +269,9 @@ public class BreezController : Controller
|
||||
return RedirectToAction(nameof(Configure), new {storeId});
|
||||
}
|
||||
|
||||
if (address.Equals("store", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var store = ControllerContext.HttpContext.GetStoreData()
|
||||
.GetDerivationSchemeSettings(_paymentMethodHandlerDictionary, "BTC");
|
||||
var res = await _btcWalletProvider.GetWallet(storeId)
|
||||
.ReserveAddressAsync(storeId, store.AccountDerivation, "Breez");
|
||||
address = res.Address.ToString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
var prep = client.Sdk.PrepareOnchainPayment(new PrepareOnchainPaymentRequest(amount, SwapAmountType.Send, satPerByte));
|
||||
var result = client.Sdk.PayOnchain(new PayOnchainRequest(address, prep));
|
||||
// var result = client.Sdk.SendSpontaneousPayment(new SendSpontaneousPaymentRequestew SendOnchainRequest(amount, address, feesHash, satPerByte));
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"swap out created: {result.reverseSwapInfo.id}";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"Couldnt create swap out: {e.Message}";
|
||||
}
|
||||
// Spark SDK doesn't support onchain swap-out
|
||||
// This is a nodeless protocol focused on Lightning
|
||||
TempData[WellKnownTempData.ErrorMessage] = "Swap out is not available in Spark SDK (nodeless mode). Please withdraw via Lightning.";
|
||||
|
||||
return RedirectToAction("SwapOut", new {storeId});
|
||||
}
|
||||
@@ -304,7 +291,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)
|
||||
public async Task<IActionResult> SwapInRefund(string storeId, string depositId, string refundAddress)
|
||||
{
|
||||
var client = _breezService.GetClient(storeId);
|
||||
if (client is null)
|
||||
@@ -314,8 +301,8 @@ public class BreezController : Controller
|
||||
|
||||
try
|
||||
{
|
||||
var resp = client.Sdk.Refund(new RefundRequest(address, refundAddress, satPerByte));
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Refund tx: {resp.refundTxId}";
|
||||
var resp = await client.Sdk.RefundDeposit(new RefundDepositRequest(depositId, refundAddress));
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Refund successful: {resp.txId}";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -178,8 +178,8 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
|
||||
return new LightningNodeInformation()
|
||||
{
|
||||
Alias = $"spark {response.nodeId}",
|
||||
BlockHeight = (int)(response.blockHeight ?? 0)
|
||||
Alias = "Breez Spark (nodeless)",
|
||||
BlockHeight = 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
{
|
||||
OnchainBalance = new OnchainBalance()
|
||||
{
|
||||
Confirmed = Money.Satoshis((long)response.balanceSats)
|
||||
Confirmed = Money.Zero
|
||||
},
|
||||
OffchainBalance = new OffchainBalance()
|
||||
{
|
||||
@@ -245,8 +245,8 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
||||
_ => LightningPaymentStatus.Unknown
|
||||
},
|
||||
TotalAmount = LightMoney.Satoshis((long)sendResponse.payment.amountSats),
|
||||
FeeAmount = (long)sendResponse.payment.feesSats
|
||||
TotalAmount = LightMoney.Satoshis((long)sendResponse.payment.amount),
|
||||
FeeAmount = (long)sendResponse.payment.fees
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -291,9 +291,9 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
{
|
||||
return new LightningInvoice()
|
||||
{
|
||||
BOLT11 = response.destination,
|
||||
BOLT11 = response.paymentRequest,
|
||||
Status = LightningInvoiceStatus.Unpaid,
|
||||
Amount = LightMoney.Satoshis((long)response.feesSats)
|
||||
Amount = LightMoney.Satoshis((long)response.fee)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -301,10 +301,21 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
{
|
||||
if (payment == null) return null;
|
||||
|
||||
string paymentHash = null;
|
||||
string bolt11 = null;
|
||||
|
||||
if (payment.details is PaymentDetails.Lightning lightningDetails)
|
||||
{
|
||||
paymentHash = lightningDetails.paymentHash;
|
||||
bolt11 = lightningDetails.invoice;
|
||||
}
|
||||
|
||||
return new LightningInvoice()
|
||||
{
|
||||
Id = payment.id,
|
||||
Amount = LightMoney.Satoshis((long)payment.amountSats),
|
||||
PaymentHash = paymentHash ?? payment.id,
|
||||
BOLT11 = bolt11,
|
||||
Amount = LightMoney.Satoshis((long)payment.amount),
|
||||
Status = payment.status switch
|
||||
{
|
||||
PaymentStatus.Pending => LightningInvoiceStatus.Unpaid,
|
||||
@@ -312,7 +323,7 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
PaymentStatus.Completed => LightningInvoiceStatus.Paid,
|
||||
_ => LightningInvoiceStatus.Unpaid
|
||||
},
|
||||
PaidAt = payment.timestamp.HasValue ? DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp.Value) : null
|
||||
PaidAt = DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -320,10 +331,24 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
{
|
||||
if (payment == null) return null;
|
||||
|
||||
string paymentHash = null;
|
||||
string preimage = null;
|
||||
string bolt11 = null;
|
||||
|
||||
if (payment.details is PaymentDetails.Lightning lightningDetails)
|
||||
{
|
||||
paymentHash = lightningDetails.paymentHash;
|
||||
preimage = lightningDetails.preimage;
|
||||
bolt11 = lightningDetails.invoice;
|
||||
}
|
||||
|
||||
return new LightningPayment()
|
||||
{
|
||||
Id = payment.id,
|
||||
Amount = LightMoney.Satoshis((long)payment.amountSats),
|
||||
PaymentHash = paymentHash ?? payment.id,
|
||||
Preimage = preimage,
|
||||
BOLT11 = bolt11,
|
||||
Amount = LightMoney.Satoshis((long)payment.amount),
|
||||
Status = payment.status switch
|
||||
{
|
||||
PaymentStatus.Failed => LightningPaymentStatus.Failed,
|
||||
@@ -331,9 +356,9 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
||||
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
||||
_ => LightningPaymentStatus.Unknown
|
||||
},
|
||||
CreatedAt = payment.timestamp.HasValue ? DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp.Value) : DateTimeOffset.Now,
|
||||
Fee = LightMoney.Satoshis((long)payment.feesSats),
|
||||
AmountSent = LightMoney.Satoshis((long)payment.amountSats)
|
||||
CreatedAt = DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp),
|
||||
Fee = LightMoney.Satoshis((long)payment.fees),
|
||||
AmountSent = LightMoney.Satoshis((long)payment.amount)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Submodule submodules/btcpayserver updated: f3184c35b4...7932abd8b5
Reference in New Issue
Block a user