mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 14:34:23 +01:00
Add translations to the Dashboard
This commit is contained in:
@@ -8,6 +8,14 @@ namespace BTCPayServer.Abstractions.Extensions;
|
|||||||
|
|
||||||
public static class SetStatusMessageModelExtensions
|
public static class SetStatusMessageModelExtensions
|
||||||
{
|
{
|
||||||
|
public static void SetStatusSuccess(this ITempDataDictionary tempData, string statusMessage)
|
||||||
|
{
|
||||||
|
tempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
|
{
|
||||||
|
Severity = StatusMessageModel.StatusSeverity.Success,
|
||||||
|
Message = statusMessage
|
||||||
|
});
|
||||||
|
}
|
||||||
public static void SetStatusMessageModel(this ITempDataDictionary tempData, StatusMessageModel statusMessage)
|
public static void SetStatusMessageModel(this ITempDataDictionary tempData, StatusMessageModel statusMessage)
|
||||||
{
|
{
|
||||||
if (statusMessage == null)
|
if (statusMessage == null)
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ using BTCPayServer.Client.Models;
|
|||||||
using BTCPayServer.Controllers;
|
using BTCPayServer.Controllers;
|
||||||
using ExchangeSharp;
|
using ExchangeSharp;
|
||||||
using Microsoft.AspNetCore.Html;
|
using Microsoft.AspNetCore.Html;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Localization;
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.Extensions.FileSystemGlobbing;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -349,6 +351,8 @@ retry:
|
|||||||
{
|
{
|
||||||
defaultTranslatedKeys.Add(k);
|
defaultTranslatedKeys.Add(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddLocalizers(defaultTranslatedKeys, txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all cshtml file, search for text-translate or ViewLocalizer usage
|
// Go through all cshtml file, search for text-translate or ViewLocalizer usage
|
||||||
@@ -360,21 +364,11 @@ retry:
|
|||||||
{
|
{
|
||||||
var filePath = file.FullName;
|
var filePath = file.FullName;
|
||||||
var txt = File.ReadAllText(file.FullName);
|
var txt = File.ReadAllText(file.FullName);
|
||||||
foreach (string localizer in new[] { "ViewLocalizer", "StringLocalizer" })
|
AddLocalizers(defaultTranslatedKeys, txt);
|
||||||
{
|
|
||||||
if (txt.Contains(localizer))
|
|
||||||
{
|
|
||||||
var matches = Regex.Matches(txt, localizer + "\\[\"(.*?)\"[\\],]");
|
|
||||||
foreach (Match match in matches)
|
|
||||||
{
|
|
||||||
defaultTranslatedKeys.Add(match.Groups[1].Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filePath = filePath.Replace(Path.Combine(soldir.FullName, "BTCPayServer"), "/");
|
filePath = filePath.Replace(Path.Combine(soldir.FullName, "BTCPayServer"), "/");
|
||||||
var item = engine.FileSystem.GetItem(filePath);
|
var item = engine.FileSystem.GetItem(filePath);
|
||||||
|
|
||||||
var node = (DocumentIntermediateNode)engine.Process(item).Items[typeof(DocumentIntermediateNode)];
|
var node = (DocumentIntermediateNode)engine.Process(item).Items[typeof(DocumentIntermediateNode)];
|
||||||
var w = new TranslatedKeyNodeWalker(defaultTranslatedKeys, txt);
|
var w = new TranslatedKeyNodeWalker(defaultTranslatedKeys, txt);
|
||||||
w.Visit(node);
|
w.Visit(node);
|
||||||
@@ -397,6 +391,24 @@ retry:
|
|||||||
content += defaultTranslation.Substring(endIdx);
|
content += defaultTranslation.Substring(endIdx);
|
||||||
File.WriteAllText(path, content);
|
File.WriteAllText(path, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddLocalizers(List<string> defaultTranslatedKeys, string txt)
|
||||||
|
{
|
||||||
|
foreach (string localizer in new[] { "ViewLocalizer", "StringLocalizer" })
|
||||||
|
{
|
||||||
|
if (txt.Contains(localizer))
|
||||||
|
{
|
||||||
|
var matches = Regex.Matches(txt, localizer + "\\[\"(.*?)\"[\\],]");
|
||||||
|
foreach (Match match in matches)
|
||||||
|
{
|
||||||
|
var k = match.Groups[1].Value;
|
||||||
|
k = k.Replace("\\", "");
|
||||||
|
defaultTranslatedKeys.Add(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DisplayNameWalker : CSharpSyntaxWalker
|
class DisplayNameWalker : CSharpSyntaxWalker
|
||||||
{
|
{
|
||||||
public List<string> Keys = new List<string>();
|
public List<string> Keys = new List<string>();
|
||||||
|
|||||||
@@ -107,13 +107,13 @@
|
|||||||
@if (ViewData.IsCategoryActive(typeof(WalletsNavPages), scheme.WalletId.ToString()) || ViewData.IsPageActive([WalletsNavPages.Settings], scheme.WalletId.ToString()) || ViewData.IsPageActive([StoreNavPages.OnchainSettings], categoryId))
|
@if (ViewData.IsCategoryActive(typeof(WalletsNavPages), scheme.WalletId.ToString()) || ViewData.IsPageActive([WalletsNavPages.Settings], scheme.WalletId.ToString()) || ViewData.IsPageActive([StoreNavPages.OnchainSettings], categoryId))
|
||||||
{
|
{
|
||||||
<li class="nav-item nav-item-sub">
|
<li class="nav-item nav-item-sub">
|
||||||
<a id="WalletNav-Send" class="nav-link @ViewData.ActivePageClass([WalletsNavPages.Send, WalletsNavPages.PSBT], scheme.WalletId.ToString())" asp-area="" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@scheme.WalletId">Send</a>
|
<a id="WalletNav-Send" class="nav-link @ViewData.ActivePageClass([WalletsNavPages.Send, WalletsNavPages.PSBT], scheme.WalletId.ToString())" asp-area="" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@scheme.WalletId" text-translate="true">Send</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item nav-item-sub">
|
<li class="nav-item nav-item-sub">
|
||||||
<a id="WalletNav-Receive" class="nav-link @ViewData.ActivePageClass(WalletsNavPages.Receive, scheme.WalletId.ToString())" asp-area="" asp-controller="UIWallets" asp-action="WalletReceive" asp-route-walletId="@scheme.WalletId">Receive</a>
|
<a id="WalletNav-Receive" class="nav-link @ViewData.ActivePageClass(WalletsNavPages.Receive, scheme.WalletId.ToString())" asp-area="" asp-controller="UIWallets" asp-action="WalletReceive" asp-route-walletId="@scheme.WalletId" text-translate="true">Receive</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item nav-item-sub">
|
<li class="nav-item nav-item-sub">
|
||||||
<a id="WalletNav-Settings" class="nav-link @ViewData.ActivePageClass(WalletsNavPages.Settings, scheme.WalletId.ToString()) @ViewData.ActivePageClass(StoreNavPages.OnchainSettings, categoryId)" asp-area="" asp-controller="UIStores" asp-action="WalletSettings" asp-route-cryptoCode="@scheme.WalletId.CryptoCode" asp-route-storeId="@scheme.WalletId.StoreId">Settings</a>
|
<a id="WalletNav-Settings" class="nav-link @ViewData.ActivePageClass(WalletsNavPages.Settings, scheme.WalletId.ToString()) @ViewData.ActivePageClass(StoreNavPages.OnchainSettings, categoryId)" asp-area="" asp-controller="UIStores" asp-action="WalletSettings" asp-route-cryptoCode="@scheme.WalletId.CryptoCode" asp-route-storeId="@scheme.WalletId.StoreId" text-translate="true">Settings</a>
|
||||||
</li>
|
</li>
|
||||||
<vc:ui-extension-point location="wallet-nav" model="@Model" />
|
<vc:ui-extension-point location="wallet-nav" model="@Model" />
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
@if (ViewData.IsPageActive([StoreNavPages.Lightning, StoreNavPages.LightningSettings], $"{Model.Store.Id}-{scheme.CryptoCode}"))
|
@if (ViewData.IsPageActive([StoreNavPages.Lightning, StoreNavPages.LightningSettings], $"{Model.Store.Id}-{scheme.CryptoCode}"))
|
||||||
{
|
{
|
||||||
<li class="nav-item nav-item-sub">
|
<li class="nav-item nav-item-sub">
|
||||||
<a id="StoreNav-@(nameof(StoreNavPages.LightningSettings))" class="nav-link @ViewData.ActivePageClass(StoreNavPages.LightningSettings)" asp-controller="UIStores" asp-action="LightningSettings" asp-route-storeId="@Model.Store.Id" asp-route-cryptoCode="@scheme.CryptoCode">Settings</a>
|
<a id="StoreNav-@(nameof(StoreNavPages.LightningSettings))" class="nav-link @ViewData.ActivePageClass(StoreNavPages.LightningSettings)" asp-controller="UIStores" asp-action="LightningSettings" asp-route-storeId="@Model.Store.Id" asp-route-cryptoCode="@scheme.CryptoCode" text-translate="true">Settings</a>
|
||||||
</li>
|
</li>
|
||||||
<vc:ui-extension-point location="lightning-nav" model="@Model"/>
|
<vc:ui-extension-point location="lightning-nav" model="@Model"/>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
}
|
}
|
||||||
<div id="StoreLightningBalance-@Model.Store.Id" class="widget store-lightning-balance">
|
<div id="StoreLightningBalance-@Model.Store.Id" class="widget store-lightning-balance">
|
||||||
<div class="d-flex gap-3 align-items-center justify-content-between mb-2">
|
<div class="d-flex gap-3 align-items-center justify-content-between mb-2">
|
||||||
<h6>Lightning Balance</h6>
|
<h6 text-translate="true">Lightning Balance</h6>
|
||||||
@if (Model.CryptoCode != Model.DefaultCurrency && Model.Balance != null)
|
@if (Model.CryptoCode != Model.DefaultCurrency && Model.Balance != null)
|
||||||
{
|
{
|
||||||
<div class="btn-group btn-group-sm gap-0 currency-toggle" role="group">
|
<div class="btn-group btn-group-sm gap-0 currency-toggle" role="group">
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<div class="d-flex align-items-baseline gap-1">
|
<div class="d-flex align-items-baseline gap-1">
|
||||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOffchain" data-sensitive>@Model.TotalOffchain</h3>
|
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOffchain" data-sensitive>@Model.TotalOffchain</h3>
|
||||||
<span class="text-secondary fw-semibold text-nowrap">
|
<span class="text-secondary fw-semibold text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> in channels
|
@ViewLocalizer["<span class=\"currency\">{0}</span> in channels", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
@Model.Balance.OffchainBalance.Opening
|
@Model.Balance.OffchainBalance.Opening
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> opening channels
|
@ViewLocalizer["<span class=\"currency\">{0}</span> opening channels", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
@Model.Balance.OffchainBalance.Local
|
@Model.Balance.OffchainBalance.Local
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> local balance
|
@ViewLocalizer["<span class=\"currency\">{0}</span> local balance", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
@Model.Balance.OffchainBalance.Remote
|
@Model.Balance.OffchainBalance.Remote
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> remote balance
|
@ViewLocalizer["<span class=\"currency\">{0}</span> remote balance", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
@Model.Balance.OffchainBalance.Closing
|
@Model.Balance.OffchainBalance.Closing
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> closing channels
|
@ViewLocalizer["<span class=\"currency\">{0}</span> closing channels", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
<div class="d-flex align-items-baseline gap-1">
|
<div class="d-flex align-items-baseline gap-1">
|
||||||
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOnchain" data-sensitive>@Model.TotalOnchain</h3>
|
<h3 class="d-inline-block me-1" data-balance="@Model.TotalOnchain" data-sensitive>@Model.TotalOnchain</h3>
|
||||||
<span class="text-secondary fw-semibold text-nowrap">
|
<span class="text-secondary fw-semibold text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> on-chain
|
@ViewLocalizer["<span class=\"currency\">{0}</span> on-chain", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="balance-details collapse" id="balanceDetailsOnchain">
|
<div class="balance-details collapse" id="balanceDetailsOnchain">
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
@Model.Balance.OnchainBalance.Confirmed
|
@Model.Balance.OnchainBalance.Confirmed
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> confirmed
|
@ViewLocalizer["<span class=\"currency\">{0}</span> confirmed", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
@Model.Balance.OnchainBalance.Unconfirmed
|
@Model.Balance.OnchainBalance.Unconfirmed
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> unconfirmed
|
@ViewLocalizer["<span class=\"currency\">{0}</span> unconfirmed", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
@Model.Balance.OnchainBalance.Reserved
|
@Model.Balance.OnchainBalance.Reserved
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondary text-nowrap">
|
<span class="text-secondary text-nowrap">
|
||||||
<span class="currency">@Model.CryptoCode</span> reserved
|
@ViewLocalizer["<span class=\"currency\">{0}</span> reserved", @Model.CryptoCode]
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
{
|
{
|
||||||
<button class="d-inline-flex align-items-center btn btn-link text-primary fw-semibold p-0 mt-3 ms-n1" type="button" data-bs-toggle="collapse" data-bs-target=".balance-details" aria-expanded="false" aria-controls="balanceDetailsOffchain balanceDetailsOnchain">
|
<button class="d-inline-flex align-items-center btn btn-link text-primary fw-semibold p-0 mt-3 ms-n1" type="button" data-bs-toggle="collapse" data-bs-target=".balance-details" aria-expanded="false" aria-controls="balanceDetailsOffchain balanceDetailsOnchain">
|
||||||
<vc:icon symbol="caret-down"/>
|
<vc:icon symbol="caret-down"/>
|
||||||
<span class="ms-1">Details</span>
|
<span class="ms-1" text-translate="true">Details</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
{
|
{
|
||||||
<div class="loading d-flex justify-content-center p-3">
|
<div class="loading d-flex justify-content-center p-3">
|
||||||
<div class="spinner-border text-light" role="status">
|
<div class="spinner-border text-light" role="status">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden" text-translate="true">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -4,14 +4,15 @@
|
|||||||
{
|
{
|
||||||
<div id="StoreLightningServices-@Model.Store.Id" class="widget store-lightning-services">
|
<div id="StoreLightningServices-@Model.Store.Id" class="widget store-lightning-services">
|
||||||
<header class="mb-4">
|
<header class="mb-4">
|
||||||
<h6>Lightning Services</h6>
|
<h6 text-translate="true">Lightning Services</h6>
|
||||||
<a
|
<a
|
||||||
asp-controller="UIPublicLightningNodeInfo"
|
asp-controller="UIPublicLightningNodeInfo"
|
||||||
asp-action="ShowLightningNodeInfo"app-top-items
|
asp-action="ShowLightningNodeInfo"app-top-items
|
||||||
asp-route-cryptoCode="@Model.CryptoCode"
|
asp-route-cryptoCode="@Model.CryptoCode"
|
||||||
asp-route-storeId="@Model.Store.Id"
|
asp-route-storeId="@Model.Store.Id"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
id="PublicNodeInfo">
|
id="PublicNodeInfo"
|
||||||
|
text-translate="true">
|
||||||
Node Info
|
Node Info
|
||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
{
|
{
|
||||||
<div class="store-number">
|
<div class="store-number">
|
||||||
<header>
|
<header>
|
||||||
<h6>Paid invoices in the last @Model.TimeframeDays days</h6>
|
<h6 text-translate="true">@ViewLocalizer["Paid invoices in the last {0} days", @Model.TimeframeDays]</h6>
|
||||||
@if (Model.PaidInvoices > 0)
|
@if (Model.PaidInvoices > 0)
|
||||||
{
|
{
|
||||||
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanViewInvoices">View All</a>
|
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanViewInvoices">View All</a>
|
||||||
@@ -34,14 +34,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="store-number">
|
<div class="store-number">
|
||||||
<header>
|
<header>
|
||||||
<h6>Payouts Pending</h6>
|
<h6 text-translate="true">Payouts Pending</h6>
|
||||||
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanManagePullPayments">Manage</a>
|
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.Store.Id" permission="@Policies.CanManagePullPayments" text-translate="true">Manage</a>
|
||||||
</header>
|
</header>
|
||||||
<div class="h3">@Model.PayoutsPending</div>
|
<div class="h3">@Model.PayoutsPending</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="store-number">
|
<div class="store-number">
|
||||||
<header>
|
<header>
|
||||||
<h6>Refunds Issued</h6>
|
<h6 text-translate="true">Refunds Issued</h6>
|
||||||
</header>
|
</header>
|
||||||
<div class="h3">@Model.RefundsIssued</div>
|
<div class="h3">@Model.RefundsIssued</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,17 +6,17 @@
|
|||||||
|
|
||||||
<div class="widget store-recent-invoices" id="StoreRecentInvoices-@Model.Store.Id">
|
<div class="widget store-recent-invoices" id="StoreRecentInvoices-@Model.Store.Id">
|
||||||
<header>
|
<header>
|
||||||
<h3>Recent Invoices</h3>
|
<h3 text-translate="true">Recent Invoices</h3>
|
||||||
@if (Model.Invoices.Any())
|
@if (Model.Invoices.Any())
|
||||||
{
|
{
|
||||||
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id">View All</a>
|
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" text-translate="true">View All</a>
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
@if (Model.InitialRendering)
|
@if (Model.InitialRendering)
|
||||||
{
|
{
|
||||||
<div class="loading d-flex justify-content-center p-3">
|
<div class="loading d-flex justify-content-center p-3">
|
||||||
<div class="spinner-border text-light" role="status">
|
<div class="spinner-border text-light" role="status">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden" text-translate="true">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
<table class="table table-hover mb-0">
|
<table class="table table-hover mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-125px">Date</th>
|
<th class="w-125px" text-translate="true">Date</th>
|
||||||
<th class="text-nowrap">Invoice Id</th>
|
<th class="text-nowrap" text-translate="true">Invoice Id</th>
|
||||||
<th>Status</th>
|
<th text-translate="true">Status</th>
|
||||||
<th class="text-end">Amount</th>
|
<th class="text-end" text-translate="true">Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -65,10 +65,10 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p class="text-secondary my-3">
|
<p class="text-secondary my-3" text-translate="true">
|
||||||
There are no recent invoices.
|
There are no recent invoices.
|
||||||
</p>
|
</p>
|
||||||
<a asp-controller="UIInvoice" asp-action="CreateInvoice" asp-route-storeId="@Model.Store.Id" class="fw-semibold">
|
<a asp-controller="UIInvoice" asp-action="CreateInvoice" asp-route-storeId="@Model.Store.Id" class="fw-semibold" text-translate="true">
|
||||||
Create Invoice
|
Create Invoice
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
|
|
||||||
<div class="widget store-recent-transactions" id="StoreRecentTransactions-@Model.Store.Id">
|
<div class="widget store-recent-transactions" id="StoreRecentTransactions-@Model.Store.Id">
|
||||||
<header>
|
<header>
|
||||||
<h3>Recent Transactions</h3>
|
<h3 text-translate="true">Recent Transactions</h3>
|
||||||
@if (Model.Transactions.Any())
|
@if (Model.Transactions.Any())
|
||||||
{
|
{
|
||||||
<a asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@Model.WalletId">View All</a>
|
<a asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@Model.WalletId" text-translate="true">View All</a>
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
@if (Model.InitialRendering)
|
@if (Model.InitialRendering)
|
||||||
{
|
{
|
||||||
<div class="loading d-flex justify-content-center p-3">
|
<div class="loading d-flex justify-content-center p-3">
|
||||||
<div class="spinner-border text-light" role="status">
|
<div class="spinner-border text-light" role="status">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden" text-translate="true">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
<table class="table table-hover mb-0">
|
<table class="table table-hover mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-125px">Date</th>
|
<th class="w-125px" text-translate="true">Date</th>
|
||||||
<th>Transaction</th>
|
<th text-translate="true">Transaction</th>
|
||||||
<th>Labels</th>
|
<th text-translate="true">Labels</th>
|
||||||
<th class="text-end">Amount</th>
|
<th class="text-end" text-translate="true">Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p class="text-secondary mt-3 mb-0">
|
<p class="text-secondary mt-3 mb-0" text-translate="true">
|
||||||
There are no recent transactions.
|
There are no recent transactions.
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@inject BTCPayNetworkProvider NetworkProvider
|
@inject BTCPayNetworkProvider NetworkProvider
|
||||||
<div id="StoreWalletBalance-@Model.Store.Id" class="widget store-wallet-balance">
|
<div id="StoreWalletBalance-@Model.Store.Id" class="widget store-wallet-balance">
|
||||||
<div class="d-flex gap-3 align-items-center justify-content-between mb-2">
|
<div class="d-flex gap-3 align-items-center justify-content-between mb-2">
|
||||||
<h6>Wallet Balance</h6>
|
<h6 text-translate="true">Wallet Balance</h6>
|
||||||
@if (Model.CryptoCode != Model.DefaultCurrency)
|
@if (Model.CryptoCode != Model.DefaultCurrency)
|
||||||
{
|
{
|
||||||
<div class="btn-group btn-group-sm gap-0 currency-toggle" role="group">
|
<div class="btn-group btn-group-sm gap-0 currency-toggle" role="group">
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
{
|
{
|
||||||
<div class="ct-chart"></div>
|
<div class="ct-chart"></div>
|
||||||
}
|
}
|
||||||
else if (Model.Store.GetPaymentMethodConfig(PaymentTypes.CHAIN.GetPaymentMethodId(Model.CryptoCode)) is null)
|
else if (Model.Store.GetPaymentMethodConfig(PaymentTypes.CHAIN.GetPaymentMethodId(Model.CryptoCode)) is null)
|
||||||
{
|
{
|
||||||
<p>
|
<p>
|
||||||
We would like to show you a chart of your balance but you have not yet <a href="@Url.Action("SetupWallet", "UIStores", new {storeId = Model.Store.Id, cryptoCode = Model.CryptoCode})">configured a wallet</a>.
|
We would like to show you a chart of your balance but you have not yet <a href="@Url.Action("SetupWallet", "UIStores", new {storeId = Model.Store.Id, cryptoCode = Model.CryptoCode})">configured a wallet</a>.
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ using BTCPayServer.Services;
|
|||||||
using BTCPayServer.Services.Rates;
|
using BTCPayServer.Services.Rates;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using MarkPayoutRequest = BTCPayServer.HostedServices.MarkPayoutRequest;
|
using MarkPayoutRequest = BTCPayServer.HostedServices.MarkPayoutRequest;
|
||||||
using PayoutData = BTCPayServer.Data.PayoutData;
|
using PayoutData = BTCPayServer.Data.PayoutData;
|
||||||
@@ -50,7 +52,10 @@ namespace BTCPayServer.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IStringLocalizer StringLocalizer { get; }
|
||||||
|
|
||||||
public UIStorePullPaymentsController(BTCPayNetworkProvider btcPayNetworkProvider,
|
public UIStorePullPaymentsController(BTCPayNetworkProvider btcPayNetworkProvider,
|
||||||
|
IStringLocalizer stringLocalizer,
|
||||||
PayoutMethodHandlerDictionary payoutHandlers,
|
PayoutMethodHandlerDictionary payoutHandlers,
|
||||||
CurrencyNameTable currencyNameTable,
|
CurrencyNameTable currencyNameTable,
|
||||||
DisplayFormatter displayFormatter,
|
DisplayFormatter displayFormatter,
|
||||||
@@ -62,6 +67,7 @@ namespace BTCPayServer.Controllers
|
|||||||
IAuthorizationService authorizationService)
|
IAuthorizationService authorizationService)
|
||||||
{
|
{
|
||||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||||
|
StringLocalizer = stringLocalizer;
|
||||||
_payoutHandlers = payoutHandlers;
|
_payoutHandlers = payoutHandlers;
|
||||||
_currencyNameTable = currencyNameTable;
|
_currencyNameTable = currencyNameTable;
|
||||||
_displayFormatter = displayFormatter;
|
_displayFormatter = displayFormatter;
|
||||||
@@ -85,7 +91,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||||
{
|
{
|
||||||
Message = "You must enable at least one payment method before creating a pull payment.",
|
Message = StringLocalizer["You must enable at least one payment method before creating a pull payment."],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
||||||
@@ -119,25 +125,25 @@ namespace BTCPayServer.Controllers
|
|||||||
// them here to reflect user's selection so that they can correct their mistake
|
// them here to reflect user's selection so that they can correct their mistake
|
||||||
model.PayoutMethodsItem =
|
model.PayoutMethodsItem =
|
||||||
paymentMethodOptions.Select(id => new SelectListItem(id.ToString(), id.ToString(), false));
|
paymentMethodOptions.Select(id => new SelectListItem(id.ToString(), id.ToString(), false));
|
||||||
ModelState.AddModelError(nameof(model.PayoutMethods), "You need at least one payout method");
|
ModelState.AddModelError(nameof(model.PayoutMethods), StringLocalizer["You need at least one payout method"]);
|
||||||
}
|
}
|
||||||
if (_currencyNameTable.GetCurrencyData(model.Currency, false) is null)
|
if (_currencyNameTable.GetCurrencyData(model.Currency, false) is null)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(model.Currency), "Invalid currency");
|
ModelState.AddModelError(nameof(model.Currency), StringLocalizer["Invalid currency"]);
|
||||||
}
|
}
|
||||||
if (model.Amount <= 0.0m)
|
if (model.Amount <= 0.0m)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(model.Amount), "The amount should be more than zero");
|
ModelState.AddModelError(nameof(model.Amount), StringLocalizer["The amount should be more than zero"]);
|
||||||
}
|
}
|
||||||
if (model.Name.Length > 50)
|
if (model.Name.Length > 50)
|
||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(model.Name), "The name should be maximum 50 characters.");
|
ModelState.AddModelError(nameof(model.Name), StringLocalizer["The name should be maximum 50 characters."]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedPaymentMethodIds = model.PayoutMethods.Select(PayoutMethodId.Parse).ToArray();
|
var selectedPaymentMethodIds = model.PayoutMethods.Select(PayoutMethodId.Parse).ToArray();
|
||||||
if (!selectedPaymentMethodIds.All(id => paymentMethodOptions.Contains(id)))
|
if (!selectedPaymentMethodIds.All(id => paymentMethodOptions.Contains(id)))
|
||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(model.Name), "Not all payout methods are supported");
|
ModelState.AddModelError(nameof(model.Name), StringLocalizer["Not all payout methods are supported"]);
|
||||||
}
|
}
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return View(model);
|
return View(model);
|
||||||
@@ -156,7 +162,7 @@ namespace BTCPayServer.Controllers
|
|||||||
});
|
});
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||||
{
|
{
|
||||||
Message = "Pull payment request created",
|
Message = StringLocalizer["Pull payment request created"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Success
|
Severity = StatusMessageModel.StatusSeverity.Success
|
||||||
});
|
});
|
||||||
return RedirectToAction(nameof(PullPayments), new { storeId });
|
return RedirectToAction(nameof(PullPayments), new { storeId });
|
||||||
@@ -198,7 +204,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||||
{
|
{
|
||||||
Message = "You must enable at least one payment method before creating a pull payment.",
|
Message = StringLocalizer["You must enable at least one payment method before creating a pull payment."],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
||||||
@@ -260,7 +266,7 @@ namespace BTCPayServer.Controllers
|
|||||||
string pullPaymentId)
|
string pullPaymentId)
|
||||||
{
|
{
|
||||||
return View("Confirm",
|
return View("Confirm",
|
||||||
new ConfirmModel("Archive pull payment", "Do you really want to archive the pull payment?", "Archive"));
|
new ConfirmModel(StringLocalizer["Archive pull payment"], StringLocalizer["Do you really want to archive the pull payment?"], "Archive"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("stores/{storeId}/pull-payments/{pullPaymentId}/archive")]
|
[HttpPost("stores/{storeId}/pull-payments/{pullPaymentId}/archive")]
|
||||||
@@ -298,7 +304,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = "No payout selected",
|
Message = StringLocalizer["No payout selected"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
return RedirectToAction(nameof(Payouts),
|
return RedirectToAction(nameof(Payouts),
|
||||||
@@ -341,7 +347,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
this.TempData.SetStatusMessageModel(new StatusMessageModel()
|
this.TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = $"Rate unavailable: {rateResult.EvaluatedRule}",
|
Message = StringLocalizer["Rate unavailable: {0}", rateResult.EvaluatedRule],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
failed = true;
|
failed = true;
|
||||||
@@ -379,7 +385,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = "Payouts approved",
|
Message = StringLocalizer["Payouts approved"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Success
|
Severity = StatusMessageModel.StatusSeverity.Success
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -391,7 +397,7 @@ namespace BTCPayServer.Controllers
|
|||||||
return await handler.InitiatePayment(payoutIds);
|
return await handler.InitiatePayment(payoutIds);
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = "Paying via this payment method is not supported",
|
Message = StringLocalizer["Paying via this payment method is not supported"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -430,7 +436,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = "Payouts marked as paid",
|
Message = StringLocalizer["Payouts marked as paid"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Success
|
Severity = StatusMessageModel.StatusSeverity.Success
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -441,7 +447,7 @@ namespace BTCPayServer.Controllers
|
|||||||
new PullPaymentHostedService.CancelRequest(payoutIds, new[] { storeId }));
|
new PullPaymentHostedService.CancelRequest(payoutIds, new[] { storeId }));
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel()
|
TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||||
{
|
{
|
||||||
Message = "Payouts archived",
|
Message = StringLocalizer["Payouts archived"],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Success
|
Severity = StatusMessageModel.StatusSeverity.Success
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -482,7 +488,7 @@ namespace BTCPayServer.Controllers
|
|||||||
{
|
{
|
||||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||||
{
|
{
|
||||||
Message = "You must enable at least one payment method before creating a payout.",
|
Message = StringLocalizer["You must enable at least one payment method before creating a payout."],
|
||||||
Severity = StatusMessageModel.StatusSeverity.Error
|
Severity = StatusMessageModel.StatusSeverity.Error
|
||||||
});
|
});
|
||||||
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new { storeId });
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ public partial class UIStoresController
|
|||||||
vm.AvailableExchanges = sources;
|
vm.AvailableExchanges = sources;
|
||||||
var exchange = storeBlob.GetPreferredExchange(_defaultRules);
|
var exchange = storeBlob.GetPreferredExchange(_defaultRules);
|
||||||
var chosenSource = sources.First(r => r.Id == exchange);
|
var chosenSource = sources.First(r => r.Id == exchange);
|
||||||
vm.Exchanges = UIUserStoresController.GetExchangesSelectList(_rateFactory, _defaultRules, storeBlob);
|
vm.Exchanges = _userStoresController.GetExchangesSelectList(storeBlob);
|
||||||
vm.PreferredExchange = vm.Exchanges.SelectedValue as string;
|
vm.PreferredExchange = vm.Exchanges.SelectedValue as string;
|
||||||
vm.PreferredResolvedExchange = chosenSource.Id;
|
vm.PreferredResolvedExchange = chosenSource.Id;
|
||||||
vm.RateSource = chosenSource.Url;
|
vm.RateSource = chosenSource.Url;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public partial class UIStoresController : Controller
|
|||||||
DefaultRulesCollection defaultRules,
|
DefaultRulesCollection defaultRules,
|
||||||
EmailSenderFactory emailSenderFactory,
|
EmailSenderFactory emailSenderFactory,
|
||||||
WalletFileParsers onChainWalletParsers,
|
WalletFileParsers onChainWalletParsers,
|
||||||
|
UIUserStoresController userStoresController,
|
||||||
UriResolver uriResolver,
|
UriResolver uriResolver,
|
||||||
SettingsRepository settingsRepository,
|
SettingsRepository settingsRepository,
|
||||||
CurrencyNameTable currencyNameTable,
|
CurrencyNameTable currencyNameTable,
|
||||||
@@ -82,6 +83,7 @@ public partial class UIStoresController : Controller
|
|||||||
_externalServiceOptions = externalServiceOptions;
|
_externalServiceOptions = externalServiceOptions;
|
||||||
_emailSenderFactory = emailSenderFactory;
|
_emailSenderFactory = emailSenderFactory;
|
||||||
_onChainWalletParsers = onChainWalletParsers;
|
_onChainWalletParsers = onChainWalletParsers;
|
||||||
|
_userStoresController = userStoresController;
|
||||||
_uriResolver = uriResolver;
|
_uriResolver = uriResolver;
|
||||||
_settingsRepository = settingsRepository;
|
_settingsRepository = settingsRepository;
|
||||||
_currencyNameTable = currencyNameTable;
|
_currencyNameTable = currencyNameTable;
|
||||||
@@ -115,6 +117,7 @@ public partial class UIStoresController : Controller
|
|||||||
private readonly IOptions<ExternalServicesOptions> _externalServiceOptions;
|
private readonly IOptions<ExternalServicesOptions> _externalServiceOptions;
|
||||||
private readonly EmailSenderFactory _emailSenderFactory;
|
private readonly EmailSenderFactory _emailSenderFactory;
|
||||||
private readonly WalletFileParsers _onChainWalletParsers;
|
private readonly WalletFileParsers _onChainWalletParsers;
|
||||||
|
private readonly UIUserStoresController _userStoresController;
|
||||||
private readonly UriResolver _uriResolver;
|
private readonly UriResolver _uriResolver;
|
||||||
private readonly EventAggregator _eventAggregator;
|
private readonly EventAggregator _eventAggregator;
|
||||||
private readonly IHtmlHelper _html;
|
private readonly IHtmlHelper _html;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Abstractions.Constants;
|
using BTCPayServer.Abstractions.Constants;
|
||||||
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Abstractions.Models;
|
using BTCPayServer.Abstractions.Models;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
@@ -12,7 +13,9 @@ using BTCPayServer.Services.Stores;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Localization;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers
|
namespace BTCPayServer.Controllers
|
||||||
{
|
{
|
||||||
@@ -21,6 +24,7 @@ namespace BTCPayServer.Controllers
|
|||||||
public class UIUserStoresController : Controller
|
public class UIUserStoresController : Controller
|
||||||
{
|
{
|
||||||
private readonly StoreRepository _repo;
|
private readonly StoreRepository _repo;
|
||||||
|
private readonly IStringLocalizer StringLocalizer;
|
||||||
private readonly SettingsRepository _settingsRepository;
|
private readonly SettingsRepository _settingsRepository;
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly DefaultRulesCollection _defaultRules;
|
private readonly DefaultRulesCollection _defaultRules;
|
||||||
@@ -31,10 +35,12 @@ namespace BTCPayServer.Controllers
|
|||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
DefaultRulesCollection defaultRules,
|
DefaultRulesCollection defaultRules,
|
||||||
StoreRepository storeRepository,
|
StoreRepository storeRepository,
|
||||||
|
IStringLocalizer stringLocalizer,
|
||||||
RateFetcher rateFactory,
|
RateFetcher rateFactory,
|
||||||
SettingsRepository settingsRepository)
|
SettingsRepository settingsRepository)
|
||||||
{
|
{
|
||||||
_repo = storeRepository;
|
_repo = storeRepository;
|
||||||
|
StringLocalizer = stringLocalizer;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_defaultRules = defaultRules;
|
_defaultRules = defaultRules;
|
||||||
_rateFactory = rateFactory;
|
_rateFactory = rateFactory;
|
||||||
@@ -95,7 +101,7 @@ namespace BTCPayServer.Controllers
|
|||||||
store.SetStoreBlob(blob);
|
store.SetStoreBlob(blob);
|
||||||
await _repo.CreateStore(GetUserId(), store);
|
await _repo.CreateStore(GetUserId(), store);
|
||||||
CreatedStoreId = store.Id;
|
CreatedStoreId = store.Id;
|
||||||
TempData[WellKnownTempData.SuccessMessage] = "Store successfully created";
|
TempData.SetStatusSuccess(StringLocalizer["Store successfully created"]);
|
||||||
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new
|
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new
|
||||||
{
|
{
|
||||||
storeId = store.Id
|
storeId = store.Id
|
||||||
@@ -109,7 +115,7 @@ namespace BTCPayServer.Controllers
|
|||||||
var store = HttpContext.GetStoreData();
|
var store = HttpContext.GetStoreData();
|
||||||
if (store == null)
|
if (store == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return View("Confirm", new ConfirmModel($"Delete store {store.StoreName}", "This store will still be accessible to users sharing it", "Delete"));
|
return View("Confirm", new ConfirmModel(StringLocalizer["Delete store {0}", store.StoreName], StringLocalizer["This store will still be accessible to users sharing it"], "Delete"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{storeId}/me/delete")]
|
[HttpPost("{storeId}/me/delete")]
|
||||||
@@ -121,24 +127,23 @@ namespace BTCPayServer.Controllers
|
|||||||
if (store == null)
|
if (store == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await _repo.RemoveStore(storeId, userId);
|
await _repo.RemoveStore(storeId, userId);
|
||||||
TempData[WellKnownTempData.SuccessMessage] = "Store removed successfully";
|
TempData.SetStatusSuccess(StringLocalizer["Store removed successfully"]);
|
||||||
return RedirectToAction(nameof(UIHomeController.Index), "UIHome");
|
return RedirectToAction(nameof(UIHomeController.Index), "UIHome");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetUserId() => _userManager.GetUserId(User);
|
private string GetUserId() => _userManager.GetUserId(User);
|
||||||
|
|
||||||
private SelectList GetExchangesSelectList(StoreBlob storeBlob) => GetExchangesSelectList(_rateFactory, _defaultRules, storeBlob);
|
internal SelectList GetExchangesSelectList(StoreBlob storeBlob)
|
||||||
internal static SelectList GetExchangesSelectList(RateFetcher rateFetcher, DefaultRulesCollection defaultRules, StoreBlob storeBlob)
|
|
||||||
{
|
{
|
||||||
if (storeBlob is null)
|
if (storeBlob is null)
|
||||||
storeBlob = new StoreBlob();
|
storeBlob = new StoreBlob();
|
||||||
var defaultExchange = defaultRules.GetRecommendedExchange(storeBlob.DefaultCurrency);
|
var defaultExchange = _defaultRules.GetRecommendedExchange(storeBlob.DefaultCurrency);
|
||||||
var exchanges = rateFetcher.RateProviderFactory
|
var exchanges = _rateFactory.RateProviderFactory
|
||||||
.AvailableRateProviders
|
.AvailableRateProviders
|
||||||
.OrderBy(s => s.Id, StringComparer.OrdinalIgnoreCase)
|
.OrderBy(s => s.Id, StringComparer.OrdinalIgnoreCase)
|
||||||
.ToList();
|
.ToList();
|
||||||
var exchange = exchanges.First(e => e.Id == defaultExchange);
|
var exchange = exchanges.First(e => e.Id == defaultExchange);
|
||||||
exchanges.Insert(0, new(null, $"Recommendation ({exchange.DisplayName})", ""));
|
exchanges.Insert(0, new(null, StringLocalizer["Recommendation ({0})", exchange.DisplayName], ""));
|
||||||
var chosen = exchanges.FirstOrDefault(f => f.Id == storeBlob.PreferredExchange) ?? exchanges.First();
|
var chosen = exchanges.FirstOrDefault(f => f.Id == storeBlob.PreferredExchange) ?? exchanges.First();
|
||||||
return new SelectList(exchanges, nameof(chosen.Id), nameof(chosen.DisplayName), chosen.Id);
|
return new SelectList(exchanges, nameof(chosen.Id), nameof(chosen.DisplayName), chosen.Id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ using BTCPayServer.Payments.Bitcoin;
|
|||||||
using BTCPayServer.Payments.Lightning;
|
using BTCPayServer.Payments.Lightning;
|
||||||
using BTCPayServer.Payouts;
|
using BTCPayServer.Payouts;
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using BTCPayServer.Services.Reporting;
|
using BTCPayServer.Services.Reporting;
|
||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
@@ -291,7 +292,17 @@ namespace BTCPayServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
public static IServiceCollection AddDefaultTransactions(this IServiceCollection services, params string[] keyValues)
|
||||||
|
{
|
||||||
|
return services.AddDefaultTransactions(keyValues.Select(k => KeyValuePair.Create<string, string?>(k, string.Empty)).ToArray());
|
||||||
|
}
|
||||||
|
public static IServiceCollection AddDefaultTransactions(this IServiceCollection services, params KeyValuePair<string, string?>[] keyValues)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IDefaultTransactionProvider>(new InMemoryDefaultTransactionProvider(keyValues));
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
#nullable restore
|
||||||
public static IServiceCollection AddUIExtension(this IServiceCollection services, string location, string partialViewName)
|
public static IServiceCollection AddUIExtension(this IServiceCollection services, string location, string partialViewName)
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
|
|||||||
@@ -631,6 +631,7 @@ o.GetRequiredService<IEnumerable<IPaymentLinkExtension>>().ToDictionary(o => o.P
|
|||||||
(IPaymentLinkExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentLinkExtension), new object[] { network, pmi }));
|
(IPaymentLinkExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentLinkExtension), new object[] { network, pmi }));
|
||||||
services.AddSingleton<ICheckoutModelExtension>(provider =>
|
services.AddSingleton<ICheckoutModelExtension>(provider =>
|
||||||
(BitcoinCheckoutModelExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinCheckoutModelExtension), new object[] { network, pmi }));
|
(BitcoinCheckoutModelExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinCheckoutModelExtension), new object[] { network, pmi }));
|
||||||
|
services.AddDefaultTransactions(network.DisplayName);
|
||||||
services.AddSingleton<IPaymentMethodBitpayAPIExtension>(provider =>
|
services.AddSingleton<IPaymentMethodBitpayAPIExtension>(provider =>
|
||||||
(IPaymentMethodBitpayAPIExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentMethodBitpayAPIExtension), new object[] { pmi }));
|
(IPaymentMethodBitpayAPIExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentMethodBitpayAPIExtension), new object[] { pmi }));
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using BTCPayServer.Models.InvoicingModels;
|
|||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.DataEncoders;
|
using NBitcoin.DataEncoders;
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
public const string CheckoutBodyComponentName = "BitcoinCheckoutBody";
|
public const string CheckoutBodyComponentName = "BitcoinCheckoutBody";
|
||||||
private readonly PaymentMethodHandlerDictionary _handlers;
|
private readonly PaymentMethodHandlerDictionary _handlers;
|
||||||
private readonly BTCPayNetwork _Network;
|
private readonly BTCPayNetwork _Network;
|
||||||
|
private readonly IStringLocalizer StringLocalizer;
|
||||||
private readonly DisplayFormatter _displayFormatter;
|
private readonly DisplayFormatter _displayFormatter;
|
||||||
private readonly IPaymentLinkExtension paymentLinkExtension;
|
private readonly IPaymentLinkExtension paymentLinkExtension;
|
||||||
private readonly IPaymentLinkExtension? lnPaymentLinkExtension;
|
private readonly IPaymentLinkExtension? lnPaymentLinkExtension;
|
||||||
@@ -26,6 +28,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
public BitcoinCheckoutModelExtension(
|
public BitcoinCheckoutModelExtension(
|
||||||
PaymentMethodId paymentMethodId,
|
PaymentMethodId paymentMethodId,
|
||||||
BTCPayNetwork network,
|
BTCPayNetwork network,
|
||||||
|
IStringLocalizer stringLocalizer,
|
||||||
IEnumerable<IPaymentLinkExtension> paymentLinkExtensions,
|
IEnumerable<IPaymentLinkExtension> paymentLinkExtensions,
|
||||||
DisplayFormatter displayFormatter,
|
DisplayFormatter displayFormatter,
|
||||||
PaymentMethodHandlerDictionary handlers)
|
PaymentMethodHandlerDictionary handlers)
|
||||||
@@ -33,6 +36,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
PaymentMethodId = paymentMethodId;
|
PaymentMethodId = paymentMethodId;
|
||||||
_handlers = handlers;
|
_handlers = handlers;
|
||||||
_Network = network;
|
_Network = network;
|
||||||
|
StringLocalizer = stringLocalizer;
|
||||||
_displayFormatter = displayFormatter;
|
_displayFormatter = displayFormatter;
|
||||||
paymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId);
|
paymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId);
|
||||||
var lnPmi = PaymentTypes.LN.GetPaymentMethodId(network.CryptoCode);
|
var lnPmi = PaymentTypes.LN.GetPaymentMethodId(network.CryptoCode);
|
||||||
@@ -41,7 +45,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
lnurlPaymentLinkExtension = paymentLinkExtensions.SingleOrDefault(p => p.PaymentMethodId == lnurlPmi);
|
lnurlPaymentLinkExtension = paymentLinkExtensions.SingleOrDefault(p => p.PaymentMethodId == lnurlPmi);
|
||||||
_bech32Prefix = network.NBitcoinNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, false) is { } enc ? Encoders.ASCII.EncodeData(enc.HumanReadablePart) : null;
|
_bech32Prefix = network.NBitcoinNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, false) is { } enc ? Encoders.ASCII.EncodeData(enc.HumanReadablePart) : null;
|
||||||
}
|
}
|
||||||
public string DisplayName => _Network.DisplayName;
|
public string DisplayName => StringLocalizer[_Network.DisplayName];
|
||||||
public string Image => _Network.CryptoImagePath;
|
public string Image => _Network.CryptoImagePath;
|
||||||
public string Badge => "";
|
public string Badge => "";
|
||||||
public PaymentMethodId PaymentMethodId { get; }
|
public PaymentMethodId PaymentMethodId { get; }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using BTCPayServer.Services;
|
|||||||
using Org.BouncyCastle.Crypto.Modes.Gcm;
|
using Org.BouncyCastle.Crypto.Modes.Gcm;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
namespace BTCPayServer.Payments.Lightning
|
namespace BTCPayServer.Payments.Lightning
|
||||||
{
|
{
|
||||||
@@ -14,27 +15,31 @@ namespace BTCPayServer.Payments.Lightning
|
|||||||
public const string CheckoutBodyComponentName = "LightningCheckoutBody";
|
public const string CheckoutBodyComponentName = "LightningCheckoutBody";
|
||||||
private readonly DisplayFormatter _displayFormatter;
|
private readonly DisplayFormatter _displayFormatter;
|
||||||
IPaymentLinkExtension _PaymentLinkExtension;
|
IPaymentLinkExtension _PaymentLinkExtension;
|
||||||
|
private readonly bool isBTC;
|
||||||
|
|
||||||
public LNCheckoutModelExtension(
|
public LNCheckoutModelExtension(
|
||||||
PaymentMethodId paymentMethodId,
|
PaymentMethodId paymentMethodId,
|
||||||
BTCPayNetwork network,
|
BTCPayNetwork network,
|
||||||
DisplayFormatter displayFormatter,
|
DisplayFormatter displayFormatter,
|
||||||
IEnumerable<IPaymentLinkExtension> paymentLinkExtensions,
|
IEnumerable<IPaymentLinkExtension> paymentLinkExtensions,
|
||||||
|
IStringLocalizer stringLocalizer,
|
||||||
PaymentMethodHandlerDictionary handlers)
|
PaymentMethodHandlerDictionary handlers)
|
||||||
{
|
{
|
||||||
Network = network;
|
Network = network;
|
||||||
_displayFormatter = displayFormatter;
|
_displayFormatter = displayFormatter;
|
||||||
|
StringLocalizer = stringLocalizer;
|
||||||
Handlers = handlers;
|
Handlers = handlers;
|
||||||
PaymentMethodId = paymentMethodId;
|
PaymentMethodId = paymentMethodId;
|
||||||
_PaymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId);
|
_PaymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId);
|
||||||
var isBTC = PaymentTypes.LN.GetPaymentMethodId("BTC") == paymentMethodId;
|
isBTC = PaymentTypes.LN.GetPaymentMethodId("BTC") == paymentMethodId;
|
||||||
DisplayName = isBTC ? "Lightning" : $"Lightning ({Network.DisplayName})";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BTCPayNetwork Network { get; }
|
public BTCPayNetwork Network { get; }
|
||||||
|
public IStringLocalizer StringLocalizer { get; }
|
||||||
public PaymentMethodHandlerDictionary Handlers { get; }
|
public PaymentMethodHandlerDictionary Handlers { get; }
|
||||||
public PaymentMethodId PaymentMethodId { get; }
|
public PaymentMethodId PaymentMethodId { get; }
|
||||||
|
|
||||||
public string DisplayName { get; }
|
public string DisplayName => isBTC ? StringLocalizer["Lightning"] : StringLocalizer["Lightning ({0})", Network.DisplayName];
|
||||||
|
|
||||||
public string Image => Network.LightningImagePath;
|
public string Image => Network.LightningImagePath;
|
||||||
public string Badge => "⚡";
|
public string Badge => "⚡";
|
||||||
@@ -50,7 +55,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||||||
if (context.Model.InvoiceBitcoinUrl is not null)
|
if (context.Model.InvoiceBitcoinUrl is not null)
|
||||||
context.Model.InvoiceBitcoinUrlQR = $"lightning:{context.Model.InvoiceBitcoinUrl.ToUpperInvariant()?.Substring("LIGHTNING:".Length)}";
|
context.Model.InvoiceBitcoinUrlQR = $"lightning:{context.Model.InvoiceBitcoinUrl.ToUpperInvariant()?.Substring("LIGHTNING:".Length)}";
|
||||||
context.Model.PeerInfo = handler.ParsePaymentPromptDetails(paymentPrompt.Details).NodeInfo;
|
context.Model.PeerInfo = handler.ParsePaymentPromptDetails(paymentPrompt.Details).NodeInfo;
|
||||||
if (context.StoreBlob.LightningAmountInSatoshi && context.Model.PaymentMethodCurrency == "BTC")
|
if (context.StoreBlob.LightningAmountInSatoshi && isBTC)
|
||||||
{
|
{
|
||||||
BitcoinCheckoutModelExtension.PreparePaymentModelForAmountInSats(context.Model, paymentPrompt.Rate, _displayFormatter);
|
BitcoinCheckoutModelExtension.PreparePaymentModelForAmountInSats(context.Model, paymentPrompt.Rate, _displayFormatter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,16 +19,35 @@ using static BTCPayServer.Services.LocalizerService;
|
|||||||
|
|
||||||
namespace BTCPayServer.Services
|
namespace BTCPayServer.Services
|
||||||
{
|
{
|
||||||
|
public interface IDefaultTransactionProvider
|
||||||
|
{
|
||||||
|
Task<KeyValuePair<string, string?>[]> GetDefaultTransaction();
|
||||||
|
}
|
||||||
|
public class InMemoryDefaultTransactionProvider : IDefaultTransactionProvider
|
||||||
|
{
|
||||||
|
private readonly KeyValuePair<string, string?>[] _values;
|
||||||
|
|
||||||
|
public InMemoryDefaultTransactionProvider(KeyValuePair<string, string?>[] values)
|
||||||
|
{
|
||||||
|
_values = values;
|
||||||
|
}
|
||||||
|
public Task<KeyValuePair<string, string?>[]> GetDefaultTransaction()
|
||||||
|
{
|
||||||
|
return Task.FromResult(_values);
|
||||||
|
}
|
||||||
|
}
|
||||||
public class LocalizerService
|
public class LocalizerService
|
||||||
{
|
{
|
||||||
public LocalizerService(
|
public LocalizerService(
|
||||||
ILogger<LocalizerService> logger,
|
ILogger<LocalizerService> logger,
|
||||||
ApplicationDbContextFactory contextFactory,
|
ApplicationDbContextFactory contextFactory,
|
||||||
ISettingsAccessor<PoliciesSettings> settingsAccessor)
|
ISettingsAccessor<PoliciesSettings> settingsAccessor,
|
||||||
|
IEnumerable<IDefaultTransactionProvider> defaultTransactionProviders)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_ContextFactory = contextFactory;
|
_ContextFactory = contextFactory;
|
||||||
_settingsAccessor = settingsAccessor;
|
_settingsAccessor = settingsAccessor;
|
||||||
|
_defaultTransactionProviders = defaultTransactionProviders;
|
||||||
_LoadedTranslations = new LoadedTranslations(Translations.Default, Translations.Default, Translations.DefaultLanguage);
|
_LoadedTranslations = new LoadedTranslations(Translations.Default, Translations.Default, Translations.DefaultLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +58,7 @@ namespace BTCPayServer.Services
|
|||||||
private readonly ILogger<LocalizerService> _logger;
|
private readonly ILogger<LocalizerService> _logger;
|
||||||
private readonly ApplicationDbContextFactory _ContextFactory;
|
private readonly ApplicationDbContextFactory _ContextFactory;
|
||||||
private readonly ISettingsAccessor<PoliciesSettings> _settingsAccessor;
|
private readonly ISettingsAccessor<PoliciesSettings> _settingsAccessor;
|
||||||
|
private readonly IEnumerable<IDefaultTransactionProvider> _defaultTransactionProviders;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load the translation of the server into memory
|
/// Load the translation of the server into memory
|
||||||
@@ -69,7 +89,18 @@ namespace BTCPayServer.Services
|
|||||||
{
|
{
|
||||||
dict_id = dictionaryName,
|
dict_id = dictionaryName,
|
||||||
});
|
});
|
||||||
var fallback = new Translations(all.Where(a => a.fallback).Select(o => KeyValuePair.Create(o.sentence, o.translation)), Translations.Default);
|
var defaultDict = Translations.Default;
|
||||||
|
var loading = _defaultTransactionProviders.Select(d => d.GetDefaultTransaction()).ToArray();
|
||||||
|
Dictionary<string, string?> additionalDefault = new();
|
||||||
|
foreach (var defaultProvider in loading)
|
||||||
|
{
|
||||||
|
foreach (var kv in await defaultProvider)
|
||||||
|
{
|
||||||
|
additionalDefault.TryAdd(kv.Key, string.IsNullOrEmpty(kv.Value) ? kv.Key : kv.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultDict = new Translations(additionalDefault, defaultDict);
|
||||||
|
var fallback = new Translations(all.Where(a => a.fallback).Select(o => KeyValuePair.Create(o.sentence, o.translation)), defaultDict);
|
||||||
var translations = new Translations(all.Where(a => !a.fallback).Select(o => KeyValuePair.Create(o.sentence, o.translation)), fallback);
|
var translations = new Translations(all.Where(a => !a.fallback).Select(o => KeyValuePair.Create(o.sentence, o.translation)), fallback);
|
||||||
return new LoadedTranslations(translations, fallback, dictionaryName);
|
return new LoadedTranslations(translations, fallback, dictionaryName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,17 @@ namespace BTCPayServer.Services
|
|||||||
{
|
{
|
||||||
"... on every payment": "",
|
"... on every payment": "",
|
||||||
"... only if the customer makes more than one payment for the invoice": "",
|
"... only if the customer makes more than one payment for the invoice": "",
|
||||||
|
"<span class=\"currency\">{0}</span> closing channels": "",
|
||||||
|
"<span class=\"currency\">{0}</span> confirmed": "",
|
||||||
|
"<span class=\"currency\">{0}</span> in channels": "",
|
||||||
|
"<span class=\"currency\">{0}</span> local balance": "",
|
||||||
|
"<span class=\"currency\">{0}</span> on-chain": "",
|
||||||
|
"<span class=\"currency\">{0}</span> opening channels": "",
|
||||||
|
"<span class=\"currency\">{0}</span> remote balance": "",
|
||||||
|
"<span class=\"currency\">{0}</span> reserved": "",
|
||||||
|
"<span class=\"currency\">{0}</span> unconfirmed": "",
|
||||||
"A given currency pair match the most specific rule. If two rules are matching and are as specific, the first rule will be chosen.": "",
|
"A given currency pair match the most specific rule. If two rules are matching and are as specific, the first rule will be chosen.": "",
|
||||||
|
"A self-hosted, open-source bitcoin payment processor.": "",
|
||||||
"Access Tokens": "",
|
"Access Tokens": "",
|
||||||
"Account": "",
|
"Account": "",
|
||||||
"Account key": "",
|
"Account key": "",
|
||||||
@@ -48,6 +58,7 @@ namespace BTCPayServer.Services
|
|||||||
"Application": "",
|
"Application": "",
|
||||||
"Apply the brand color to the store's backend as well": "",
|
"Apply the brand color to the store's backend as well": "",
|
||||||
"Approve": "",
|
"Approve": "",
|
||||||
|
"Archive pull payment": "",
|
||||||
"Archive this store": "",
|
"Archive this store": "",
|
||||||
"At Least One": "",
|
"At Least One": "",
|
||||||
"At Least Ten": "",
|
"At Least Ten": "",
|
||||||
@@ -62,6 +73,7 @@ namespace BTCPayServer.Services
|
|||||||
"blocks": "",
|
"blocks": "",
|
||||||
"Brand Color": "",
|
"Brand Color": "",
|
||||||
"Branding": "",
|
"Branding": "",
|
||||||
|
"BTCPay Server currently supports:": "",
|
||||||
"But now, what if you want to support <code>DOGE</code>? The problem with <code>DOGE</code> is that most exchange do not have any pair for it. But <code>bitpay</code> has a <code>DOGE_BTC</code> pair. <br />\r\n Luckily, the rule engine allow you to reference rules:": "",
|
"But now, what if you want to support <code>DOGE</code>? The problem with <code>DOGE</code> is that most exchange do not have any pair for it. But <code>bitpay</code> has a <code>DOGE_BTC</code> pair. <br />\r\n Luckily, the rule engine allow you to reference rules:": "",
|
||||||
"Buyer Email": "",
|
"Buyer Email": "",
|
||||||
"Callback Notification URL": "",
|
"Callback Notification URL": "",
|
||||||
@@ -79,6 +91,8 @@ namespace BTCPayServer.Services
|
|||||||
"Confirm password": "",
|
"Confirm password": "",
|
||||||
"Connect an existing wallet": "",
|
"Connect an existing wallet": "",
|
||||||
"Connect hardware wallet": "",
|
"Connect hardware wallet": "",
|
||||||
|
"Connect to a Lightning node": "",
|
||||||
|
"Connection configuration for your custom Lightning node:": "",
|
||||||
"Connection string": "",
|
"Connection string": "",
|
||||||
"Consider the invoice paid even if the paid amount is … % less than expected": "",
|
"Consider the invoice paid even if the paid amount is … % less than expected": "",
|
||||||
"Consider the invoice settled when the payment transaction …": "",
|
"Consider the invoice settled when the payment transaction …": "",
|
||||||
@@ -89,6 +103,7 @@ namespace BTCPayServer.Services
|
|||||||
"Create": "",
|
"Create": "",
|
||||||
"Create a new app": "",
|
"Create a new app": "",
|
||||||
"Create a new wallet": "",
|
"Create a new wallet": "",
|
||||||
|
"Create account": "",
|
||||||
"Create Account": "",
|
"Create Account": "",
|
||||||
"Create Form": "",
|
"Create Form": "",
|
||||||
"Create Invoice": "",
|
"Create Invoice": "",
|
||||||
@@ -97,6 +112,7 @@ namespace BTCPayServer.Services
|
|||||||
"Create Store": "",
|
"Create Store": "",
|
||||||
"Create Webhook": "",
|
"Create Webhook": "",
|
||||||
"Create your account": "",
|
"Create your account": "",
|
||||||
|
"Create your store": "",
|
||||||
"Crowdfund": "",
|
"Crowdfund": "",
|
||||||
"Currency": "",
|
"Currency": "",
|
||||||
"Current password": "",
|
"Current password": "",
|
||||||
@@ -107,18 +123,21 @@ namespace BTCPayServer.Services
|
|||||||
"Custom Theme Extension Type": "",
|
"Custom Theme Extension Type": "",
|
||||||
"Custom Theme File": "",
|
"Custom Theme File": "",
|
||||||
"Dashboard": "",
|
"Dashboard": "",
|
||||||
|
"Date": "",
|
||||||
"days": "",
|
"days": "",
|
||||||
"Default currency": "",
|
"Default currency": "",
|
||||||
"Default Currency Pairs": "",
|
"Default Currency Pairs": "",
|
||||||
"Default language on checkout": "",
|
"Default language on checkout": "",
|
||||||
"Default payment method on checkout": "",
|
"Default payment method on checkout": "",
|
||||||
"Default role for users on a new store": "",
|
"Default role for users on a new store": "",
|
||||||
|
"Delete store {0}": "",
|
||||||
"Delete this store": "",
|
"Delete this store": "",
|
||||||
"Derivation scheme": "",
|
"Derivation scheme": "",
|
||||||
"Derivation scheme format": "",
|
"Derivation scheme format": "",
|
||||||
"Description": "",
|
"Description": "",
|
||||||
"Description template of the lightning invoice": "",
|
"Description template of the lightning invoice": "",
|
||||||
"Destination Address": "",
|
"Destination Address": "",
|
||||||
|
"Details": "",
|
||||||
"Dictionaries": "",
|
"Dictionaries": "",
|
||||||
"Dictionaries enable you to translate the BTCPay Server backend into different languages.": "",
|
"Dictionaries enable you to translate the BTCPay Server backend into different languages.": "",
|
||||||
"Dictionary": "",
|
"Dictionary": "",
|
||||||
@@ -136,10 +155,14 @@ namespace BTCPayServer.Services
|
|||||||
"Display Title": "",
|
"Display Title": "",
|
||||||
"Disqus Shortname": "",
|
"Disqus Shortname": "",
|
||||||
"Do not allow additional contributions after target has been reached": "",
|
"Do not allow additional contributions after target has been reached": "",
|
||||||
|
"Do not photograph it. Do not store it digitally.": "",
|
||||||
|
"Do not photograph the recovery phrase, and do not store it digitally.": "",
|
||||||
|
"Do you really want to archive the pull payment?": "",
|
||||||
"Does not extend a BTCPay Server theme, fully custom": "",
|
"Does not extend a BTCPay Server theme, fully custom": "",
|
||||||
"Domain": "",
|
"Domain": "",
|
||||||
"Domain name": "",
|
"Domain name": "",
|
||||||
"Don't create UTXO change": "",
|
"Don't create UTXO change": "",
|
||||||
|
"Done": "",
|
||||||
"Email": "",
|
"Email": "",
|
||||||
"Email address": "",
|
"Email address": "",
|
||||||
"Email confirmation required": "",
|
"Email confirmation required": "",
|
||||||
@@ -188,27 +211,40 @@ namespace BTCPayServer.Services
|
|||||||
"However, explicitely setting specific pairs like this can be a bit difficult. Instead, you can define a rule <code>X_X</code> which will match any currency pair. The following example will use <code>kraken</code> for getting the rate of any currency pair.": "",
|
"However, explicitely setting specific pairs like this can be a bit difficult. Instead, you can define a rule <code>X_X</code> which will match any currency pair. The following example will use <code>kraken</code> for getting the rate of any currency pair.": "",
|
||||||
"I don't have a wallet": "",
|
"I don't have a wallet": "",
|
||||||
"I have a wallet": "",
|
"I have a wallet": "",
|
||||||
|
"I have written down my recovery phrase and stored it in a secure location": "",
|
||||||
"If a translation isn’t available in the new dictionary, it will be searched in the fallback.": "",
|
"If a translation isn’t available in the new dictionary, it will be searched in the fallback.": "",
|
||||||
|
"If you lose it or write it down incorrectly, you may permanently lose access to your funds.": "",
|
||||||
|
"If you lose it or write it down incorrectly, you will permanently lose access to your funds.": "",
|
||||||
"Image": "",
|
"Image": "",
|
||||||
"Import {0} Wallet": "",
|
"Import {0} Wallet": "",
|
||||||
"Import an existing hardware or software wallet": "",
|
"Import an existing hardware or software wallet": "",
|
||||||
"Import wallet file": "",
|
"Import wallet file": "",
|
||||||
"Import your public keys using our Vault application": "",
|
"Import your public keys using our Vault application": "",
|
||||||
"Input the key string manually": "",
|
"Input the key string manually": "",
|
||||||
|
"Invalid currency": "",
|
||||||
"Invitation URL": "",
|
"Invitation URL": "",
|
||||||
"Invoice currency": "",
|
"Invoice currency": "",
|
||||||
"Invoice expires if the full amount has not been paid after …": "",
|
"Invoice expires if the full amount has not been paid after …": "",
|
||||||
|
"Invoice Id": "",
|
||||||
"Invoice metadata": "",
|
"Invoice metadata": "",
|
||||||
"Invoices": "",
|
"Invoices": "",
|
||||||
"Is administrator?": "",
|
"Is administrator?": "",
|
||||||
"Is signing key": "",
|
"Is signing key": "",
|
||||||
"Is unconfirmed": "",
|
"Is unconfirmed": "",
|
||||||
|
"It is secure, private, censorship-resistant and free.": "",
|
||||||
"It is worth noting that the inverses of those pairs are automatically supported as well.<br />\r\n It means that the rule <code>USD_DOGE = 1 / DOGE_USD</code> implicitely exists.": "",
|
"It is worth noting that the inverses of those pairs are automatically supported as well.<br />\r\n It means that the rule <code>USD_DOGE = 1 / DOGE_USD</code> implicitely exists.": "",
|
||||||
"Item Description": "",
|
"Item Description": "",
|
||||||
"Keypad": "",
|
"Keypad": "",
|
||||||
|
"Labels": "",
|
||||||
"Let's get started": "",
|
"Let's get started": "",
|
||||||
|
"Lightning": "",
|
||||||
|
"Lightning ({0})": "",
|
||||||
|
"Lightning Address": "",
|
||||||
|
"Lightning Balance": "",
|
||||||
"Lightning node (LNURL Auth)": "",
|
"Lightning node (LNURL Auth)": "",
|
||||||
|
"Lightning Services": "",
|
||||||
"LNURL Classic Mode": "",
|
"LNURL Classic Mode": "",
|
||||||
|
"Loading...": "",
|
||||||
"Local File System": "",
|
"Local File System": "",
|
||||||
"Log in": "",
|
"Log in": "",
|
||||||
"Login Codes": "",
|
"Login Codes": "",
|
||||||
@@ -217,6 +253,7 @@ namespace BTCPayServer.Services
|
|||||||
"Logs": "",
|
"Logs": "",
|
||||||
"Maintenance": "",
|
"Maintenance": "",
|
||||||
"Make Crowdfund Public": "",
|
"Make Crowdfund Public": "",
|
||||||
|
"Manage": "",
|
||||||
"Manage Account": "",
|
"Manage Account": "",
|
||||||
"Manage Plugins": "",
|
"Manage Plugins": "",
|
||||||
"Master fingerprint": "",
|
"Master fingerprint": "",
|
||||||
@@ -228,11 +265,15 @@ namespace BTCPayServer.Services
|
|||||||
"Never add network fee": "",
|
"Never add network fee": "",
|
||||||
"New password": "",
|
"New password": "",
|
||||||
"Next": "",
|
"Next": "",
|
||||||
|
"No payout selected": "",
|
||||||
|
"No scope": "",
|
||||||
|
"Node Info": "",
|
||||||
"Non-admins can access the User Creation API Endpoint": "",
|
"Non-admins can access the User Creation API Endpoint": "",
|
||||||
"Non-admins can create Hot Wallets for their Store": "",
|
"Non-admins can create Hot Wallets for their Store": "",
|
||||||
"Non-admins can import Hot Wallets for their Store": "",
|
"Non-admins can import Hot Wallets for their Store": "",
|
||||||
"Non-admins can use the Internal Lightning Node for their Store": "",
|
"Non-admins can use the Internal Lightning Node for their Store": "",
|
||||||
"Non-admins cannot access the User Creation API Endpoint": "",
|
"Non-admins cannot access the User Creation API Endpoint": "",
|
||||||
|
"Not all payout methods are supported": "",
|
||||||
"Not recommended": "",
|
"Not recommended": "",
|
||||||
"Notification Email": "",
|
"Notification Email": "",
|
||||||
"Notification URL": "",
|
"Notification URL": "",
|
||||||
@@ -241,18 +282,27 @@ namespace BTCPayServer.Services
|
|||||||
"Optional seed passphrase": "",
|
"Optional seed passphrase": "",
|
||||||
"Order Id": "",
|
"Order Id": "",
|
||||||
"Override the block explorers used": "",
|
"Override the block explorers used": "",
|
||||||
|
"Paid invoices in the last {0} days": "",
|
||||||
"Pair to": "",
|
"Pair to": "",
|
||||||
"Password": "",
|
"Password": "",
|
||||||
"Password (leave blank to generate invite-link)": "",
|
"Password (leave blank to generate invite-link)": "",
|
||||||
"Pay Button": "",
|
"Pay Button": "",
|
||||||
|
"Paying via this payment method is not supported": "",
|
||||||
"PayJoin BIP21": "",
|
"PayJoin BIP21": "",
|
||||||
"Payment": "",
|
"Payment": "",
|
||||||
"Payment invalid if transactions fails to confirm … after invoice expiration": "",
|
"Payment invalid if transactions fails to confirm … after invoice expiration": "",
|
||||||
|
"Payment Requests": "",
|
||||||
"Payments": "",
|
"Payments": "",
|
||||||
"Payout Methods": "",
|
"Payout Methods": "",
|
||||||
"Payout Processors": "",
|
"Payout Processors": "",
|
||||||
"Payouts": "",
|
"Payouts": "",
|
||||||
|
"Payouts approved": "",
|
||||||
|
"Payouts archived": "",
|
||||||
|
"Payouts marked as paid": "",
|
||||||
|
"Payouts Pending": "",
|
||||||
|
"Permissions": "",
|
||||||
"Please enable JavaScript for this option to be available": "",
|
"Please enable JavaScript for this option to be available": "",
|
||||||
|
"Please make sure to also write down your passphrase.": "",
|
||||||
"Please note that creating a hot wallet is not supported by this instance for non administrators.": "",
|
"Please note that creating a hot wallet is not supported by this instance for non administrators.": "",
|
||||||
"Plugin server": "",
|
"Plugin server": "",
|
||||||
"Plugins": "",
|
"Plugins": "",
|
||||||
@@ -261,6 +311,7 @@ namespace BTCPayServer.Services
|
|||||||
"Policies": "",
|
"Policies": "",
|
||||||
"Preferred Price Source": "",
|
"Preferred Price Source": "",
|
||||||
"Print display": "",
|
"Print display": "",
|
||||||
|
"Process approved payouts instantly": "",
|
||||||
"Product list": "",
|
"Product list": "",
|
||||||
"Product list with cart": "",
|
"Product list with cart": "",
|
||||||
"Profile Picture": "",
|
"Profile Picture": "",
|
||||||
@@ -268,15 +319,22 @@ namespace BTCPayServer.Services
|
|||||||
"PSBT content": "",
|
"PSBT content": "",
|
||||||
"PSBT to combine with…": "",
|
"PSBT to combine with…": "",
|
||||||
"Public Key": "",
|
"Public Key": "",
|
||||||
|
"Pull payment request created": "",
|
||||||
"Pull Payments": "",
|
"Pull Payments": "",
|
||||||
"Rate Rules": "",
|
"Rate Rules": "",
|
||||||
"Rate script allows you to express precisely how you want to calculate rates for currency pairs.": "",
|
"Rate script allows you to express precisely how you want to calculate rates for currency pairs.": "",
|
||||||
|
"Rate unavailable: {0}": "",
|
||||||
"Rates": "",
|
"Rates": "",
|
||||||
|
"Receive": "",
|
||||||
|
"Recent Invoices": "",
|
||||||
|
"Recent Transactions": "",
|
||||||
|
"Recommendation ({0})": "",
|
||||||
"Recommended": "",
|
"Recommended": "",
|
||||||
"Recommended fee confirmation target blocks": "",
|
"Recommended fee confirmation target blocks": "",
|
||||||
"Recovery Code": "",
|
"Recovery Code": "",
|
||||||
"Redirect invoice to redirect url automatically after paid": "",
|
"Redirect invoice to redirect url automatically after paid": "",
|
||||||
"Redirect URL": "",
|
"Redirect URL": "",
|
||||||
|
"Refunds Issued": "",
|
||||||
"Register": "",
|
"Register": "",
|
||||||
"Remember me": "",
|
"Remember me": "",
|
||||||
"Remember this machine": "",
|
"Remember this machine": "",
|
||||||
@@ -298,10 +356,12 @@ namespace BTCPayServer.Services
|
|||||||
"Scope": "",
|
"Scope": "",
|
||||||
"Scripting": "",
|
"Scripting": "",
|
||||||
"Search engines can index this site": "",
|
"Search engines can index this site": "",
|
||||||
|
"Secure your recovery phrase": "",
|
||||||
"Security device (FIDO2)": "",
|
"Security device (FIDO2)": "",
|
||||||
"Select": "",
|
"Select": "",
|
||||||
"Select the Default Currency during Store Creation": "",
|
"Select the Default Currency during Store Creation": "",
|
||||||
"Select the payout method used for refund": "",
|
"Select the payout method used for refund": "",
|
||||||
|
"Send": "",
|
||||||
"Send invitation email": "",
|
"Send invitation email": "",
|
||||||
"Send test webhook": "",
|
"Send test webhook": "",
|
||||||
"Server Name": "",
|
"Server Name": "",
|
||||||
@@ -309,6 +369,8 @@ namespace BTCPayServer.Services
|
|||||||
"Services": "",
|
"Services": "",
|
||||||
"Set Password": "",
|
"Set Password": "",
|
||||||
"Set to default settings": "",
|
"Set to default settings": "",
|
||||||
|
"Set up a Lightning node": "",
|
||||||
|
"Set up a wallet": "",
|
||||||
"Settings": "",
|
"Settings": "",
|
||||||
"Setup {0} Wallet": "",
|
"Setup {0} Wallet": "",
|
||||||
"Shop Name": "",
|
"Shop Name": "",
|
||||||
@@ -326,28 +388,46 @@ namespace BTCPayServer.Services
|
|||||||
"Specify the amount and currency for the refund": "",
|
"Specify the amount and currency for the refund": "",
|
||||||
"Start date": "",
|
"Start date": "",
|
||||||
"Starting index": "",
|
"Starting index": "",
|
||||||
|
"Status": "",
|
||||||
"Store": "",
|
"Store": "",
|
||||||
"Store Id": "",
|
"Store Id": "",
|
||||||
"Store Name": "",
|
"Store Name": "",
|
||||||
|
"Store removed successfully": "",
|
||||||
"Store Settings": "",
|
"Store Settings": "",
|
||||||
"Store Speed Policy": "",
|
"Store Speed Policy": "",
|
||||||
|
"Store successfully created": "",
|
||||||
"Store Website": "",
|
"Store Website": "",
|
||||||
|
"Store: {0}": "",
|
||||||
"Submit": "",
|
"Submit": "",
|
||||||
"Subtract fees from amount": "",
|
"Subtract fees from amount": "",
|
||||||
"Support URL": "",
|
"Support URL": "",
|
||||||
"Supported by BlueWallet, Cobo Vault, Passport and Specter DIY": "",
|
"Supported by BlueWallet, Cobo Vault, Passport and Specter DIY": "",
|
||||||
"Supported Transaction Currencies": "",
|
"Supported Transaction Currencies": "",
|
||||||
"Target Amount": "",
|
"Target Amount": "",
|
||||||
|
"Test connection": "",
|
||||||
"Test Email": "",
|
"Test Email": "",
|
||||||
"Test Results:": "",
|
"Test Results:": "",
|
||||||
"Testing": "",
|
"Testing": "",
|
||||||
"Text to display in the tip input": "",
|
"Text to display in the tip input": "",
|
||||||
"Text to display on buttons allowing the user to enter a custom amount": "",
|
"Text to display on buttons allowing the user to enter a custom amount": "",
|
||||||
"Text to display on each button for items with a specific price": "",
|
"Text to display on each button for items with a specific price": "",
|
||||||
|
"The amount should be more than zero": "",
|
||||||
|
"The combination of words below are called your recovery phrase.\r\n The recovery phrase allows you to access and restore your wallet.\r\n Write them down on a piece of paper in the exact order:": "",
|
||||||
"The following methods assume that you already have an existing wallet created and backed up.": "",
|
"The following methods assume that you already have an existing wallet created and backed up.": "",
|
||||||
|
"The name should be maximum 50 characters.": "",
|
||||||
|
"The recommended price source gets chosen based on the default currency.": "",
|
||||||
|
"The recovery phrase is a backup that allows you to restore your wallet in case of a server crash.": "",
|
||||||
|
"The recovery phrase will also be stored on the server as a hot wallet.": "",
|
||||||
|
"The recovery phrase will be permanently erased from the server.": "",
|
||||||
"The script language is composed of several rules composed of a currency pair and a mathematic expression.\r\n The example below will use <code>kraken</code> for both <code>LTC_USD</code> and <code>BTC_USD</code> pairs.": "",
|
"The script language is composed of several rules composed of a currency pair and a mathematic expression.\r\n The example below will use <code>kraken</code> for both <code>LTC_USD</code> and <code>BTC_USD</code> pairs.": "",
|
||||||
"Theme": "",
|
"Theme": "",
|
||||||
|
"There are no recent invoices.": "",
|
||||||
|
"There are no recent transactions.": "",
|
||||||
|
"This store is ready to accept transactions, good job!": "",
|
||||||
|
"This store will still be accessible to users sharing it": "",
|
||||||
"Tip percentage amounts (comma separated)": "",
|
"Tip percentage amounts (comma separated)": "",
|
||||||
|
"To start accepting payments, set up a wallet or a Lightning node.": "",
|
||||||
|
"Transaction": "",
|
||||||
"Translations": "",
|
"Translations": "",
|
||||||
"Two-Factor Authentication": "",
|
"Two-Factor Authentication": "",
|
||||||
"Unarchive this store": "",
|
"Unarchive this store": "",
|
||||||
@@ -357,14 +437,19 @@ namespace BTCPayServer.Services
|
|||||||
"Upload a file exported from your wallet": "",
|
"Upload a file exported from your wallet": "",
|
||||||
"Upload PSBT from file…": "",
|
"Upload PSBT from file…": "",
|
||||||
"Url of the Dynamic DNS service you are using": "",
|
"Url of the Dynamic DNS service you are using": "",
|
||||||
|
"Use custom node": "",
|
||||||
"Use custom theme": "",
|
"Use custom theme": "",
|
||||||
|
"Use internal node": "",
|
||||||
"Use SSL": "",
|
"Use SSL": "",
|
||||||
"User can input custom amount": "",
|
"User can input custom amount": "",
|
||||||
"User can input discount in %": "",
|
"User can input discount in %": "",
|
||||||
"Users": "",
|
"Users": "",
|
||||||
|
"Using the BTCPay Server internal node for this store requires no further configuration. Click the save button below to start accepting Bitcoin through the Lightning Network.": "",
|
||||||
"UTXOs to spend from": "",
|
"UTXOs to spend from": "",
|
||||||
"Verification Code": "",
|
"Verification Code": "",
|
||||||
|
"View All": "",
|
||||||
"View-Only Wallet File": "",
|
"View-Only Wallet File": "",
|
||||||
|
"Wallet Balance": "",
|
||||||
"Wallet file": "",
|
"Wallet file": "",
|
||||||
"Wallet file content": "",
|
"Wallet file content": "",
|
||||||
"Wallet Keys File": "",
|
"Wallet Keys File": "",
|
||||||
@@ -376,8 +461,12 @@ namespace BTCPayServer.Services
|
|||||||
"Webhooks": "",
|
"Webhooks": "",
|
||||||
"Welcome to {0}": "",
|
"Welcome to {0}": "",
|
||||||
"With <code>DOGE_USD</code> will be expanded to <code>bitpay(DOGE_BTC) * kraken(BTC_USD)</code>. And <code>DOGE_CAD</code> will be expanded to <code>bitpay(DOGE_BTC) * ndax(BTC_CAD)</code>. <br />\r\n However, we advise you to write it that way to increase coverage so that <code>DOGE_BTC</code> is also supported:": "",
|
"With <code>DOGE_USD</code> will be expanded to <code>bitpay(DOGE_BTC) * kraken(BTC_USD)</code>. And <code>DOGE_CAD</code> will be expanded to <code>bitpay(DOGE_BTC) * ndax(BTC_CAD)</code>. <br />\r\n However, we advise you to write it that way to increase coverage so that <code>DOGE_BTC</code> is also supported:": "",
|
||||||
|
"You must enable at least one payment method before creating a payout.": "",
|
||||||
|
"You must enable at least one payment method before creating a pull payment.": "",
|
||||||
|
"You need at least one payout method": "",
|
||||||
"You really should not type your seed into a device that is connected to the internet.": "",
|
"You really should not type your seed into a device that is connected to the internet.": "",
|
||||||
"Your dynamic DNS hostname": "",
|
"Your dynamic DNS hostname": "",
|
||||||
|
"Your instance administrator has disabled the use of the Internal node for non-admin users.": "",
|
||||||
"Zero Confirmation": ""
|
"Zero Confirmation": ""
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@model ErrorViewModel
|
@model ErrorViewModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Error";
|
ViewData["Title"] = ViewLocalizer["Error"];
|
||||||
}
|
}
|
||||||
|
|
||||||
<h1 class="text-danger">
|
<h1 class="text-danger">
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<li class="nav-item" permission="@Policies.CanModifyStoreSettings">
|
<li class="nav-item" permission="@Policies.CanModifyStoreSettings">
|
||||||
<a asp-area="" asp-controller="UILNURL" asp-action="EditLightningAddress" asp-route-storeId="@store.Id" class="nav-link @ViewData.ActivePageClass("LightningAddress", nameof(StoreNavPages))" id="StoreNav-LightningAddress">
|
<a asp-area="" asp-controller="UILNURL" asp-action="EditLightningAddress" asp-route-storeId="@store.Id" class="nav-link @ViewData.ActivePageClass("LightningAddress", nameof(StoreNavPages))" id="StoreNav-LightningAddress">
|
||||||
<vc:icon symbol="nav-lightning-address "/>
|
<vc:icon symbol="nav-lightning-address "/>
|
||||||
<span>Lightning Address</span>
|
<span text-translate="true">Lightning Address</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,8 @@
|
|||||||
@if (ViewBag.ShowLeadText)
|
@if (ViewBag.ShowLeadText)
|
||||||
{
|
{
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<span class="d-sm-block">A self-hosted, open-source bitcoin payment processor.</span>
|
<span class="d-sm-block" text-translate="true">A self-hosted, open-source bitcoin payment processor.</span>
|
||||||
<span class="d-sm-block">It is secure, private, censorship-resistant and free.</span>
|
<span class="d-sm-block" text-translate="true">It is secure, private, censorship-resistant and free.</span>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
@model CheatPermissionsViewModel
|
@model CheatPermissionsViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Permissions";
|
ViewData["Title"] = ViewLocalizer["Permissions"];
|
||||||
Layout = "_LayoutSignedOut";
|
Layout = "_LayoutSignedOut";
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Model.StoreId is not null)
|
@if (Model.StoreId is not null)
|
||||||
{
|
{
|
||||||
<h1>Store: @Model.StoreId</h1>
|
<h1 text-translate="true">@ViewLocalizer["Store: {0}", @Model.StoreId]</h1>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<h1>No scope</h1>
|
<h1 text-translate="true">No scope</h1>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@model RegisterViewModel
|
@model RegisterViewModel
|
||||||
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Create account";
|
ViewData["Title"] = ViewLocalizer["Create account"];
|
||||||
ViewBag.ShowLeadText = true;
|
ViewBag.ShowLeadText = true;
|
||||||
Layout = "_LayoutSignedOut";
|
Layout = "_LayoutSignedOut";
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="form-group mt-4">
|
<div class="form-group mt-4">
|
||||||
<button type="submit" class="btn btn-primary btn-lg w-100" id="RegisterButton">Create account</button>
|
<button type="submit" class="btn btn-primary btn-lg w-100" id="RegisterButton" text-translate="true">Create account</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -30,13 +30,13 @@
|
|||||||
<vc:icon symbol="warning" />
|
<vc:icon symbol="warning" />
|
||||||
</div>
|
</div>
|
||||||
<div class="lead text-center">
|
<div class="lead text-center">
|
||||||
<h1 class="text-center text-warning mb-3">
|
<h1 class="text-center text-warning mb-3" text-translate="true">
|
||||||
Secure your recovery phrase
|
Secure your recovery phrase
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lead text-center">
|
<div class="lead text-center">
|
||||||
<p class="mb-0">
|
<p class="mb-0" text-translate="true">
|
||||||
The combination of words below are called your recovery phrase.
|
The combination of words below are called your recovery phrase.
|
||||||
The recovery phrase allows you to access and restore your wallet.
|
The recovery phrase allows you to access and restore your wallet.
|
||||||
Write them down on a piece of paper in the exact order:
|
Write them down on a piece of paper in the exact order:
|
||||||
@@ -54,41 +54,41 @@
|
|||||||
@if (Model.IsStored)
|
@if (Model.IsStored)
|
||||||
{
|
{
|
||||||
<p>
|
<p>
|
||||||
<span>The recovery phrase is a backup that allows you to restore your wallet in case of a server crash.</span>
|
<span text-translate="true">The recovery phrase is a backup that allows you to restore your wallet in case of a server crash.</span>
|
||||||
<span>If you lose it or write it down incorrectly, you may permanently lose access to your funds.</span>
|
<span text-translate="true">If you lose it or write it down incorrectly, you may permanently lose access to your funds.</span>
|
||||||
<span>Do not photograph it. Do not store it digitally.</span>
|
<span text-translate="true">Do not photograph it. Do not store it digitally.</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-warning">
|
<p class="text-warning">
|
||||||
<strong>The recovery phrase will also be stored on the server as a hot wallet.</strong>
|
<strong text-translate="true">The recovery phrase will also be stored on the server as a hot wallet.</strong>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p>
|
<p>
|
||||||
<span>If you lose it or write it down incorrectly, you will permanently lose access to your funds.</span>
|
<span text-translate="true">If you lose it or write it down incorrectly, you will permanently lose access to your funds.</span>
|
||||||
<span>Do not photograph the recovery phrase, and do not store it digitally.</span>
|
<span text-translate="true">Do not photograph the recovery phrase, and do not store it digitally.</span>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<p class="text-warning">
|
<p class="text-warning">
|
||||||
<strong>The recovery phrase will be permanently erased from the server.</strong>
|
<strong text-translate="true">The recovery phrase will be permanently erased from the server.</strong>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
@if (!string.IsNullOrEmpty(Model.Passphrase))
|
@if (!string.IsNullOrEmpty(Model.Passphrase))
|
||||||
{
|
{
|
||||||
<p class="mt-3 mb-0">Please make sure to also write down your passphrase.</p>
|
<p class="mt-3 mb-0" text-translate="true">Please make sure to also write down your passphrase.</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if (Model.RequireConfirm)
|
@if (Model.RequireConfirm)
|
||||||
{
|
{
|
||||||
<form id="RecoveryConfirmation" action="@Url.EnsureLocal(Model.ReturnUrl, Context.Request)" class="position-relative d-flex align-items-start justify-content-center" style="padding:20px 0 100px" rel="noreferrer noopener">
|
<form id="RecoveryConfirmation" action="@Url.EnsureLocal(Model.ReturnUrl, Context.Request)" class="position-relative d-flex align-items-start justify-content-center" style="padding:20px 0 100px" rel="noreferrer noopener">
|
||||||
<label class="form-check-label lead order-2" for="confirm">I have written down my recovery phrase and stored it in a secure location</label>
|
<label class="form-check-label lead order-2" for="confirm" text-translate="true">I have written down my recovery phrase and stored it in a secure location</label>
|
||||||
<input type="checkbox" class="me-3 order-1 form-check-input" id="confirm" style="margin-top:.35rem;flex-shrink:0">
|
<input type="checkbox" class="me-3 order-1 form-check-input" id="confirm" style="margin-top:.35rem;flex-shrink:0">
|
||||||
<button type="submit" class="btn btn-primary btn-lg px-5 order-3" id="submit">Done</button>
|
<button type="submit" class="btn btn-primary btn-lg px-5 order-3" id="submit" text-translate="true">Done</button>
|
||||||
<button type="submit" class="btn btn-primary btn-lg px-5 order-3" disabled>Done</button>
|
<button type="submit" class="btn btn-primary btn-lg px-5 order-3" disabled text-translate="true">Done</button>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a href="@Url.EnsureLocal(Model.ReturnUrl, Context.Request)" class="btn btn-primary btn-lg mt-3 px-5 order-3" id="proceed" rel="noreferrer noopener">Done</a>
|
<a href="@Url.EnsureLocal(Model.ReturnUrl, Context.Request)" class="btn btn-primary btn-lg mt-3 px-5 order-3" id="proceed" rel="noreferrer noopener" text-translate="true">Done</a>
|
||||||
}
|
}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@model BTCPayServer.Models.NotificationViewModels.NotificationIndexViewModel
|
@model BTCPayServer.Models.NotificationViewModels.NotificationIndexViewModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Notifications";
|
ViewData["Title"] = ViewLocalizer["Notifications"];
|
||||||
string status = ViewBag.Status;
|
string status = ViewBag.Status;
|
||||||
var statusFilterCount = CountArrayFilter("type");
|
var statusFilterCount = CountArrayFilter("type");
|
||||||
var storesFilterCount = CountArrayFilter("storeid");
|
var storesFilterCount = CountArrayFilter("storeid");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
@model BTCPayServer.Models.PaymentRequestViewModels.ListPaymentRequestsViewModel
|
@model BTCPayServer.Models.PaymentRequestViewModels.ListPaymentRequestsViewModel
|
||||||
@{
|
@{
|
||||||
Layout = "_Layout";
|
Layout = "_Layout";
|
||||||
ViewData["Title"] = "Payment Requests";
|
ViewData["Title"] = ViewLocalizer["Payment Requests"];
|
||||||
var storeId = Context.GetStoreData().Id;
|
var storeId = Context.GetStoreData().Id;
|
||||||
var statusFilterCount = CountArrayFilter("status") + (HasBooleanFilter("includearchived") ? 1 : 0);
|
var statusFilterCount = CountArrayFilter("status") + (HasBooleanFilter("includearchived") ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
@using BTCPayServer.Client
|
@using BTCPayServer.Client
|
||||||
@model StoreDashboardViewModel
|
@model StoreDashboardViewModel
|
||||||
@{
|
@{
|
||||||
BTCPayServer.Plugins.PluginExceptionHandler.SetDisablePluginIfCrash(Context);
|
BTCPayServer.Plugins.PluginExceptionHandler.SetDisablePluginIfCrash(Context);
|
||||||
ViewData.SetActivePage(StoreNavPages.Dashboard, Model.StoreName, Model.StoreId);
|
ViewData.SetActivePage(StoreNavPages.Dashboard, Model.StoreName, Model.StoreId);
|
||||||
var store = ViewContext.HttpContext.GetStoreData();
|
var store = ViewContext.HttpContext.GetStoreData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,61 +50,61 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<div id="Dashboard" class="mt-4">
|
<div id="Dashboard" class="mt-4">
|
||||||
<vc:ui-extension-point location="dashboard" model="@Model"/>
|
<vc:ui-extension-point location="dashboard" model="@Model" />
|
||||||
@if (Model.WalletEnabled)
|
@if (Model.WalletEnabled)
|
||||||
{
|
{
|
||||||
<vc:store-wallet-balance store="@store"/>
|
<vc:store-wallet-balance store="@store" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="widget setup-guide">
|
<div class="widget setup-guide">
|
||||||
<header>
|
<header>
|
||||||
<h5 class="mb-4 text-muted">This store is ready to accept transactions, good job!</h5>
|
<h5 class="mb-4 text-muted" text-translate="true">This store is ready to accept transactions, good job!</h5>
|
||||||
</header>
|
</header>
|
||||||
<div class="list-group" id="SetupGuide">
|
<div class="list-group" id="SetupGuide">
|
||||||
<div class="list-group-item d-flex align-items-center" id="SetupGuide-LightningDone">
|
<div class="list-group-item d-flex align-items-center" id="SetupGuide-LightningDone">
|
||||||
<vc:icon symbol="done"/>
|
<vc:icon symbol="done" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0 text-success">Set up a Lightning node</h5>
|
<h5 class="mb-0 text-success" text-translate="true">Set up a Lightning node</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a asp-controller="UIStores" asp-action="SetupWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Wallet" class="list-group-item list-group-item-action d-flex align-items-center">
|
<a asp-controller="UIStores" asp-action="SetupWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Wallet" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
<vc:icon symbol="wallet-new"/>
|
<vc:icon symbol="wallet-new" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0">Set up a wallet</h5>
|
<h5 class="mb-0" text-translate="true">Set up a wallet</h5>
|
||||||
</div>
|
</div>
|
||||||
<vc:icon symbol="caret-right"/>
|
<vc:icon symbol="caret-right" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<vc:store-numbers vm="@(new StoreNumbersViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/>
|
<vc:store-numbers vm="@(new StoreNumbersViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" />
|
||||||
@if (Model.LightningEnabled)
|
@if (Model.LightningEnabled)
|
||||||
{
|
{
|
||||||
<vc:store-lightning-balance vm="@(new StoreLightningBalanceViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/>
|
<vc:store-lightning-balance vm="@(new StoreLightningBalanceViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" />
|
||||||
<vc:store-lightning-services vm="@(new StoreLightningServicesViewModel { Store = store, CryptoCode = Model.CryptoCode })" permission="@Policies.CanModifyServerSettings"/>
|
<vc:store-lightning-services vm="@(new StoreLightningServicesViewModel { Store = store, CryptoCode = Model.CryptoCode })" permission="@Policies.CanModifyServerSettings" />
|
||||||
}
|
}
|
||||||
@if (Model.WalletEnabled)
|
@if (Model.WalletEnabled)
|
||||||
{
|
{
|
||||||
<vc:store-recent-transactions vm="@(new StoreRecentTransactionsViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/>
|
<vc:store-recent-transactions vm="@(new StoreRecentTransactionsViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" />
|
||||||
}
|
}
|
||||||
<vc:store-recent-invoices vm="@(new StoreRecentInvoicesViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/>
|
<vc:store-recent-invoices vm="@(new StoreRecentInvoicesViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })" />
|
||||||
@foreach (var app in Model.Apps)
|
@foreach (var app in Model.Apps)
|
||||||
{
|
{
|
||||||
<vc:app-sales app-id="@app.Id" app-type="@app.AppType" />
|
<vc:app-sales app-id="@app.Id" app-type="@app.AppType" />
|
||||||
<vc:app-top-items app-id="@app.Id" app-type="@app.AppType" />
|
<vc:app-top-items app-id="@app.Id" app-type="@app.AppType" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p class="lead text-secondary mt-2">To start accepting payments, set up a wallet or a Lightning node.</p>
|
<p class="lead text-secondary mt-2" text-translate="true">To start accepting payments, set up a wallet or a Lightning node.</p>
|
||||||
|
|
||||||
<div class="list-group" id="SetupGuide">
|
<div class="list-group" id="SetupGuide">
|
||||||
<div class="list-group-item d-flex align-items-center" id="SetupGuide-StoreDone">
|
<div class="list-group-item d-flex align-items-center" id="SetupGuide-StoreDone">
|
||||||
<vc:icon symbol="done"/>
|
<vc:icon symbol="done" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0 text-success">Create your store</h5>
|
<h5 class="mb-0 text-success" text-translate="true">Create your store</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (Model.Network is BTCPayNetwork)
|
@if (Model.Network is BTCPayNetwork)
|
||||||
@@ -113,40 +113,41 @@ else
|
|||||||
@if (!Model.WalletEnabled)
|
@if (!Model.WalletEnabled)
|
||||||
{
|
{
|
||||||
<a asp-controller="UIStores" asp-action="SetupWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Wallet" class="list-group-item list-group-item-action d-flex align-items-center order-1">
|
<a asp-controller="UIStores" asp-action="SetupWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Wallet" class="list-group-item list-group-item-action d-flex align-items-center order-1">
|
||||||
<vc:icon symbol="wallet-new"/>
|
<vc:icon symbol="wallet-new" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0">Set up a wallet</h5>
|
<h5 class="mb-0" text-translate="true">Set up a wallet</h5>
|
||||||
</div>
|
</div>
|
||||||
<vc:icon symbol="caret-right"/>
|
<vc:icon symbol="caret-right" />
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="list-group-item d-flex align-items-center" id="SetupGuide-WalletDone">
|
<div class="list-group-item d-flex align-items-center" id="SetupGuide-WalletDone">
|
||||||
<vc:icon symbol="done"/>
|
<vc:icon symbol="done" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0 text-success">Set up a wallet</h5>
|
<h5 class="mb-0 text-success" text-translate="true">Set up a wallet</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if (Model.LightningSupported) {
|
@if (Model.LightningSupported)
|
||||||
|
{
|
||||||
if (!Model.LightningEnabled)
|
if (!Model.LightningEnabled)
|
||||||
{
|
{
|
||||||
<a asp-controller="UIStores" asp-action="SetupLightningNode" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Lightning" class="list-group-item list-group-item-action d-flex align-items-center order-1">
|
<a asp-controller="UIStores" asp-action="SetupLightningNode" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" id="SetupGuide-Lightning" class="list-group-item list-group-item-action d-flex align-items-center order-1">
|
||||||
<vc:icon symbol="wallet-new"/>
|
<vc:icon symbol="wallet-new" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0">Set up a Lightning node</h5>
|
<h5 class="mb-0" text-translate="true">Set up a Lightning node</h5>
|
||||||
</div>
|
</div>
|
||||||
<vc:icon symbol="caret-right"/>
|
<vc:icon symbol="caret-right" />
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="list-group-item d-flex align-items-center" id="SetupGuide-LightningDone">
|
<div class="list-group-item d-flex align-items-center" id="SetupGuide-LightningDone">
|
||||||
<vc:icon symbol="done"/>
|
<vc:icon symbol="done" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h5 class="mb-0 text-success">Set up a Lightning node</h5>
|
<h5 class="mb-0 text-success" text-translate="true">Set up a Lightning node</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@model LightningNodeViewModel
|
@model LightningNodeViewModel
|
||||||
@{
|
@{
|
||||||
Layout = "_LayoutWalletSetup.cshtml";
|
Layout = "_LayoutWalletSetup.cshtml";
|
||||||
ViewData.SetActivePage(StoreNavPages.LightningSettings, "Connect to a Lightning node", Context.GetStoreData().Id);
|
ViewData.SetActivePage(StoreNavPages.LightningSettings, StringLocalizer["Connect to a Lightning node"], Context.GetStoreData().Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@section PageHeadContent {
|
@section PageHeadContent {
|
||||||
@@ -28,10 +28,10 @@
|
|||||||
<form method="post" class="mt-n2 text-center">
|
<form method="post" class="mt-n2 text-center">
|
||||||
<div id="LightningNodeTypeTablist" class="nav btcpay-pills align-items-center justify-content-center mb-3" role="tablist">
|
<div id="LightningNodeTypeTablist" class="nav btcpay-pills align-items-center justify-content-center mb-3" role="tablist">
|
||||||
<input asp-for="LightningNodeType" value="@LightningNodeType.Internal" type="radio" id="LightningNodeType-@LightningNodeType.Internal" data-bs-toggle="pill" data-bs-target="#InternalSetup" role="tab" aria-controls="InternalSetup" aria-selected="@(Model.LightningNodeType == LightningNodeType.Internal ? "true" : "false")" class="@(Model.LightningNodeType == LightningNodeType.Internal ? "active" : "")" disabled="@(!Model.CanUseInternalNode)">
|
<input asp-for="LightningNodeType" value="@LightningNodeType.Internal" type="radio" id="LightningNodeType-@LightningNodeType.Internal" data-bs-toggle="pill" data-bs-target="#InternalSetup" role="tab" aria-controls="InternalSetup" aria-selected="@(Model.LightningNodeType == LightningNodeType.Internal ? "true" : "false")" class="@(Model.LightningNodeType == LightningNodeType.Internal ? "active" : "")" disabled="@(!Model.CanUseInternalNode)">
|
||||||
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Internal}")">Use internal node</label>
|
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Internal}")" text-translate="true">Use internal node</label>
|
||||||
|
|
||||||
<input asp-for="LightningNodeType" value="@LightningNodeType.Custom" type="radio" id="LightningNodeType-@LightningNodeType.Custom" data-bs-toggle="pill" data-bs-target="#CustomSetup" role="tab" aria-controls="CustomSetup" aria-selected="@(Model.LightningNodeType == LightningNodeType.Custom ? "true" : "false")" class="@(Model.LightningNodeType == LightningNodeType.Custom ? "active" : "")">
|
<input asp-for="LightningNodeType" value="@LightningNodeType.Custom" type="radio" id="LightningNodeType-@LightningNodeType.Custom" data-bs-toggle="pill" data-bs-target="#CustomSetup" role="tab" aria-controls="CustomSetup" aria-selected="@(Model.LightningNodeType == LightningNodeType.Custom ? "true" : "false")" class="@(Model.LightningNodeType == LightningNodeType.Custom ? "active" : "")">
|
||||||
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Custom}")">Use custom node</label>
|
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Custom}")" text-translate="true">Use custom node</label>
|
||||||
|
|
||||||
<vc:ui-extension-point location="ln-payment-method-setup-tabhead" model="@Model"/>
|
<vc:ui-extension-point location="ln-payment-method-setup-tabhead" model="@Model"/>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,24 +40,24 @@
|
|||||||
<div id="InternalSetup" class="pt-3 tab-pane fade @(Model.LightningNodeType == LightningNodeType.Internal ? "show active" : "")" role="tabpanel" aria-labelledby="LightningNodeType-@LightningNodeType.Internal">
|
<div id="InternalSetup" class="pt-3 tab-pane fade @(Model.LightningNodeType == LightningNodeType.Internal ? "show active" : "")" role="tabpanel" aria-labelledby="LightningNodeType-@LightningNodeType.Internal">
|
||||||
@if (Model.CanUseInternalNode)
|
@if (Model.CanUseInternalNode)
|
||||||
{
|
{
|
||||||
<p class="mb-4">Using the BTCPay Server internal node for this store requires no further configuration. Click the save button below to start accepting Bitcoin through the Lightning Network.</p>
|
<p class="mb-4" text-translate="true">Using the BTCPay Server internal node for this store requires no further configuration. Click the save button below to start accepting Bitcoin through the Lightning Network.</p>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<p class="mb-4">Your instance administrator has disabled the use of the Internal node for non-admin users.</p>
|
<p class="mb-4" text-translate="true">Your instance administrator has disabled the use of the Internal node for non-admin users.</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div id="CustomSetup" class="pt-3 tab-pane fade @(Model.LightningNodeType == LightningNodeType.Custom ? "show active" : "")" role="tabpanel" aria-labelledby="LightningNodeType-@LightningNodeType.Custom">
|
<div id="CustomSetup" class="pt-3 tab-pane fade @(Model.LightningNodeType == LightningNodeType.Custom ? "show active" : "")" role="tabpanel" aria-labelledby="LightningNodeType-@LightningNodeType.Custom">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="ConnectionString" class="form-label">Connection configuration for your custom Lightning node:</label>
|
<label asp-for="ConnectionString" class="form-label" text-translate="true">Connection configuration for your custom Lightning node:</label>
|
||||||
<div class="d-sm-flex">
|
<div class="d-sm-flex">
|
||||||
<input asp-for="ConnectionString" class="form-control mb-2 me-2" placeholder="type=…;server=…;" value="@(Model.LightningNodeType == LightningNodeType.Internal ? "" : Model.ConnectionString)"/>
|
<input asp-for="ConnectionString" class="form-control mb-2 me-2" placeholder="type=…;server=…;" value="@(Model.LightningNodeType == LightningNodeType.Internal ? "" : Model.ConnectionString)"/>
|
||||||
<button id="test" name="command" type="submit" value="test" class="btn btn-secondary text-nowrap mb-2">Test connection</button>
|
<button id="test" name="command" type="submit" value="test" class="btn btn-secondary text-nowrap mb-2" text-translate="true">Test connection</button>
|
||||||
</div>
|
</div>
|
||||||
<span asp-validation-for="ConnectionString" class="text-danger"></span>
|
<span asp-validation-for="ConnectionString" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<vc:ui-extension-point location="ln-payment-method-setup-custom" model="@Model"/>
|
<vc:ui-extension-point location="ln-payment-method-setup-custom" model="@Model"/>
|
||||||
<p class="mt-4 mb-2">BTCPay Server currently supports:</p>
|
<p class="mt-4 mb-2" text-translate="true">BTCPay Server currently supports:</p>
|
||||||
<div class="accordion" id="CustomNodeSupport">
|
<div class="accordion" id="CustomNodeSupport">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="CustomNodeCLightningHeader">
|
<h2 class="accordion-header" id="CustomNodeCLightningHeader">
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="PreferredExchange" class="form-label" data-required></label>
|
<label asp-for="PreferredExchange" class="form-label" data-required></label>
|
||||||
<select asp-for="PreferredExchange" asp-items="Model.Exchanges" class="form-select w-300px"></select>
|
<select asp-for="PreferredExchange" asp-items="Model.Exchanges" class="form-select w-300px"></select>
|
||||||
<div class="form-text mt-2 only-for-js">The recommended price source gets chosen based on the default currency.</div>
|
<div class="form-text mt-2 only-for-js" text-translate="true">The recommended price source gets chosen based on the default currency.</div>
|
||||||
<span asp-validation-for="PreferredExchange" class="text-danger"></span>
|
<span asp-validation-for="PreferredExchange" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mt-4">
|
<div class="form-group mt-4">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
@using Microsoft.AspNetCore.Routing;
|
@using Microsoft.AspNetCore.Routing;
|
||||||
@using BTCPayServer.Abstractions.Extensions;
|
@using BTCPayServer.Abstractions.Extensions;
|
||||||
@inject Microsoft.AspNetCore.Mvc.Localization.ViewLocalizer ViewLocalizer
|
@inject Microsoft.AspNetCore.Mvc.Localization.ViewLocalizer ViewLocalizer
|
||||||
|
@inject Microsoft.Extensions.Localization.IStringLocalizer StringLocalizer
|
||||||
@inject Safe Safe
|
@inject Safe Safe
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
@addTagHelper *, BTCPayServer
|
@addTagHelper *, BTCPayServer
|
||||||
|
|||||||
Reference in New Issue
Block a user