mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-12 10:30:47 +01:00
Pull Payment: Support LNURL Withdraw with SATS denomination (#5041)
* Pull Payment: Support LNURL Withdraw with SATS denomination * Refactor and add tests
This commit is contained in:
parent
fa8b977016
commit
f11424f73a
8 changed files with 89 additions and 35 deletions
|
@ -1074,6 +1074,22 @@ namespace BTCPayServer.Tests
|
||||||
var lnrURLs = await unauthenticated.GetPullPaymentLNURL(test4.Id);
|
var lnrURLs = await unauthenticated.GetPullPaymentLNURL(test4.Id);
|
||||||
Assert.IsType<string>(lnrURLs.LNURLBech32);
|
Assert.IsType<string>(lnrURLs.LNURLBech32);
|
||||||
Assert.IsType<string>(lnrURLs.LNURLUri);
|
Assert.IsType<string>(lnrURLs.LNURLUri);
|
||||||
|
Assert.Equal(12.303228134m, test4.Amount);
|
||||||
|
Assert.Equal("BTC", test4.Currency);
|
||||||
|
|
||||||
|
// Test with SATS denomination values
|
||||||
|
var testSats = await client.CreatePullPayment(storeId, new Client.Models.CreatePullPaymentRequest()
|
||||||
|
{
|
||||||
|
Name = "Test SATS",
|
||||||
|
Amount = 21000,
|
||||||
|
Currency = "SATS",
|
||||||
|
PaymentMethods = new[] { "BTC", "BTC-LightningNetwork", "BTC_LightningLike" }
|
||||||
|
});
|
||||||
|
lnrURLs = await unauthenticated.GetPullPaymentLNURL(testSats.Id);
|
||||||
|
Assert.IsType<string>(lnrURLs.LNURLBech32);
|
||||||
|
Assert.IsType<string>(lnrURLs.LNURLUri);
|
||||||
|
Assert.Equal(21000, testSats.Amount);
|
||||||
|
Assert.Equal("SATS", testSats.Currency);
|
||||||
|
|
||||||
//permission test around auto approved pps and payouts
|
//permission test around auto approved pps and payouts
|
||||||
var nonApproved = await acc.CreateClient(Policies.CanCreateNonApprovedPullPayments);
|
var nonApproved = await acc.CreateClient(Policies.CanCreateNonApprovedPullPayments);
|
||||||
|
|
|
@ -1748,7 +1748,6 @@ namespace BTCPayServer.Tests
|
||||||
Assert.Contains(labels, element => element.Text == "pull-payment");
|
Assert.Contains(labels, element => element.Text == "pull-payment");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
s.GoToStore(s.StoreId, StoreNavPages.Payouts);
|
s.GoToStore(s.StoreId, StoreNavPages.Payouts);
|
||||||
s.Driver.FindElement(By.Id($"{PayoutState.InProgress}-view")).Click();
|
s.Driver.FindElement(By.Id($"{PayoutState.InProgress}-view")).Click();
|
||||||
ReadOnlyCollection<IWebElement> txs;
|
ReadOnlyCollection<IWebElement> txs;
|
||||||
|
@ -1932,8 +1931,7 @@ namespace BTCPayServer.Tests
|
||||||
|
|
||||||
Assert.Contains(PayoutState.AwaitingPayment.GetStateString(), s.Driver.PageSource);
|
Assert.Contains(PayoutState.AwaitingPayment.GetStateString(), s.Driver.PageSource);
|
||||||
|
|
||||||
//lnurl-w support check
|
// LNURL Withdraw support check with BTC denomination
|
||||||
|
|
||||||
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||||
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
||||||
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
||||||
|
@ -2001,6 +1999,42 @@ namespace BTCPayServer.Tests
|
||||||
|
|
||||||
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
|
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// LNURL Withdraw support check with SATS denomination
|
||||||
|
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||||
|
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
||||||
|
s.Driver.FindElement(By.Id("Name")).SendKeys("PP SATS");
|
||||||
|
s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true);
|
||||||
|
s.Driver.FindElement(By.Id("Amount")).Clear();
|
||||||
|
s.Driver.FindElement(By.Id("Amount")).SendKeys("21021");
|
||||||
|
s.Driver.FindElement(By.Id("Currency")).Clear();
|
||||||
|
s.Driver.FindElement(By.Id("Currency")).SendKeys("SATS" + Keys.Enter);
|
||||||
|
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
|
||||||
|
s.Driver.FindElement(By.LinkText("View")).Click();
|
||||||
|
s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click();
|
||||||
|
lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http"));
|
||||||
|
s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click();
|
||||||
|
var amount = new LightMoney(21021, LightMoneyUnit.Satoshi);
|
||||||
|
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient));
|
||||||
|
Assert.Equal(amount, info.MaxWithdrawable);
|
||||||
|
Assert.Equal(amount, info.CurrentBalance);
|
||||||
|
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(info.BalanceCheck, s.Server.PayTester.HttpClient));
|
||||||
|
Assert.Equal(amount, info.MaxWithdrawable);
|
||||||
|
Assert.Equal(amount, info.CurrentBalance);
|
||||||
|
|
||||||
|
bolt2 = (await s.Server.CustomerLightningD.CreateInvoice(
|
||||||
|
amount,
|
||||||
|
$"LNurl w payout test {DateTime.UtcNow.Ticks}",
|
||||||
|
TimeSpan.FromHours(1), CancellationToken.None));
|
||||||
|
response = await info.SendRequest(bolt2.BOLT11, s.Server.PayTester.HttpClient);
|
||||||
|
await TestUtils.EventuallyAsync(async () =>
|
||||||
|
{
|
||||||
|
s.Driver.Navigate().Refresh();
|
||||||
|
Assert.Contains(bolt2.BOLT11, s.Driver.PageSource);
|
||||||
|
|
||||||
|
Assert.Contains(PayoutState.Completed.GetStateString(), s.Driver.PageSource);
|
||||||
|
Assert.Equal(LightningInvoiceStatus.Paid, (await s.Server.CustomerLightningD.GetInvoice(bolt2.Id)).Status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
@ -255,16 +255,15 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||||
return PullPaymentNotFound();
|
return PullPaymentNotFound();
|
||||||
|
|
||||||
var blob = pp.GetBlob();
|
var blob = pp.GetBlob();
|
||||||
var pms = blob.SupportedPaymentMethods.FirstOrDefault(id => id.PaymentType == LightningPaymentType.Instance && _networkProvider.DefaultNetwork.CryptoCode == id.CryptoCode);
|
if (_pullPaymentService.SupportsLNURL(blob))
|
||||||
if (pms is not null && blob.Currency.Equals(pms.CryptoCode, StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
{
|
||||||
var lnurlEndpoint = new Uri(Url.Action("GetLNURLForPullPayment", "UILNURL", new
|
var lnurlEndpoint = new Uri(Url.Action("GetLNURLForPullPayment", "UILNURL", new
|
||||||
{
|
{
|
||||||
cryptoCode = _networkProvider.DefaultNetwork.CryptoCode,
|
cryptoCode = _networkProvider.DefaultNetwork.CryptoCode,
|
||||||
pullPaymentId = pullPaymentId
|
pullPaymentId
|
||||||
}, Request.Scheme, Request.Host.ToString())!);
|
}, Request.Scheme, Request.Host.ToString())!);
|
||||||
|
|
||||||
return base.Ok(new PullPaymentLNURL()
|
return base.Ok(new PullPaymentLNURL
|
||||||
{
|
{
|
||||||
LNURLBech32 = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", true).ToString(),
|
LNURLBech32 = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", true).ToString(),
|
||||||
LNURLUri = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", false).ToString()
|
LNURLUri = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", false).ToString()
|
||||||
|
|
|
@ -109,24 +109,24 @@ namespace BTCPayServer
|
||||||
}
|
}
|
||||||
|
|
||||||
var blob = pp.GetBlob();
|
var blob = pp.GetBlob();
|
||||||
if (!blob.Currency.Equals(cryptoCode, StringComparison.InvariantCultureIgnoreCase))
|
if (!_pullPaymentHostedService.SupportsLNURL(blob))
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var unit = blob.Currency == "SATS" ? LightMoneyUnit.Satoshi : LightMoneyUnit.BTC;
|
||||||
var progress = _pullPaymentHostedService.CalculatePullPaymentProgress(pp, DateTimeOffset.UtcNow);
|
var progress = _pullPaymentHostedService.CalculatePullPaymentProgress(pp, DateTimeOffset.UtcNow);
|
||||||
|
|
||||||
var remaining = progress.Limit - progress.Completed - progress.Awaiting;
|
var remaining = progress.Limit - progress.Completed - progress.Awaiting;
|
||||||
var request = new LNURLWithdrawRequest
|
var request = new LNURLWithdrawRequest
|
||||||
{
|
{
|
||||||
MaxWithdrawable = LightMoney.FromUnit(remaining, LightMoneyUnit.BTC),
|
MaxWithdrawable = LightMoney.FromUnit(remaining, unit),
|
||||||
K1 = pullPaymentId,
|
K1 = pullPaymentId,
|
||||||
BalanceCheck = new Uri(Request.GetCurrentUrl()),
|
BalanceCheck = new Uri(Request.GetCurrentUrl()),
|
||||||
CurrentBalance = LightMoney.FromUnit(remaining, LightMoneyUnit.BTC),
|
CurrentBalance = LightMoney.FromUnit(remaining, unit),
|
||||||
MinWithdrawable =
|
MinWithdrawable =
|
||||||
LightMoney.FromUnit(
|
LightMoney.FromUnit(
|
||||||
Math.Min(await _lightningLikePayoutHandler.GetMinimumPayoutAmount(pmi, null), remaining),
|
Math.Min(await _lightningLikePayoutHandler.GetMinimumPayoutAmount(pmi, null), remaining),
|
||||||
LightMoneyUnit.BTC),
|
unit),
|
||||||
Tag = "withdrawRequest",
|
Tag = "withdrawRequest",
|
||||||
Callback = new Uri(Request.GetCurrentUrl()),
|
Callback = new Uri(Request.GetCurrentUrl()),
|
||||||
// It's not `pp.GetBlob().Description` because this would be HTML
|
// It's not `pp.GetBlob().Description` because this would be HTML
|
||||||
|
@ -154,13 +154,13 @@ namespace BTCPayServer
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var claimResponse = await _pullPaymentHostedService.Claim(new ClaimRequest()
|
var claimResponse = await _pullPaymentHostedService.Claim(new ClaimRequest
|
||||||
{
|
{
|
||||||
Destination = new BoltInvoiceClaimDestination(pr, result),
|
Destination = new BoltInvoiceClaimDestination(pr, result),
|
||||||
PaymentMethodId = pmi,
|
PaymentMethodId = pmi,
|
||||||
PullPaymentId = pullPaymentId,
|
PullPaymentId = pullPaymentId,
|
||||||
StoreId = pp.StoreId,
|
StoreId = pp.StoreId,
|
||||||
Value = result.MinimumAmount.ToDecimal(LightMoneyUnit.BTC)
|
Value = result.MinimumAmount.ToDecimal(unit)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (claimResponse.Result != ClaimRequest.ClaimResult.Ok)
|
if (claimResponse.Result != ClaimRequest.ClaimResult.Ok)
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace BTCPayServer.Controllers
|
||||||
private readonly CurrencyNameTable _currencyNameTable;
|
private readonly CurrencyNameTable _currencyNameTable;
|
||||||
private readonly DisplayFormatter _displayFormatter;
|
private readonly DisplayFormatter _displayFormatter;
|
||||||
private readonly PullPaymentHostedService _pullPaymentHostedService;
|
private readonly PullPaymentHostedService _pullPaymentHostedService;
|
||||||
|
private readonly BTCPayNetworkProvider _networkProvider;
|
||||||
private readonly BTCPayNetworkJsonSerializerSettings _serializerSettings;
|
private readonly BTCPayNetworkJsonSerializerSettings _serializerSettings;
|
||||||
private readonly IEnumerable<IPayoutHandler> _payoutHandlers;
|
private readonly IEnumerable<IPayoutHandler> _payoutHandlers;
|
||||||
private readonly StoreRepository _storeRepository;
|
private readonly StoreRepository _storeRepository;
|
||||||
|
@ -37,6 +38,7 @@ namespace BTCPayServer.Controllers
|
||||||
CurrencyNameTable currencyNameTable,
|
CurrencyNameTable currencyNameTable,
|
||||||
DisplayFormatter displayFormatter,
|
DisplayFormatter displayFormatter,
|
||||||
PullPaymentHostedService pullPaymentHostedService,
|
PullPaymentHostedService pullPaymentHostedService,
|
||||||
|
BTCPayNetworkProvider networkProvider,
|
||||||
BTCPayNetworkJsonSerializerSettings serializerSettings,
|
BTCPayNetworkJsonSerializerSettings serializerSettings,
|
||||||
IEnumerable<IPayoutHandler> payoutHandlers,
|
IEnumerable<IPayoutHandler> payoutHandlers,
|
||||||
StoreRepository storeRepository)
|
StoreRepository storeRepository)
|
||||||
|
@ -48,6 +50,7 @@ namespace BTCPayServer.Controllers
|
||||||
_serializerSettings = serializerSettings;
|
_serializerSettings = serializerSettings;
|
||||||
_payoutHandlers = payoutHandlers;
|
_payoutHandlers = payoutHandlers;
|
||||||
_storeRepository = storeRepository;
|
_storeRepository = storeRepository;
|
||||||
|
_networkProvider = networkProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
|
@ -102,6 +105,13 @@ namespace BTCPayServer.Controllers
|
||||||
}).ToList()
|
}).ToList()
|
||||||
};
|
};
|
||||||
vm.IsPending &= vm.AmountDue > 0.0m;
|
vm.IsPending &= vm.AmountDue > 0.0m;
|
||||||
|
|
||||||
|
if (_pullPaymentHostedService.SupportsLNURL(blob))
|
||||||
|
{
|
||||||
|
var url = Url.Action("GetLNURLForPullPayment", "UILNURL", new { cryptoCode = _networkProvider.DefaultNetwork.CryptoCode, pullPaymentId = vm.Id }, Request.Scheme, Request.Host.ToString());
|
||||||
|
vm.LnurlEndpoint = url != null ? new Uri(url) : null;
|
||||||
|
}
|
||||||
|
|
||||||
return View(nameof(ViewPullPayment), vm);
|
return View(nameof(ViewPullPayment), vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace BTCPayServer.HostedServices
|
||||||
|
|
||||||
public class PullPaymentHostedService : BaseAsyncService
|
public class PullPaymentHostedService : BaseAsyncService
|
||||||
{
|
{
|
||||||
|
private readonly string[] _lnurlSupportedCurrencies = { "BTC", "SATS" };
|
||||||
|
|
||||||
public class CancelRequest
|
public class CancelRequest
|
||||||
{
|
{
|
||||||
public CancelRequest(string pullPaymentId)
|
public CancelRequest(string pullPaymentId)
|
||||||
|
@ -337,6 +339,14 @@ namespace BTCPayServer.HostedServices
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SupportsLNURL(PullPaymentBlob blob)
|
||||||
|
{
|
||||||
|
var pms = blob.SupportedPaymentMethods.FirstOrDefault(id =>
|
||||||
|
id.PaymentType == LightningPaymentType.Instance &&
|
||||||
|
_networkProvider.DefaultNetwork.CryptoCode == id.CryptoCode);
|
||||||
|
return pms is not null && _lnurlSupportedCurrencies.Contains(blob.Currency);
|
||||||
|
}
|
||||||
|
|
||||||
public Task<RateResult> GetRate(PayoutData payout, string explicitRateRule, CancellationToken cancellationToken)
|
public Task<RateResult> GetRate(PayoutData payout, string explicitRateRule, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var ppBlob = payout.PullPaymentData?.GetBlob();
|
var ppBlob = payout.PullPaymentData?.GetBlob();
|
||||||
|
|
|
@ -96,6 +96,7 @@ namespace BTCPayServer.Models
|
||||||
public DateTimeOffset StartDate { get; set; }
|
public DateTimeOffset StartDate { get; set; }
|
||||||
public DateTime LastRefreshed { get; set; }
|
public DateTime LastRefreshed { get; set; }
|
||||||
public CurrencyData CurrencyData { get; set; }
|
public CurrencyData CurrencyData { get; set; }
|
||||||
|
public Uri LnurlEndpoint { get; set; }
|
||||||
public bool Archived { get; set; }
|
public bool Archived { get; set; }
|
||||||
public bool AutoApprove { get; set; }
|
public bool AutoApprove { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
@using BTCPayServer.Client
|
@using BTCPayServer.Client
|
||||||
@using BTCPayServer.Payments
|
|
||||||
@using BTCPayServer.Services
|
@using BTCPayServer.Services
|
||||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
@using BTCPayServer.Abstractions.TagHelpers
|
@using BTCPayServer.Abstractions.TagHelpers
|
||||||
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
|
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
|
||||||
@inject BTCPayServerEnvironment Env
|
@inject BTCPayServerEnvironment Env
|
||||||
@inject BTCPayNetworkProvider BtcPayNetworkProvider
|
|
||||||
@inject DisplayFormatter DisplayFormatter
|
@inject DisplayFormatter DisplayFormatter
|
||||||
@model BTCPayServer.Models.ViewPullPaymentModel
|
@model BTCPayServer.Models.ViewPullPaymentModel
|
||||||
@{
|
@{
|
||||||
|
@ -25,22 +23,6 @@
|
||||||
return "bg-warning";
|
return "bg-warning";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string lnurl = null;
|
|
||||||
string lnurlUri = null;
|
|
||||||
|
|
||||||
var pms = Model.PaymentMethods.FirstOrDefault(id => id.PaymentType == LightningPaymentType.Instance && BtcPayNetworkProvider.DefaultNetwork.CryptoCode == id.CryptoCode);
|
|
||||||
if (pms is not null && Model.Currency.Equals(pms.CryptoCode, StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
var lnurlEndpoint = new Uri(Url.Action("GetLNURLForPullPayment", "UILNURL", new
|
|
||||||
{
|
|
||||||
cryptoCode = pms.CryptoCode,
|
|
||||||
pullPaymentId = Model.Id
|
|
||||||
}, Context.Request.Scheme, Context.Request.Host.ToString()));
|
|
||||||
lnurl = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", true).ToString();
|
|
||||||
lnurlUri = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", false).ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" @(Env.IsDeveloping ? " data-devenv" : "")>
|
<html lang="en" @(Env.IsDeveloping ? " data-devenv" : "")>
|
||||||
|
@ -62,7 +44,7 @@
|
||||||
<div class="row align-items-center" style="width:calc(100% + 30px)">
|
<div class="row align-items-center" style="width:calc(100% + 30px)">
|
||||||
<div class="col-12 mb-3 col-lg-6 mb-lg-0">
|
<div class="col-12 mb-3 col-lg-6 mb-lg-0">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@if (lnurl is not null)
|
@if (Model.LnurlEndpoint is not null)
|
||||||
{
|
{
|
||||||
<button type="button" class="input-group-prepend btn btn-outline-secondary" id="lnurlwithdraw-button" data-bs-toggle="modal" data-bs-target="#scan-qr-modal">
|
<button type="button" class="input-group-prepend btn btn-outline-secondary" id="lnurlwithdraw-button" data-bs-toggle="modal" data-bs-target="#scan-qr-modal">
|
||||||
<span class="fa fa-qrcode fa-2x" title="LNURL-Withdraw"></span>
|
<span class="fa fa-qrcode fa-2x" title="LNURL-Withdraw"></span>
|
||||||
|
@ -223,8 +205,10 @@
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<partial name="LayoutFoot" />
|
<partial name="LayoutFoot" />
|
||||||
@if (lnurl is not null)
|
@if (Model.LnurlEndpoint is not null)
|
||||||
{
|
{
|
||||||
|
var lnurlUri = LNURL.LNURL.EncodeUri(Model.LnurlEndpoint, "withdrawRequest", false).ToString();
|
||||||
|
var lnurlBech32 = LNURL.LNURL.EncodeUri(Model.LnurlEndpoint, "withdrawRequest", true).ToString();
|
||||||
var note = "You can scan or open this link with a <a href='https://github.com/fiatjaf/lnurl-rfc#lnurl-documents' target='_blank' rel='noreferrer noopener'>LNURL-Withdraw</a> enabled wallet.";
|
var note = "You can scan or open this link with a <a href='https://github.com/fiatjaf/lnurl-rfc#lnurl-documents' target='_blank' rel='noreferrer noopener'>LNURL-Withdraw</a> enabled wallet.";
|
||||||
if (!Model.AutoApprove)
|
if (!Model.AutoApprove)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +221,7 @@
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const modes = {
|
const modes = {
|
||||||
uri: { title: "URI", fragments: [@Safe.Json(lnurlUri)], showData: true, href: @Safe.Json(lnurlUri) },
|
uri: { title: "URI", fragments: [@Safe.Json(lnurlUri)], showData: true, href: @Safe.Json(lnurlUri) },
|
||||||
bech32: { title: "Bech32", fragments: [@Safe.Json(lnurl)], showData: true, href: @Safe.Json(lnurl) }
|
bech32: { title: "Bech32", fragments: [@Safe.Json(lnurlBech32)], showData: true, href: @Safe.Json(lnurlBech32) }
|
||||||
};
|
};
|
||||||
initQRShow({ title: "LNURL Withdraw", note: @Safe.Json(note), modes })
|
initQRShow({ title: "LNURL Withdraw", note: @Safe.Json(note), modes })
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue