mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-17 15:44:26 +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")]
|
[HttpPost("sweep")]
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
[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);
|
var client = _breezService.GetClient(storeId);
|
||||||
if (client is null)
|
if (client is null)
|
||||||
@@ -112,27 +112,33 @@ public class BreezController : Controller
|
|||||||
return RedirectToAction(nameof(Configure), new {storeId});
|
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
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
TempData[WellKnownTempData.ErrorMessage] = $"error with sweep: {e.Message}";
|
TempData[WellKnownTempData.ErrorMessage] = $"error claiming deposits: {e.Message}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return View((object) storeId);
|
return View((object) storeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,28 +269,9 @@ public class BreezController : Controller
|
|||||||
return RedirectToAction(nameof(Configure), new {storeId});
|
return RedirectToAction(nameof(Configure), new {storeId});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address.Equals("store", StringComparison.InvariantCultureIgnoreCase))
|
// Spark SDK doesn't support onchain swap-out
|
||||||
{
|
// This is a nodeless protocol focused on Lightning
|
||||||
var store = ControllerContext.HttpContext.GetStoreData()
|
TempData[WellKnownTempData.ErrorMessage] = "Swap out is not available in Spark SDK (nodeless mode). Please withdraw via Lightning.";
|
||||||
.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}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return RedirectToAction("SwapOut", new {storeId});
|
return RedirectToAction("SwapOut", new {storeId});
|
||||||
}
|
}
|
||||||
@@ -304,7 +291,7 @@ public class BreezController : Controller
|
|||||||
|
|
||||||
[HttpPost("swapin/{address}/refund")]
|
[HttpPost("swapin/{address}/refund")]
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
[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);
|
var client = _breezService.GetClient(storeId);
|
||||||
if (client is null)
|
if (client is null)
|
||||||
@@ -314,8 +301,8 @@ public class BreezController : Controller
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var resp = client.Sdk.Refund(new RefundRequest(address, refundAddress, satPerByte));
|
var resp = await client.Sdk.RefundDeposit(new RefundDepositRequest(depositId, refundAddress));
|
||||||
TempData[WellKnownTempData.SuccessMessage] = $"Refund tx: {resp.refundTxId}";
|
TempData[WellKnownTempData.SuccessMessage] = $"Refund successful: {resp.txId}";
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -178,8 +178,8 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
|
|
||||||
return new LightningNodeInformation()
|
return new LightningNodeInformation()
|
||||||
{
|
{
|
||||||
Alias = $"spark {response.nodeId}",
|
Alias = "Breez Spark (nodeless)",
|
||||||
BlockHeight = (int)(response.blockHeight ?? 0)
|
BlockHeight = 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
{
|
{
|
||||||
OnchainBalance = new OnchainBalance()
|
OnchainBalance = new OnchainBalance()
|
||||||
{
|
{
|
||||||
Confirmed = Money.Satoshis((long)response.balanceSats)
|
Confirmed = Money.Zero
|
||||||
},
|
},
|
||||||
OffchainBalance = new OffchainBalance()
|
OffchainBalance = new OffchainBalance()
|
||||||
{
|
{
|
||||||
@@ -245,8 +245,8 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
||||||
_ => LightningPaymentStatus.Unknown
|
_ => LightningPaymentStatus.Unknown
|
||||||
},
|
},
|
||||||
TotalAmount = LightMoney.Satoshis((long)sendResponse.payment.amountSats),
|
TotalAmount = LightMoney.Satoshis((long)sendResponse.payment.amount),
|
||||||
FeeAmount = (long)sendResponse.payment.feesSats
|
FeeAmount = (long)sendResponse.payment.fees
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -291,9 +291,9 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
{
|
{
|
||||||
return new LightningInvoice()
|
return new LightningInvoice()
|
||||||
{
|
{
|
||||||
BOLT11 = response.destination,
|
BOLT11 = response.paymentRequest,
|
||||||
Status = LightningInvoiceStatus.Unpaid,
|
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;
|
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()
|
return new LightningInvoice()
|
||||||
{
|
{
|
||||||
Id = payment.id,
|
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
|
Status = payment.status switch
|
||||||
{
|
{
|
||||||
PaymentStatus.Pending => LightningInvoiceStatus.Unpaid,
|
PaymentStatus.Pending => LightningInvoiceStatus.Unpaid,
|
||||||
@@ -312,7 +323,7 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
PaymentStatus.Completed => LightningInvoiceStatus.Paid,
|
PaymentStatus.Completed => LightningInvoiceStatus.Paid,
|
||||||
_ => LightningInvoiceStatus.Unpaid
|
_ => 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;
|
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()
|
return new LightningPayment()
|
||||||
{
|
{
|
||||||
Id = payment.id,
|
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
|
Status = payment.status switch
|
||||||
{
|
{
|
||||||
PaymentStatus.Failed => LightningPaymentStatus.Failed,
|
PaymentStatus.Failed => LightningPaymentStatus.Failed,
|
||||||
@@ -331,9 +356,9 @@ public class BreezLightningClient : ILightningClient, IDisposable
|
|||||||
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
PaymentStatus.Pending => LightningPaymentStatus.Pending,
|
||||||
_ => LightningPaymentStatus.Unknown
|
_ => LightningPaymentStatus.Unknown
|
||||||
},
|
},
|
||||||
CreatedAt = payment.timestamp.HasValue ? DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp.Value) : DateTimeOffset.Now,
|
CreatedAt = DateTimeOffset.FromUnixTimeSeconds((long)payment.timestamp),
|
||||||
Fee = LightMoney.Satoshis((long)payment.feesSats),
|
Fee = LightMoney.Satoshis((long)payment.fees),
|
||||||
AmountSent = LightMoney.Satoshis((long)payment.amountSats)
|
AmountSent = LightMoney.Satoshis((long)payment.amount)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Submodule submodules/btcpayserver updated: f3184c35b4...7932abd8b5
Reference in New Issue
Block a user