Compare commits
7 Commits
fqpjn3
...
pj/no-invo
Author | SHA1 | Date | |
---|---|---|---|
c1fe473cc7 | |||
d3923da8e4 | |||
eac4d54466 | |||
717836e9e0 | |||
8d1ec4b5c0 | |||
1ee5c82b8b | |||
c775c3cc78 |
@ -9,5 +9,7 @@ namespace BTCPayServer.Client.Models
|
||||
public string Address { get; set; }
|
||||
[JsonConverter(typeof(KeyPathJsonConverter))]
|
||||
public KeyPath KeyPath { get; set; }
|
||||
|
||||
public string PaymentLink { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ namespace BTCPayServer
|
||||
//precision 0: 10 = 0.00000010
|
||||
//precision 2: 10 = 0.00001000
|
||||
//precision 8: 10 = 10
|
||||
var money = new Money(cryptoInfoDue.ToDecimal(MoneyUnit.BTC) / decimal.Parse("1".PadRight(1 + 8 - Divisibility, '0')), MoneyUnit.BTC);
|
||||
return $"{base.GenerateBIP21(cryptoInfoAddress, money)}&assetid={AssetId}";
|
||||
var money = cryptoInfoDue is null? null: new Money(cryptoInfoDue.ToDecimal(MoneyUnit.BTC) / decimal.Parse("1".PadRight(1 + 8 - Divisibility, '0')), MoneyUnit.BTC);
|
||||
return $"{base.GenerateBIP21(cryptoInfoAddress, money)}{(money is null? "?": "&")}assetid={AssetId}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ namespace BTCPayServer
|
||||
|
||||
public virtual string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
|
||||
{
|
||||
return $"{UriScheme}:{cryptoInfoAddress}?amount={cryptoInfoDue.ToString(false, true)}";
|
||||
return $"{UriScheme}:{cryptoInfoAddress}{(cryptoInfoDue is null? string.Empty: $"?amount={cryptoInfoDue.ToString(false, true)}")}";
|
||||
}
|
||||
|
||||
public virtual List<TransactionInformation> FilterValidTransactions(List<TransactionInformation> transactionInformationSet)
|
||||
|
@ -225,7 +225,7 @@ namespace BTCPayServer.Tests
|
||||
|
||||
public void ClickOnAllSideMenus()
|
||||
{
|
||||
var links = Driver.FindElements(By.CssSelector(".nav .nav-link")).Select(c => c.GetAttribute("href")).ToList();
|
||||
var links = Driver.FindElements(By.CssSelector(".nav-pills .nav-link")).Select(c => c.GetAttribute("href")).ToList();
|
||||
Driver.AssertNoError();
|
||||
Assert.NotEmpty(links);
|
||||
foreach (var l in links)
|
||||
|
@ -240,7 +240,7 @@ namespace BTCPayServer.Tests
|
||||
Assert.True(valid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async Task EnsureSwaggerPermissionsDocumented()
|
||||
@ -252,7 +252,7 @@ namespace BTCPayServer.Tests
|
||||
|
||||
var description =
|
||||
"BTCPay Server supports authenticating and authorizing users through an API Key that is generated by them. Send the API Key as a header value to Authorization with the format: `token {token}`. For a smoother experience, you can generate a url that redirects users to an API key creation screen.\n\n The following permissions are available to the context of the user creating the API Key:\n\n#OTHERPERMISSIONS#\n\nThe following permissions are available if the user is an administrator:\n\n#SERVERPERMISSIONS#\n\nThe following permissions applies to all stores of the user, you can limit to a specific store with the following format: `btcpay.store.cancreateinvoice:6HSHAEU4iYWtjxtyRs9KyPjM9GAQp8kw2T9VWbGG1FnZ`:\n\n#STOREPERMISSIONS#\n\nNote that API Keys only limits permission of a user and can never expand it. If an API Key has the permission `btcpay.server.canmodifyserversettings` but that the user account creating this API Key is not administrator, the API Key will not be able to modify the server settings.\n";
|
||||
|
||||
|
||||
var storePolicies =
|
||||
ManageController.AddApiKeyViewModel.PermissionValueItem.PermissionDescriptions.Where(pair =>
|
||||
Policies.IsStorePolicy(pair.Key) && !pair.Key.EndsWith(":", StringComparison.InvariantCulture));
|
||||
@ -270,7 +270,7 @@ namespace BTCPayServer.Tests
|
||||
.Replace("#STOREPERMISSIONS#",
|
||||
string.Join("\n", storePolicies.Select(pair => $"* `{pair.Key}`: {pair.Value.Title}")));
|
||||
Logs.Tester.LogInformation(description);
|
||||
|
||||
|
||||
var sresp = Assert
|
||||
.IsType<JsonResult>(await tester.PayTester.GetController<HomeController>(acc.UserId, acc.StoreId)
|
||||
.Swagger()).Value.ToJson();
|
||||
@ -668,7 +668,7 @@ namespace BTCPayServer.Tests
|
||||
AssertPayoutLabel(info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Fast", "Fast")]
|
||||
@ -905,7 +905,7 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
await tester.ExplorerNode.SendToAddressAsync(
|
||||
BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest), Money.Coins(0.00005m));
|
||||
}, e => e.InvoiceId == invoice.Id && e.PaymentMethodId.PaymentType == LightningPaymentType.Instance);
|
||||
}, e => e.InvoiceId == invoice.Id && e.PaymentMethodId.PaymentType == LightningPaymentType.Instance );
|
||||
await tester.ExplorerNode.GenerateAsync(1);
|
||||
await Task.Delay(100); // wait a bit for payment to process before fetching new invoice
|
||||
var newInvoice = await user.BitPay.GetInvoiceAsync(invoice.Id);
|
||||
@ -2321,8 +2321,6 @@ namespace BTCPayServer.Tests
|
||||
{("[1,2,3]", new Dictionary<string, object>() {{string.Empty, "[1,2,3]"}})},
|
||||
{("{ \"key\": \"value\"}", new Dictionary<string, object>() {{"key", "value"}})},
|
||||
{("{ \"key\": true}", new Dictionary<string, object>() {{"key", "True"}})},
|
||||
// Duplicate keys should not crash things
|
||||
{("{ \"key\": true, \"key\": true}", new Dictionary<string, object>() {{"key", "True"}})},
|
||||
{
|
||||
("{ invalidjson file here}",
|
||||
new Dictionary<string, object>() {{String.Empty, "{ invalidjson file here}"}})
|
||||
@ -2332,17 +2330,6 @@ namespace BTCPayServer.Tests
|
||||
testCases.ForEach(tuple =>
|
||||
{
|
||||
Assert.Equal(tuple.expectedOutput, InvoiceController.PosDataParser.ParsePosData(tuple.input));
|
||||
JObject jobj = null;
|
||||
try
|
||||
{
|
||||
jobj = JObject.Parse(tuple.input);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
// If the posData is directly a jobject, it should parse the same as if it was a string with json encoded
|
||||
if (jobj != null)
|
||||
Assert.Equal(tuple.expectedOutput, InvoiceController.PosDataParser.ParsePosData(jobj));
|
||||
});
|
||||
}
|
||||
|
||||
@ -3142,7 +3129,7 @@ namespace BTCPayServer.Tests
|
||||
("\\test.com", false),
|
||||
("te\\st.com", false)
|
||||
};
|
||||
foreach (var t in tests)
|
||||
foreach(var t in tests)
|
||||
{
|
||||
Assert.Equal(t.Item2, t.Item1.IsValidFileName());
|
||||
}
|
||||
@ -3452,7 +3439,7 @@ namespace BTCPayServer.Tests
|
||||
var acc = tester.NewAccount();
|
||||
await acc.GrantAccessAsync(true);
|
||||
await acc.CreateStoreAsync();
|
||||
|
||||
|
||||
// Test if legacy DerivationStrategy column is converted to DerivationStrategies
|
||||
var store = await tester.PayTester.StoreRepository.FindStore(acc.StoreId);
|
||||
var xpub = "tpubDDmH1briYfZcTDMEc7uMEA5hinzjUTzR9yMC1drxTMeiWyw1VyCqTuzBke6df2sqbfw9QG6wbgTLF5yLjcXsZNaXvJMZLwNEwyvmiFWcLav";
|
||||
@ -3467,7 +3454,7 @@ namespace BTCPayServer.Tests
|
||||
Assert.Equal(derivation, v.AccountOriginal.ToString());
|
||||
Assert.Equal(xpub, v.SigningKey.ToString());
|
||||
Assert.Equal(xpub, v.GetSigningAccountKeySettings().AccountKey.ToString());
|
||||
|
||||
|
||||
await acc.RegisterLightningNodeAsync("BTC", LightningConnectionType.CLightning, true);
|
||||
store = await tester.PayTester.StoreRepository.FindStore(acc.StoreId);
|
||||
var lnMethod = store.GetSupportedPaymentMethods(tester.NetworkProvider).OfType<LightningSupportedPaymentMethod>().First();
|
||||
@ -3614,43 +3601,43 @@ namespace BTCPayServer.Tests
|
||||
|
||||
var settings = tester.PayTester.GetService<SettingsRepository>();
|
||||
var emailSenderFactory = tester.PayTester.GetService<EmailSenderFactory>();
|
||||
|
||||
|
||||
Assert.Null(await Assert.IsType<ServerEmailSender>(emailSenderFactory.GetEmailSender()).GetEmailSettings());
|
||||
Assert.Null(await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings());
|
||||
|
||||
|
||||
|
||||
await settings.UpdateSetting(new PoliciesSettings() { DisableStoresToUseServerEmailSettings = false });
|
||||
await settings.UpdateSetting(new EmailSettings()
|
||||
{
|
||||
From = "admin@admin.com",
|
||||
Login = "admin@admin.com",
|
||||
Password = "admin@admin.com",
|
||||
Port = 1234,
|
||||
Server = "admin.com",
|
||||
EnableSSL = true
|
||||
From = "admin@admin.com",
|
||||
Login = "admin@admin.com",
|
||||
Password = "admin@admin.com",
|
||||
Port = 1234,
|
||||
Server = "admin.com",
|
||||
EnableSSL = true
|
||||
});
|
||||
Assert.Equal("admin@admin.com", (await Assert.IsType<ServerEmailSender>(emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
||||
Assert.Equal("admin@admin.com", (await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||
Assert.Equal("admin@admin.com",(await Assert.IsType<ServerEmailSender>(emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
||||
Assert.Equal("admin@admin.com",(await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||
|
||||
await settings.UpdateSetting(new PoliciesSettings() { DisableStoresToUseServerEmailSettings = true });
|
||||
Assert.Equal("admin@admin.com", (await Assert.IsType<ServerEmailSender>(emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
||||
Assert.Equal("admin@admin.com",(await Assert.IsType<ServerEmailSender>(emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
||||
Assert.Null(await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings());
|
||||
|
||||
Assert.IsType<RedirectToActionResult>(await acc.GetController<StoresController>().Emails(acc.StoreId, new EmailsViewModel(new EmailSettings()
|
||||
{
|
||||
From = "store@store.com",
|
||||
From = "store@store.com",
|
||||
Login = "store@store.com",
|
||||
Password = "store@store.com",
|
||||
Port = 1234,
|
||||
Server = "store.com",
|
||||
EnableSSL = true
|
||||
}), ""));
|
||||
|
||||
Assert.Equal("store@store.com", (await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||
|
||||
Assert.Equal("store@store.com",(await Assert.IsType<StoreEmailSender>(emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,22 +16,23 @@ namespace BTCPayServer.Controllers
|
||||
public string StoreId { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Empty;
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{appId}/settings/crowdfund")]
|
||||
|
||||
[HttpGet]
|
||||
[Route("{appId}/settings/crowdfund")]
|
||||
public async Task<IActionResult> UpdateCrowdfund(string appId)
|
||||
{
|
||||
var app = await GetOwnedApp(appId, AppType.Crowdfund);
|
||||
if (app == null)
|
||||
return NotFound();
|
||||
var settings = app.GetSettings<CrowdfundSettings>();
|
||||
var vm = new UpdateCrowdfundViewModel
|
||||
var vm = new UpdateCrowdfundViewModel()
|
||||
{
|
||||
Title = settings.Title,
|
||||
StoreId = app.StoreDataId,
|
||||
StoreName = app.StoreData?.StoreName,
|
||||
Enabled = settings.Enabled,
|
||||
EnforceTargetAmount = settings.EnforceTargetAmount,
|
||||
StartDate = settings.StartDate,
|
||||
|
@ -97,11 +97,10 @@ namespace BTCPayServer.Controllers
|
||||
settings.DefaultView = settings.EnableShoppingCart ? PosViewType.Cart : settings.DefaultView;
|
||||
settings.EnableShoppingCart = false;
|
||||
|
||||
var vm = new UpdatePointOfSaleViewModel
|
||||
var vm = new UpdatePointOfSaleViewModel()
|
||||
{
|
||||
Id = appId,
|
||||
StoreId = app.StoreDataId,
|
||||
StoreName = app.StoreData?.StoreName,
|
||||
Title = settings.Title,
|
||||
DefaultView = settings.DefaultView,
|
||||
ShowCustomAmount = settings.ShowCustomAmount,
|
||||
@ -184,7 +183,7 @@ namespace BTCPayServer.Controllers
|
||||
var app = await GetOwnedApp(appId, AppType.PointOfSale);
|
||||
if (app == null)
|
||||
return NotFound();
|
||||
app.SetSettings(new PointOfSaleSettings
|
||||
app.SetSettings(new PointOfSaleSettings()
|
||||
{
|
||||
Title = vm.Title,
|
||||
DefaultView = vm.DefaultView,
|
||||
|
@ -11,6 +11,7 @@ using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Models.WalletViewModels;
|
||||
using BTCPayServer.Payments.PayJoin;
|
||||
using BTCPayServer.Payments.PayJoin.Sender;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Wallets;
|
||||
@ -122,9 +123,18 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var bip21 = network.GenerateBIP21(kpi.Address.ToString(), null);
|
||||
var allowedPayjoin = derivationScheme.IsHotWallet && Store.GetStoreBlob().PayJoinEnabled;
|
||||
if (allowedPayjoin)
|
||||
{
|
||||
bip21 +=
|
||||
$"?{PayjoinClient.BIP21EndpointKey}={Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new {cryptoCode}))}";
|
||||
}
|
||||
return Ok(new OnChainWalletAddressData()
|
||||
{
|
||||
Address = kpi.Address.ToString(),
|
||||
PaymentLink = bip21,
|
||||
KeyPath = kpi.KeyPath
|
||||
});
|
||||
}
|
||||
@ -323,7 +333,7 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
request.AddModelError(transactionRequest => transactionRequest.Destinations[index],
|
||||
"Amount must be specified or destination must be a BIP21 payment link, and greater than 0", this);
|
||||
}
|
||||
if (request.ProceedWithPayjoin && bip21?.UnknowParameters?.ContainsKey("pj") is true)
|
||||
if (request.ProceedWithPayjoin && bip21?.UnknowParameters?.ContainsKey(PayjoinClient.BIP21EndpointKey) is true)
|
||||
{
|
||||
payjoinOutputIndex = index;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ namespace BTCPayServer.Controllers
|
||||
ExpirationDate = invoice.ExpirationTime,
|
||||
MonitoringDate = invoice.MonitoringExpiration,
|
||||
Fiat = _CurrencyNameTable.DisplayFormatCurrency(invoice.Price, invoice.Currency),
|
||||
TaxIncluded = _CurrencyNameTable.DisplayFormatCurrency(invoice.Metadata.TaxIncluded.AsDecimal() ?? 0.0m, invoice.Currency),
|
||||
TaxIncluded = _CurrencyNameTable.DisplayFormatCurrency(invoice.Metadata.TaxIncluded ?? 0.0m, invoice.Currency),
|
||||
NotificationUrl = invoice.NotificationURL?.AbsoluteUri,
|
||||
RedirectUrl = invoice.RedirectURL?.AbsoluteUri,
|
||||
TypedMetadata = invoice.Metadata,
|
||||
@ -539,7 +539,7 @@ namespace BTCPayServer.Controllers
|
||||
Activated = paymentMethodDetails.Activated,
|
||||
CryptoCode = network.CryptoCode,
|
||||
RootPath = this.Request.PathBase.Value.WithTrailingSlash(),
|
||||
OrderId = invoice.Metadata.OrderId.AsString(),
|
||||
OrderId = invoice.Metadata.OrderId,
|
||||
InvoiceId = invoice.Id,
|
||||
DefaultLang = lang ?? invoice.DefaultLanguage ?? storeBlob.DefaultLang ?? "en",
|
||||
CustomCSSLink = storeBlob.CustomCSS,
|
||||
@ -556,7 +556,7 @@ namespace BTCPayServer.Controllers
|
||||
ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds),
|
||||
MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds,
|
||||
MaxTimeMinutes = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalMinutes,
|
||||
ItemDesc = invoice.Metadata.ItemDesc.AsString(),
|
||||
ItemDesc = invoice.Metadata.ItemDesc,
|
||||
Rate = ExchangeRate(paymentMethod),
|
||||
MerchantRefLink = invoice.RedirectURL?.AbsoluteUri ?? "/",
|
||||
RedirectAutomatically = invoice.RedirectAutomatically,
|
||||
@ -725,7 +725,7 @@ namespace BTCPayServer.Controllers
|
||||
ShowCheckout = invoice.Status == InvoiceStatusLegacy.New,
|
||||
Date = invoice.InvoiceTime,
|
||||
InvoiceId = invoice.Id,
|
||||
OrderId = invoice.Metadata.OrderId.AsString() ?? string.Empty,
|
||||
OrderId = invoice.Metadata.OrderId ?? string.Empty,
|
||||
RedirectUrl = invoice.RedirectURL?.AbsoluteUri ?? string.Empty,
|
||||
AmountCurrency = _CurrencyNameTable.DisplayFormatCurrency(invoice.Price, invoice.Currency),
|
||||
CanMarkInvalid = state.CanMarkInvalid(),
|
||||
@ -900,55 +900,42 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
public class PosDataParser
|
||||
{
|
||||
public static Dictionary<string, object> ParsePosData(JToken posData)
|
||||
public static Dictionary<string, object> ParsePosData(string posData)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
if (posData is null)
|
||||
if (string.IsNullOrEmpty(posData))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
JObject posDataJObj = posData as JObject;
|
||||
if (posDataJObj is null)
|
||||
try
|
||||
{
|
||||
if (posData.AsString() is string posDataStr)
|
||||
var jObject = JObject.Parse(posData);
|
||||
foreach (var item in jObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(posDataStr))
|
||||
return result;
|
||||
try
|
||||
|
||||
switch (item.Value.Type)
|
||||
{
|
||||
posDataJObj = JObject.Parse(posDataStr);
|
||||
}
|
||||
catch
|
||||
{
|
||||
result.TryAdd(string.Empty, posDataStr);
|
||||
case JTokenType.Array:
|
||||
var items = item.Value.AsEnumerable().ToList();
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
{
|
||||
result.Add($"{item.Key}[{i}]", ParsePosData(items[i].ToString()));
|
||||
}
|
||||
break;
|
||||
case JTokenType.Object:
|
||||
result.Add(item.Key, ParsePosData(item.Value.ToString()));
|
||||
break;
|
||||
default:
|
||||
result.Add(item.Key, item.Value.ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (posDataJObj is null)
|
||||
return result;
|
||||
|
||||
|
||||
foreach (var item in posDataJObj)
|
||||
catch
|
||||
{
|
||||
|
||||
switch (item.Value.Type)
|
||||
{
|
||||
case JTokenType.Array:
|
||||
var items = item.Value.AsEnumerable().ToList();
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
{
|
||||
result.TryAdd($"{item.Key}[{i}]", ParsePosData(items[i]));
|
||||
}
|
||||
break;
|
||||
case JTokenType.Object:
|
||||
result.TryAdd(item.Key, ParsePosData(item.Value));
|
||||
break;
|
||||
default:
|
||||
result.TryAdd(item.Key, item.Value.ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
result.Add(string.Empty, posData);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -196,9 +196,9 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
if (entity.Metadata.BuyerEmail != null)
|
||||
{
|
||||
if (!EmailValidator.IsEmail(entity.Metadata.BuyerEmail.AsString()))
|
||||
if (!EmailValidator.IsEmail(entity.Metadata.BuyerEmail))
|
||||
throw new BitpayHttpException(400, "Invalid email");
|
||||
entity.RefundMail = entity.Metadata.BuyerEmail.AsString();
|
||||
entity.RefundMail = entity.Metadata.BuyerEmail;
|
||||
}
|
||||
entity.Status = InvoiceStatusLegacy.New;
|
||||
HashSet<CurrencyPair> currencyPairsToFetch = new HashSet<CurrencyPair>();
|
||||
|
@ -29,10 +29,7 @@ namespace BTCPayServer.Controllers
|
||||
var usersQuery = _UserManager.Users;
|
||||
if (!string.IsNullOrWhiteSpace(model.SearchTerm))
|
||||
{
|
||||
#pragma warning disable CA1307 // Specify StringComparison
|
||||
// This is Entity query, can't pass string comparison without crashing
|
||||
usersQuery = usersQuery.Where(u => u.Email.Contains(model.SearchTerm));
|
||||
#pragma warning restore CA1307 // Specify StringComparison
|
||||
}
|
||||
|
||||
if (sortOrder != null)
|
||||
|
@ -857,12 +857,6 @@ namespace BTCPayServer.Controllers
|
||||
if (string.IsNullOrWhiteSpace(userId))
|
||||
return Challenge(AuthenticationSchemes.Cookie);
|
||||
var storeId = CurrentStore?.Id;
|
||||
if (storeId != null)
|
||||
{
|
||||
var store = await _Repo.FindStore(storeId, userId);
|
||||
if (store != null)
|
||||
HttpContext.SetStoreData(store);
|
||||
}
|
||||
var model = new CreateTokenViewModel();
|
||||
ViewBag.HidePublicKey = true;
|
||||
ViewBag.ShowStores = true;
|
||||
@ -919,14 +913,6 @@ namespace BTCPayServer.Controllers
|
||||
return Challenge(AuthenticationSchemes.Cookie);
|
||||
if (pairingCode == null)
|
||||
return NotFound();
|
||||
if (selectedStore != null)
|
||||
{
|
||||
var store = await _Repo.FindStore(selectedStore, userId);
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
HttpContext.SetStoreData(store);
|
||||
ViewBag.ShowStores = false;
|
||||
}
|
||||
var pairing = await _TokenRepository.GetPairingAsync(pairingCode);
|
||||
if (pairing == null)
|
||||
{
|
||||
@ -936,7 +922,7 @@ namespace BTCPayServer.Controllers
|
||||
else
|
||||
{
|
||||
var stores = await _Repo.GetStoresByUserId(userId);
|
||||
return View(new PairingModel
|
||||
return View(new PairingModel()
|
||||
{
|
||||
Id = pairing.Id,
|
||||
Label = pairing.Label,
|
||||
@ -995,6 +981,8 @@ namespace BTCPayServer.Controllers
|
||||
return _UserManager.GetUserId(User);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Need to have talk about how architect default currency implementation
|
||||
// For now we have also hardcoded USD for Store creation and then Invoice creation
|
||||
const string DEFAULT_CURRENCY = "USD";
|
||||
|
@ -27,6 +27,7 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NBitcoin;
|
||||
using BTCPayServer.BIP78.Sender;
|
||||
using BTCPayServer.Payments.PayJoin;
|
||||
using NBitcoin.DataEncoders;
|
||||
using NBXplorer;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
@ -341,8 +342,6 @@ namespace BTCPayServer.Controllers
|
||||
model.Transactions = model.Transactions.OrderByDescending(t => t.Timestamp).Skip(skip).Take(count).ToList();
|
||||
}
|
||||
|
||||
model.CryptoCode = walletId.CryptoCode;
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
@ -364,13 +363,20 @@ namespace BTCPayServer.Controllers
|
||||
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId?.CryptoCode);
|
||||
if (network == null)
|
||||
return NotFound();
|
||||
|
||||
var address = _walletReceiveService.Get(walletId)?.Address;
|
||||
var allowedPayjoin = paymentMethod.IsHotWallet && CurrentStore.GetStoreBlob().PayJoinEnabled;
|
||||
var bip21 = address is null ? null : network.GenerateBIP21(address.ToString(), null);
|
||||
if (allowedPayjoin)
|
||||
{
|
||||
bip21 +=
|
||||
$"?{PayjoinClient.BIP21EndpointKey}={Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new {walletId.CryptoCode}))}";
|
||||
}
|
||||
return View(new WalletReceiveViewModel()
|
||||
{
|
||||
CryptoCode = walletId.CryptoCode,
|
||||
Address = address?.ToString(),
|
||||
CryptoImage = GetImage(paymentMethod.PaymentId, network)
|
||||
CryptoImage = GetImage(paymentMethod.PaymentId, network),
|
||||
PaymentLink = bip21
|
||||
});
|
||||
}
|
||||
|
||||
@ -724,7 +730,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
new WalletSendModel.TransactionOutput()
|
||||
{
|
||||
Amount = uriBuilder.Amount.ToDecimal(MoneyUnit.BTC),
|
||||
Amount = uriBuilder.Amount?.ToDecimal(MoneyUnit.BTC),
|
||||
DestinationAddress = uriBuilder.Address.ToString(),
|
||||
SubtractFeesFromOutput = false
|
||||
}
|
||||
@ -1179,6 +1185,7 @@ namespace BTCPayServer.Controllers
|
||||
public string CryptoImage { get; set; }
|
||||
public string CryptoCode { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string PaymentLink { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,6 @@ using NBitpayClient;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
using NBXplorer.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
@ -428,42 +427,6 @@ namespace BTCPayServer
|
||||
{
|
||||
return ctx.Items.TryGet("BTCPAY.STOREDATA") as StoreData;
|
||||
}
|
||||
|
||||
|
||||
// https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JToken.cs#L1235
|
||||
private static readonly JTokenType[] StringTypes = new[] { JTokenType.Date, JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes, JTokenType.Guid, JTokenType.TimeSpan, JTokenType.Uri };
|
||||
public static string AsString(this JToken tok)
|
||||
{
|
||||
if (tok is JValue v && StringTypes.Contains(v.Type))
|
||||
{
|
||||
if (v.Value is null)
|
||||
return null;
|
||||
|
||||
if (v.Value is byte[] bytes)
|
||||
return Convert.ToBase64String(bytes);
|
||||
if (v.Value is BigInteger bigint)
|
||||
return bigint.ToString(CultureInfo.InvariantCulture);
|
||||
return Convert.ToString(v.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/JToken.cs#L1108
|
||||
private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
|
||||
public static decimal? AsDecimal(this JToken tok)
|
||||
{
|
||||
if (tok is JValue v && NumberTypes.Contains(v.Type))
|
||||
{
|
||||
if (v.Value is null)
|
||||
return null;
|
||||
if (v.Value is BigInteger bigint)
|
||||
return (decimal)bigint;
|
||||
return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void SetStoreData(this HttpContext ctx, StoreData storeData)
|
||||
{
|
||||
ctx.Items["BTCPAY.STOREDATA"] = storeData;
|
||||
|
@ -35,7 +35,7 @@ namespace BTCPayServer
|
||||
{
|
||||
var negative = sats < 0;
|
||||
var amt = sats.ToString(CultureInfo.InvariantCulture)
|
||||
.Replace("-", "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("-", "", StringComparison.InvariantCulture)
|
||||
.PadLeft(divisibility, '0');
|
||||
amt = amt.Length == divisibility ? $"0.{amt}" : amt.Insert(amt.Length - divisibility, ".");
|
||||
return decimal.Parse($"{(negative? "-": string.Empty)}{amt}", CultureInfo.InvariantCulture);
|
||||
|
@ -104,8 +104,8 @@ namespace BTCPayServer.HostedServices
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!string.IsNullOrEmpty(invoiceEvent.Invoice.Metadata.ItemCode.AsString()) ||
|
||||
AppService.TryParsePosCartItems(invoiceEvent.Invoice.Metadata.PosData.AsString(), out cartItems)))
|
||||
if ((!string.IsNullOrEmpty(invoiceEvent.Invoice.Metadata.ItemCode) ||
|
||||
AppService.TryParsePosCartItems(invoiceEvent.Invoice.Metadata.PosData, out cartItems)))
|
||||
{
|
||||
var appIds = AppService.GetAppInternalTags(invoiceEvent.Invoice);
|
||||
|
||||
@ -115,9 +115,9 @@ namespace BTCPayServer.HostedServices
|
||||
}
|
||||
|
||||
var items = cartItems ?? new Dictionary<string, int>();
|
||||
if (!string.IsNullOrEmpty(invoiceEvent.Invoice.Metadata.ItemCode.AsString()))
|
||||
if (!string.IsNullOrEmpty(invoiceEvent.Invoice.Metadata.ItemCode))
|
||||
{
|
||||
items.TryAdd(invoiceEvent.Invoice.Metadata.ItemCode.AsString(), 1);
|
||||
items.TryAdd(invoiceEvent.Invoice.Metadata.ItemCode, 1);
|
||||
}
|
||||
|
||||
_eventAggregator.Publish(new UpdateAppInventory()
|
||||
|
@ -89,9 +89,9 @@ namespace BTCPayServer.HostedServices
|
||||
textSearch.Add(invoice.Id);
|
||||
textSearch.Add(invoice.InvoiceTime.ToString(CultureInfo.InvariantCulture));
|
||||
textSearch.Add(invoice.Price.ToString(CultureInfo.InvariantCulture));
|
||||
textSearch.Add(invoice.Metadata.OrderId.AsString());
|
||||
textSearch.Add(invoice.Metadata.OrderId);
|
||||
textSearch.Add(invoice.StoreId);
|
||||
textSearch.Add(invoice.Metadata.BuyerEmail.AsString());
|
||||
textSearch.Add(invoice.Metadata.BuyerEmail);
|
||||
//
|
||||
textSearch.Add(invoice.RefundMail);
|
||||
// TODO: Are there more things to cache? PaymentData?
|
||||
|
@ -1,36 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Amazon.Runtime.Internal;
|
||||
using Amazon.S3.Model;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Logging;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NBitcoin;
|
||||
using NBitcoin.DataEncoders;
|
||||
using NBitcoin.Secp256k1;
|
||||
using NBitpayClient;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using TwentyTwenty.Storage;
|
||||
|
||||
namespace BTCPayServer.HostedServices
|
||||
{
|
||||
|
@ -9,8 +9,6 @@ namespace BTCPayServer.Models.AppViewModels
|
||||
public class UpdateCrowdfundViewModel
|
||||
{
|
||||
public string StoreId { get; set; }
|
||||
public string StoreName { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(30)]
|
||||
public string Title { get; set; }
|
||||
@ -97,7 +95,12 @@ namespace BTCPayServer.Models.AppViewModels
|
||||
[Display(Name = "Colors to rotate between with animation when a payment is made. First color is the default background. One color per line. Can be any valid css color value.")]
|
||||
public string AnimationColors { get; set; }
|
||||
|
||||
|
||||
// NOTE: Improve validation if needed
|
||||
public bool ModelWithMinimumData => Description != null && Title != null && TargetCurrency != null;
|
||||
public bool ModelWithMinimumData
|
||||
{
|
||||
get { return Description != null && Title != null && TargetCurrency != null; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,6 @@ namespace BTCPayServer.Models.AppViewModels
|
||||
public class UpdatePointOfSaleViewModel
|
||||
{
|
||||
public string StoreId { get; set; }
|
||||
public string StoreName { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(30)]
|
||||
public string Title { get; set; }
|
||||
|
@ -19,6 +19,5 @@ namespace BTCPayServer.Models.WalletViewModels
|
||||
}
|
||||
public HashSet<ColoredLabel> Labels { get; set; } = new HashSet<ColoredLabel>();
|
||||
public List<TransactionViewModel> Transactions { get; set; } = new List<TransactionViewModel>();
|
||||
public string CryptoCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ namespace BTCPayServer.Payments.Lightning
|
||||
|
||||
string description = storeBlob.LightningDescriptionTemplate;
|
||||
description = description.Replace("{StoreName}", store.StoreName ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{ItemDescription}", invoice.Metadata.ItemDesc.AsString() ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{OrderId}", invoice.Metadata.OrderId.AsString() ?? "", StringComparison.OrdinalIgnoreCase);
|
||||
.Replace("{ItemDescription}", invoice.Metadata.ItemDesc ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{OrderId}", invoice.Metadata.OrderId ?? "", StringComparison.OrdinalIgnoreCase);
|
||||
using (var cts = new CancellationTokenSource(LIGHTNING_TIMEOUT))
|
||||
{
|
||||
try
|
||||
|
@ -89,6 +89,8 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
private readonly NBXplorerDashboard _dashboard;
|
||||
private readonly DelayedTransactionBroadcaster _broadcaster;
|
||||
private readonly BTCPayServerEnvironment _env;
|
||||
private readonly WalletReceiveService _walletReceiveService;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
|
||||
public PayJoinEndpointController(BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
InvoiceRepository invoiceRepository, ExplorerClientProvider explorerClientProvider,
|
||||
@ -97,7 +99,9 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
EventAggregator eventAggregator,
|
||||
NBXplorerDashboard dashboard,
|
||||
DelayedTransactionBroadcaster broadcaster,
|
||||
BTCPayServerEnvironment env)
|
||||
BTCPayServerEnvironment env,
|
||||
WalletReceiveService walletReceiveService,
|
||||
StoreRepository storeRepository)
|
||||
{
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_invoiceRepository = invoiceRepository;
|
||||
@ -108,6 +112,8 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
_dashboard = dashboard;
|
||||
_broadcaster = broadcaster;
|
||||
_env = env;
|
||||
_walletReceiveService = walletReceiveService;
|
||||
_storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
[HttpPost("")]
|
||||
@ -238,17 +244,34 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
KeyPath paymentAddressIndex = null;
|
||||
InvoiceEntity invoice = null;
|
||||
DerivationSchemeSettings derivationSchemeSettings = null;
|
||||
WalletId walletId = null;
|
||||
foreach (var output in psbt.Outputs)
|
||||
{
|
||||
var key = output.ScriptPubKey.Hash + "#" + network.CryptoCode.ToUpperInvariant();
|
||||
invoice = (await _invoiceRepository.GetInvoicesFromAddresses(new[] { key })).FirstOrDefault();
|
||||
if (invoice is null)
|
||||
continue;
|
||||
derivationSchemeSettings = invoice.GetSupportedPaymentMethod<DerivationSchemeSettings>(paymentMethodId)
|
||||
.SingleOrDefault();
|
||||
var walletReceiveMatch =
|
||||
_walletReceiveService.GetByScriptPubKey(network.CryptoCode, output.ScriptPubKey);
|
||||
if (walletReceiveMatch is null)
|
||||
{
|
||||
|
||||
var key = output.ScriptPubKey.Hash + "#" + network.CryptoCode.ToUpperInvariant();
|
||||
invoice = (await _invoiceRepository.GetInvoicesFromAddresses(new[] {key})).FirstOrDefault();
|
||||
if (invoice is null)
|
||||
continue;
|
||||
derivationSchemeSettings = invoice
|
||||
.GetSupportedPaymentMethod<DerivationSchemeSettings>(paymentMethodId)
|
||||
.SingleOrDefault();
|
||||
walletId = new WalletId(invoice.StoreId, network.CryptoCode.ToUpperInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
var store = await _storeRepository.FindStore(walletReceiveMatch.Item1.StoreId);
|
||||
derivationSchemeSettings = store.GetDerivationSchemeSettings(_btcPayNetworkProvider,
|
||||
walletReceiveMatch.Item1.CryptoCode);
|
||||
|
||||
walletId = walletReceiveMatch.Item1;
|
||||
}
|
||||
|
||||
if (derivationSchemeSettings is null)
|
||||
continue;
|
||||
|
||||
var receiverInputsType = derivationSchemeSettings.AccountDerivation.ScriptPubKeyType();
|
||||
if (receiverInputsType == ScriptPubKeyType.Legacy)
|
||||
{
|
||||
@ -259,24 +282,39 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
{
|
||||
return CreatePayjoinErrorAndLog(503, PayjoinReceiverWellknownErrors.Unavailable, "We do not have any UTXO available for making a payjoin with the sender's inputs type");
|
||||
}
|
||||
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
|
||||
var paymentDetails =
|
||||
paymentMethod.GetPaymentMethodDetails() as Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod;
|
||||
if (paymentDetails is null || !paymentDetails.PayjoinEnabled || !paymentDetails.Activated)
|
||||
continue;
|
||||
if (invoice.GetAllBitcoinPaymentData().Any())
|
||||
|
||||
if (walletReceiveMatch is null)
|
||||
{
|
||||
ctx.DoNotBroadcast();
|
||||
return UnprocessableEntity(CreatePayjoinError("already-paid",
|
||||
$"The invoice this PSBT is paying has already been partially or completely paid"));
|
||||
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
|
||||
var paymentDetails =
|
||||
paymentMethod.GetPaymentMethodDetails() as Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod;
|
||||
if (paymentDetails is null || !paymentDetails.PayjoinEnabled)
|
||||
continue;
|
||||
paidSomething = true;
|
||||
due = paymentMethod.Calculate().TotalDue - output.Value;
|
||||
if (due > Money.Zero)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
paymentAddress = paymentDetails.GetDepositAddress(network.NBitcoinNetwork);
|
||||
paymentAddressIndex = paymentDetails.KeyPath;
|
||||
|
||||
if (invoice.GetAllBitcoinPaymentData().Any())
|
||||
{
|
||||
ctx.DoNotBroadcast();
|
||||
return UnprocessableEntity(CreatePayjoinError("already-paid",
|
||||
$"The invoice this PSBT is paying has already been partially or completely paid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paidSomething = true;
|
||||
due = Money.Zero;
|
||||
paymentAddress = walletReceiveMatch.Item2.Address;
|
||||
paymentAddressIndex = walletReceiveMatch.Item2.KeyPath;
|
||||
}
|
||||
|
||||
paidSomething = true;
|
||||
due = paymentMethod.Calculate().TotalDue - output.Value;
|
||||
if (due > Money.Zero)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!await _payJoinRepository.TryLockInputs(ctx.OriginalTransaction.Inputs.Select(i => i.PrevOut).ToArray()))
|
||||
{
|
||||
@ -299,8 +337,6 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
}
|
||||
ctx.LockedUTXOs = selectedUTXOs.Select(u => u.Key).ToArray();
|
||||
originalPaymentOutput = output;
|
||||
paymentAddress = paymentDetails.GetDepositAddress(network.NBitcoinNetwork);
|
||||
paymentAddressIndex = paymentDetails.KeyPath;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -448,22 +484,27 @@ namespace BTCPayServer.Payments.PayJoin
|
||||
CoinjoinValue = originalPaymentValue - ourFeeContribution,
|
||||
ContributedOutPoints = selectedUTXOs.Select(o => o.Key).ToArray()
|
||||
};
|
||||
var payment = await _invoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, originalPaymentData, network, true);
|
||||
if (payment is null)
|
||||
if (invoice != null)
|
||||
{
|
||||
return UnprocessableEntity(CreatePayjoinError("already-paid",
|
||||
$"The original transaction has already been accounted"));
|
||||
var payment = await _invoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, originalPaymentData, network, true);
|
||||
if (payment is null)
|
||||
{
|
||||
return UnprocessableEntity(CreatePayjoinError("already-paid",
|
||||
$"The original transaction has already been accounted"));
|
||||
}
|
||||
_eventAggregator.Publish(new InvoiceEvent(invoice,InvoiceEvent.ReceivedPayment) { Payment = payment });
|
||||
}
|
||||
|
||||
|
||||
await _btcPayWalletProvider.GetWallet(network).SaveOffchainTransactionAsync(ctx.OriginalTransaction);
|
||||
_eventAggregator.Publish(new InvoiceEvent(invoice,InvoiceEvent.ReceivedPayment) { Payment = payment });
|
||||
_eventAggregator.Publish(new UpdateTransactionLabel()
|
||||
{
|
||||
WalletId = new WalletId(invoice.StoreId, network.CryptoCode),
|
||||
WalletId = walletId,
|
||||
TransactionLabels = selectedUTXOs.GroupBy(pair => pair.Key.Hash).Select(utxo =>
|
||||
new KeyValuePair<uint256, List<(string color, Label label)>>(utxo.Key,
|
||||
new List<(string color, Label label)>()
|
||||
{
|
||||
UpdateTransactionLabel.PayjoinExposedLabelTemplate(invoice.Id)
|
||||
UpdateTransactionLabel.PayjoinExposedLabelTemplate(invoice?.Id)
|
||||
}))
|
||||
.ToDictionary(pair => pair.Key, pair => pair.Value)
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ namespace BTCPayServer.Plugins
|
||||
|
||||
public static bool IsExceptionByPlugin(Exception exception)
|
||||
{
|
||||
return _pluginAssemblies.Any(assembly => assembly.FullName.Contains(exception.Source, StringComparison.OrdinalIgnoreCase));
|
||||
return _pluginAssemblies.Any(assembly => assembly.FullName.Contains(exception.Source));
|
||||
}
|
||||
public static IMvcBuilder AddPlugins(this IMvcBuilder mvcBuilder, IServiceCollection serviceCollection,
|
||||
IConfiguration config, ILoggerFactory loggerFactory)
|
||||
|
@ -98,8 +98,8 @@ namespace BTCPayServer.Services.Apps
|
||||
var currentPayments = GetContributionsByPaymentMethodId(settings.TargetCurrency, completeInvoices, !settings.EnforceTargetAmount);
|
||||
|
||||
var perkCount = paidInvoices
|
||||
.Where(entity => !string.IsNullOrEmpty(entity.Metadata.ItemCode.AsString()))
|
||||
.GroupBy(entity => entity.Metadata.ItemCode.AsString())
|
||||
.Where(entity => !string.IsNullOrEmpty(entity.Metadata.ItemCode))
|
||||
.GroupBy(entity => entity.Metadata.ItemCode)
|
||||
.ToDictionary(entities => entities.Key, entities => entities.Count());
|
||||
|
||||
var perks = Parse(settings.PerksTemplate, settings.TargetCurrency);
|
||||
|
@ -87,7 +87,7 @@ namespace BTCPayServer.Services.Invoices.Export
|
||||
// while looking just at export you could sum Paid and assume merchant "received payments"
|
||||
NetworkFee = payment.NetworkFee.ToString(CultureInfo.InvariantCulture),
|
||||
InvoiceDue = Math.Round(invoiceDue, currency.NumberDecimalDigits),
|
||||
OrderId = invoice.Metadata.OrderId.AsString() ?? string.Empty,
|
||||
OrderId = invoice.Metadata.OrderId ?? string.Empty,
|
||||
StoreId = invoice.StoreId,
|
||||
InvoiceId = invoice.Id,
|
||||
InvoiceCreatedDate = invoice.InvoiceTime.UtcDateTime,
|
||||
@ -98,11 +98,11 @@ namespace BTCPayServer.Services.Invoices.Export
|
||||
InvoiceStatus = invoice.StatusString,
|
||||
InvoiceExceptionStatus = invoice.ExceptionStatusString,
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
InvoiceItemCode = invoice.Metadata.ItemCode.AsString(),
|
||||
InvoiceItemDesc = invoice.Metadata.ItemDesc.AsString(),
|
||||
InvoiceItemCode = invoice.Metadata.ItemCode,
|
||||
InvoiceItemDesc = invoice.Metadata.ItemDesc,
|
||||
InvoicePrice = invoice.Price,
|
||||
InvoiceCurrency = invoice.Currency,
|
||||
BuyerEmail = invoice.Metadata.BuyerEmail.AsString()
|
||||
BuyerEmail = invoice.Metadata.BuyerEmail
|
||||
};
|
||||
|
||||
exportList.Add(target);
|
||||
|
@ -30,39 +30,67 @@ namespace BTCPayServer.Services.Invoices
|
||||
seria.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
MetadataSerializer = seria;
|
||||
}
|
||||
public JToken OrderId { get; set; }
|
||||
public string OrderId { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerName")]
|
||||
public JToken BuyerName { get; set; }
|
||||
public string BuyerName { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerEmail")]
|
||||
public JToken BuyerEmail { get; set; }
|
||||
public string BuyerEmail { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerCountry")]
|
||||
public JToken BuyerCountry { get; set; }
|
||||
public string BuyerCountry { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerZip")]
|
||||
public JToken BuyerZip { get; set; }
|
||||
public string BuyerZip { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerState")]
|
||||
public JToken BuyerState { get; set; }
|
||||
public string BuyerState { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerCity")]
|
||||
public JToken BuyerCity { get; set; }
|
||||
public string BuyerCity { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerAddress2")]
|
||||
public JToken BuyerAddress2 { get; set; }
|
||||
public string BuyerAddress2 { get; set; }
|
||||
[JsonProperty(PropertyName = "buyerAddress1")]
|
||||
public JToken BuyerAddress1 { get; set; }
|
||||
public string BuyerAddress1 { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "buyerPhone")]
|
||||
public JToken BuyerPhone { get; set; }
|
||||
public string BuyerPhone { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "itemDesc")]
|
||||
public JToken ItemDesc { get; set; }
|
||||
public string ItemDesc { get; set; }
|
||||
[JsonProperty(PropertyName = "itemCode")]
|
||||
public JToken ItemCode { get; set; }
|
||||
public string ItemCode { get; set; }
|
||||
[JsonProperty(PropertyName = "physical")]
|
||||
public JToken Physical { get; set; }
|
||||
public bool? Physical { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "taxIncluded", DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public JToken TaxIncluded { get; set; }
|
||||
public decimal? TaxIncluded { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string PosData
|
||||
{
|
||||
get
|
||||
{
|
||||
return PosRawData?.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
PosRawData = JValue.CreateNull();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
PosRawData = JToken.Parse(value);
|
||||
}
|
||||
catch (Exception )
|
||||
{
|
||||
PosRawData = JToken.FromObject(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "posData")]
|
||||
public JToken PosData { get; set; }
|
||||
public JToken PosRawData { get; set; }
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
|
||||
@ -255,11 +283,9 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
private Uri FillPlaceholdersUri(string v)
|
||||
{
|
||||
v ??= string.Empty;
|
||||
string orderId = Metadata.OrderId.AsString();
|
||||
v = v.Replace("{OrderId}", orderId is null ? string.Empty : System.Web.HttpUtility.UrlEncode(orderId), StringComparison.OrdinalIgnoreCase);
|
||||
v = v.Replace("{InvoiceId}", System.Web.HttpUtility.UrlEncode(Id), StringComparison.OrdinalIgnoreCase);
|
||||
if (Uri.TryCreate(v, UriKind.Absolute, out var uri) && (uri.Scheme == "http" || uri.Scheme == "https"))
|
||||
var uriStr = (v ?? string.Empty).Replace("{OrderId}", System.Web.HttpUtility.UrlEncode(Metadata.OrderId) ?? "", StringComparison.OrdinalIgnoreCase)
|
||||
.Replace("{InvoiceId}", System.Web.HttpUtility.UrlEncode(Id) ?? "", StringComparison.OrdinalIgnoreCase);
|
||||
if (Uri.TryCreate(uriStr, UriKind.Absolute, out var uri) && (uri.Scheme == "http" || uri.Scheme == "https"))
|
||||
return uri;
|
||||
return null;
|
||||
}
|
||||
@ -304,8 +330,8 @@ namespace BTCPayServer.Services.Invoices
|
||||
{
|
||||
Id = Id,
|
||||
StoreId = StoreId,
|
||||
OrderId = Metadata.OrderId.AsString(),
|
||||
PosData = Metadata.PosData.AsString(),
|
||||
OrderId = Metadata.OrderId,
|
||||
PosData = Metadata.PosData,
|
||||
CurrentTime = DateTimeOffset.UtcNow,
|
||||
InvoiceTime = InvoiceTime,
|
||||
ExpirationTime = ExpirationTime,
|
||||
@ -423,9 +449,9 @@ namespace BTCPayServer.Services.Invoices
|
||||
|
||||
//dto.AmountPaid dto.MinerFees & dto.TransactionCurrency are not supported by btcpayserver as we have multi currency payment support per invoice
|
||||
|
||||
dto.ItemCode = Metadata.ItemCode.AsString();
|
||||
dto.ItemDesc = Metadata.ItemDesc.AsString();
|
||||
dto.TaxIncluded = Metadata.TaxIncluded.AsDecimal() ?? 0m;
|
||||
dto.ItemCode = Metadata.ItemCode;
|
||||
dto.ItemDesc = Metadata.ItemDesc;
|
||||
dto.TaxIncluded = Metadata.TaxIncluded ?? 0m;
|
||||
dto.Price = Price;
|
||||
dto.Currency = Currency;
|
||||
dto.Buyer = new JObject();
|
||||
@ -437,7 +463,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
dto.Buyer.Add(new JProperty("postalCode", Metadata.BuyerZip));
|
||||
dto.Buyer.Add(new JProperty("country", Metadata.BuyerCountry));
|
||||
dto.Buyer.Add(new JProperty("phone", Metadata.BuyerPhone));
|
||||
dto.Buyer.Add(new JProperty("email", string.IsNullOrWhiteSpace(Metadata.BuyerEmail.AsString()) ? RefundMail : Metadata.BuyerEmail));
|
||||
dto.Buyer.Add(new JProperty("email", string.IsNullOrWhiteSpace(Metadata.BuyerEmail) ? RefundMail : Metadata.BuyerEmail));
|
||||
|
||||
dto.Token = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); //No idea what it is useful for
|
||||
dto.Guid = Guid.NewGuid().ToString();
|
||||
|
@ -166,11 +166,11 @@ namespace BTCPayServer.Services.Invoices
|
||||
Id = invoice.Id,
|
||||
Created = invoice.InvoiceTime,
|
||||
Blob = ToBytes(invoice, null),
|
||||
OrderId = invoice.Metadata.OrderId.AsString(),
|
||||
OrderId = invoice.Metadata.OrderId,
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Status = invoice.StatusString,
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
ItemCode = invoice.Metadata.ItemCode.AsString(),
|
||||
ItemCode = invoice.Metadata.ItemCode,
|
||||
CustomerEmail = invoice.RefundMail,
|
||||
Archived = false
|
||||
};
|
||||
@ -207,9 +207,9 @@ namespace BTCPayServer.Services.Invoices
|
||||
textSearch.Add(invoice.Id);
|
||||
textSearch.Add(invoice.InvoiceTime.ToString(CultureInfo.InvariantCulture));
|
||||
textSearch.Add(invoice.Price.ToString(CultureInfo.InvariantCulture));
|
||||
textSearch.Add(invoice.Metadata.OrderId.AsString());
|
||||
textSearch.Add(invoice.Metadata.OrderId);
|
||||
textSearch.Add(invoice.StoreId);
|
||||
textSearch.Add(invoice.Metadata.BuyerEmail.AsString());
|
||||
textSearch.Add(invoice.Metadata.BuyerEmail);
|
||||
AddToTextSearch(context, invoiceData, textSearch.ToArray());
|
||||
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
@ -597,7 +597,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
{
|
||||
entity.Events = invoice.Events.OrderBy(c => c.Timestamp).ToList();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(entity.RefundMail) && string.IsNullOrEmpty(entity.Metadata.BuyerEmail.AsString()))
|
||||
if (!string.IsNullOrEmpty(entity.RefundMail) && string.IsNullOrEmpty(entity.Metadata.BuyerEmail))
|
||||
{
|
||||
entity.Metadata.BuyerEmail = entity.RefundMail;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace BTCPayServer.Services.Labels
|
||||
{
|
||||
static void FixLegacy(JObject jObj, ReferenceLabel refLabel)
|
||||
{
|
||||
if (refLabel.Reference is null)
|
||||
if (refLabel.Reference is null && jObj.ContainsKey("id"))
|
||||
refLabel.Reference = jObj["id"].Value<string>();
|
||||
FixLegacy(jObj, (Label)refLabel);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ namespace BTCPayServer.Services.Wallets
|
||||
}
|
||||
|
||||
await explorerClient.CancelReservationAsync(kpi.DerivationStrategy, new[] {kpi.KeyPath});
|
||||
Remove(walletId);
|
||||
return kpi.Address.ToString();
|
||||
}
|
||||
|
||||
@ -128,5 +129,19 @@ namespace BTCPayServer.Services.Wallets
|
||||
_leases.Dispose();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Tuple<WalletId, KeyPathInformation>? GetByScriptPubKey(string cryptoCode,Script script)
|
||||
{
|
||||
var match = _walletReceiveState.Where(pair =>
|
||||
pair.Key.CryptoCode.Equals(cryptoCode, StringComparison.InvariantCulture) &&
|
||||
pair.Value.ScriptPubKey == script);
|
||||
if (match.Any())
|
||||
{
|
||||
var f =match.First();
|
||||
return new Tuple<WalletId, KeyPathInformation>(f.Key, f.Value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,14 @@
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
@ -33,7 +39,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
||||
<div class="row justify-content-center mb-2">
|
||||
@ -18,7 +18,10 @@
|
||||
|
||||
<h1 class="h2 mb-3">Welcome to your BTCPay Server</h1>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<partial name="_StatusMessage"/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -43,5 +43,5 @@
|
||||
</section>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -33,5 +33,5 @@
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
||||
<div class="row justify-content-center mb-2">
|
||||
@ -22,7 +22,10 @@
|
||||
<span class="d-sm-block">It is secure, private, censorship-resistant and free.</span>
|
||||
</p>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<partial name="_StatusMessage"/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
@model BTCPayServer.Models.AccountViewModels.SetPasswordViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Reset password";
|
||||
|
||||
Layout = "_LayoutSimple";
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
||||
<div class="row justify-content-center mb-2">
|
||||
@ -16,7 +17,10 @@
|
||||
|
||||
<h1 class="h2 mb-3">Welcome to your BTCPay Server</h1>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<partial name="_StatusMessage"/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,6 +2,6 @@ namespace BTCPayServer.Views.Apps
|
||||
{
|
||||
public enum AppsNavPages
|
||||
{
|
||||
Index, Create, Update
|
||||
Index, Create
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
@model CreateAppViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(AppsNavPages.Create, "Create a new app");
|
||||
ViewData["Title"] = "Create a new app";
|
||||
}
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form asp-action="CreateApp">
|
||||
@ -26,10 +28,10 @@
|
||||
<select asp-for="SelectedStore" asp-items="Model.Stores" class="form-control"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-primary" id="Create"/>
|
||||
<a asp-action="ListApps" class="text-muted ml-3">Back to list</a>
|
||||
<input type="submit" value="Create" class="btn btn-primary" id="Create" />
|
||||
</div>
|
||||
</form>
|
||||
<a asp-action="ListApps">Back to the app list</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
@model ListAppsViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(AppsNavPages.Index, "Apps");
|
||||
ViewData["Title"] = "Apps";
|
||||
var storeNameSortOrder = (string)ViewData["StoreNameSortOrder"];
|
||||
var appNameSortOrder = (string)ViewData["AppNameSortOrder"];
|
||||
var appTypeSortOrder = (string)ViewData["AppTypeSortOrder"];
|
||||
@ -10,20 +10,27 @@
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-2">
|
||||
<h2 class="mb-0">
|
||||
@ViewData["PageTitle"]
|
||||
<small>
|
||||
<a href="https://docs.btcpayserver.org/Apps/" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
</small>
|
||||
</h2>
|
||||
<a asp-action="CreateApp" class="btn btn-primary mt-3 mt-sm-0" role="button" id="CreateNewApp"><span class="fa fa-plus"></span> Create a new app</a>
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
<p>Create and manage apps.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row button-row mb-3">
|
||||
<div class="col-lg-12">
|
||||
<a asp-action="CreateApp" class="btn btn-primary" role="button" id="CreateNewApp"><span class="fa fa-plus"></span> Create a new app</a>
|
||||
<a href="https://docs.btcpayserver.org/Apps/" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
@if (Model.Apps.Any())
|
||||
|
@ -2,14 +2,25 @@
|
||||
@using System.Globalization
|
||||
@model UpdateCrowdfundViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(AppsNavPages.Update, "Update Crowdfund", Model.StoreName);
|
||||
ViewData["Title"] = "Update Crowdfund";
|
||||
}
|
||||
<section>
|
||||
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
</div>
|
||||
</div>
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form method="post">
|
||||
@ -81,9 +92,7 @@
|
||||
</div>
|
||||
<span asp-validation-for="EndDate" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<partial name="TemplateEditor" model="@(nameof(Model.PerksTemplate), "Perks")" />
|
||||
|
||||
<partial name="TemplateEditor" model="@(nameof(Model.PerksTemplate), "Perks" )"/>
|
||||
<div class="form-group">
|
||||
<label asp-for="PerksTemplate" class="control-label"></label>
|
||||
<textarea asp-for="PerksTemplate" rows="10" cols="40" class="js-product-template form-control"></textarea>
|
||||
@ -91,9 +100,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="CustomCSSLink" class="control-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<input asp-for="CustomCSSLink" class="form-control" />
|
||||
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||
</div>
|
||||
|
@ -2,14 +2,24 @@
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@model UpdatePointOfSaleViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(AppsNavPages.Update, "Update Point of Sale", Model.StoreName);
|
||||
ViewData["Title"] = "Update Point of Sale";
|
||||
}
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
</div>
|
||||
</div>
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form method="post">
|
||||
@ -69,15 +79,11 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="CustomCSSLink" class="control-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<input asp-for="CustomCSSLink" class="form-control" />
|
||||
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<partial name="TemplateEditor" model="@(nameof(Model.Template), "Products")" />
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="Template" class="control-label"></label>
|
||||
<textarea asp-for="Template" rows="10" cols="40" class="js-product-template form-control"></textarea>
|
||||
|
@ -1,2 +1 @@
|
||||
@using BTCPayServer.Views.Apps
|
||||
@using BTCPayServer.Models.AppViewModels
|
||||
@using BTCPayServer.Models.AppViewModels
|
||||
|
@ -1,6 +1,6 @@
|
||||
@using BTCPayServer.Views
|
||||
@using BTCPayServer.Views.Apps
|
||||
@{
|
||||
ViewBag.CategoryTitle = "Apps";
|
||||
ViewBag.MainTitle = "Manage app";
|
||||
ViewData.SetActiveCategory(typeof(AppsNavPages));
|
||||
}
|
||||
|
@ -202,8 +202,10 @@
|
||||
<div id="content">
|
||||
<div class="p-2 p-sm-4">
|
||||
<div class="row">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (this.TempData.HasStatusMessage())
|
||||
{
|
||||
<partial name="_StatusMessage" />
|
||||
}
|
||||
<div class="col-sm-4 col-lg-2 order-sm-last text-right mb-2">
|
||||
<a class="js-cart btn btn-lg btn-outline-primary" href="#">
|
||||
<i class="fa fa-shopping-basket"></i>
|
||||
|
@ -5,12 +5,12 @@
|
||||
|
||||
@if (Context.Request.Query.ContainsKey("simple"))
|
||||
{
|
||||
<partial name="/Views/AppsPublic/PointOfSale/MinimalLight.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/PointOfSale/MinimalLight.cshtml", Model)
|
||||
}
|
||||
else
|
||||
{
|
||||
<noscript>
|
||||
<partial name="/Views/AppsPublic/PointOfSale/MinimalLight.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/PointOfSale/MinimalLight.cshtml", Model)
|
||||
</noscript>
|
||||
<partial name="/Views/AppsPublic/PointOfSale/VueLight.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/PointOfSale/VueLight.cshtml", Model)
|
||||
}
|
||||
|
@ -6,8 +6,10 @@
|
||||
|
||||
<div class="container d-flex h-100">
|
||||
<div class="justify-content-center align-self-center text-center mx-auto px-2 py-3 w-100 m-auto">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<partial name="_StatusMessage" />
|
||||
}
|
||||
<h1 class="mb-4">@Model.Title</h1>
|
||||
@if (!string.IsNullOrEmpty(Model.Description))
|
||||
{
|
||||
|
@ -40,12 +40,12 @@
|
||||
<body>
|
||||
@if (Context.Request.Query.ContainsKey("simple"))
|
||||
{
|
||||
<partial name="/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
|
||||
}
|
||||
else
|
||||
{
|
||||
<noscript>
|
||||
<partial name="/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
|
||||
|
||||
<style>
|
||||
/* Hide the below canvas or else user will be staring "Loading..." text when JS is disabled */
|
||||
@ -60,7 +60,8 @@
|
||||
{
|
||||
<canvas id="fireworks"></canvas>
|
||||
}
|
||||
<partial name="/Views/AppsPublic/Crowdfund/VueCrowdfund.cshtml" model="Model" />
|
||||
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/VueCrowdfund.cshtml", Model)
|
||||
}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,20 +1,29 @@
|
||||
|
||||
@using BTCPayServer.Views.Stores
|
||||
@model BTCPayServer.Services.Altcoins.Ethereum.UI.EditEthereumPaymentMethodViewModel
|
||||
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
|
||||
ViewData["NavPartialName"] = "../Stores/_Nav";
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, $"{Context.GetRouteValue("cryptoCode")} Settings", Context.GetStoreData().StoreName);
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, $"{this.Context.GetRouteValue("cryptoCode")} Settings");
|
||||
}
|
||||
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="alert alert-warning">DO NOT USE THE WALLET TO ACCEPT PAYMENTS OUTSIDE OF THIS STORE.<br/>If you spend funds received on invoices which have not been marked complete yet, the invoice will be marked as unpaid.
|
||||
</div>
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<form method="post" asp-action="GetStoreEthereumLikePaymentMethod"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@Context.GetRouteValue("cryptoCode")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@this.Context.GetRouteValue("cryptoCode")"
|
||||
class="mt-4" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" asp-for="OriginalIndex"/>
|
||||
@ -76,8 +85,8 @@
|
||||
<button type="submit" class="btn btn-primary" id="SaveButton">Save</button>
|
||||
|
||||
<a class="btn btn-secondary" asp-action="GetStoreEthereumLikePaymentMethods"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@Context.GetRouteValue("cryptoCode")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@this.Context.GetRouteValue("cryptoCode")"
|
||||
asp-controller="EthereumLikeStore">
|
||||
Back to list
|
||||
</a>
|
||||
|
@ -5,13 +5,22 @@
|
||||
@inject BTCPayNetworkProvider BTCPayNetworkProvider;
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, "Ethereum Settings", Context.GetStoreData().StoreName);
|
||||
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, "Ethereum Settings");
|
||||
|
||||
ViewData["NavPartialName"] = "../Stores/_Nav";
|
||||
}
|
||||
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<table class="table table-sm table-responsive-md">
|
||||
<thead>
|
||||
@ -40,10 +49,11 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a id="Modify@(item.CryptoCode)" asp-action="GetStoreEthereumLikePaymentMethod"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@item.CryptoCode">
|
||||
Modify
|
||||
</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@ -57,6 +67,7 @@
|
||||
var chains = BTCPayNetworkProvider.GetAll().OfType<EthereumBTCPayNetwork>().Select(network => network.ChainId).Distinct();
|
||||
foreach (var chain in chains)
|
||||
{
|
||||
|
||||
<a asp-action="UpdateChainConfig" asp-controller="EthereumConfig" asp-route-chainId="@chain">Configure Web3 for chain @chain</a>
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
||||
<style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
@model BTCPayServer.Models.InvoicingModels.CreateInvoiceModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(InvoiceNavPages.Create, "Create an invoice");
|
||||
ViewData["Title"] = "Create an invoice";
|
||||
}
|
||||
<script>
|
||||
$(function() {
|
||||
@ -12,10 +12,12 @@
|
||||
</script>
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form asp-action="CreateInvoice" method="post" id="create-invoice-form">
|
||||
@ -67,9 +69,9 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-primary" id="Create" />
|
||||
<a asp-action="ListInvoices" class="text-muted ml-3">Back to list</a>
|
||||
</div>
|
||||
</form>
|
||||
<a asp-action="ListInvoices">Back to List</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,7 +13,14 @@
|
||||
|
||||
<section class="invoice-details">
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row mb-4">
|
||||
<h2 class="col-xs-12 col-lg-9 mb-4 mb-lg-0">@ViewData["Title"]</h2>
|
||||
@ -150,14 +157,14 @@
|
||||
{
|
||||
<h3 class="mb-3">Product Information</h3>
|
||||
<table class="table table-sm table-responsive-md removetopborder">
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode.AsString()))
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode))
|
||||
{
|
||||
<tr>
|
||||
<th>Item code</th>
|
||||
<td>@Model.TypedMetadata.ItemCode</td>
|
||||
</tr>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc.AsString()))
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc))
|
||||
{
|
||||
<tr>
|
||||
<th>Item Description</th>
|
||||
@ -183,14 +190,14 @@
|
||||
<div class="col-md-6 mb-4">
|
||||
<h3 class="mb-3">Product information</h3>
|
||||
<table class="table table-sm table-responsive-md removetopborder">
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode.AsString()))
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemCode))
|
||||
{
|
||||
<tr>
|
||||
<th>Item code</th>
|
||||
<td>@Model.TypedMetadata.ItemCode</td>
|
||||
</tr>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc.AsString()))
|
||||
@if (!string.IsNullOrEmpty(Model.TypedMetadata.ItemDesc))
|
||||
{
|
||||
<tr>
|
||||
<th>Item Description</th>
|
||||
|
@ -1,6 +1,7 @@
|
||||
@using BTCPayServer.Payments
|
||||
@model InvoicesModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(InvoiceNavPages.Index, "Invoices");
|
||||
ViewData["Title"] = "Invoices";
|
||||
var storeIds = string.Join("", Model.StoreIds.Select(storeId => $",storeid:{storeId}"));
|
||||
}
|
||||
@section HeadScripts {
|
||||
@ -10,25 +11,31 @@
|
||||
@Html.HiddenFor(a => a.Count)
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<h2 class="mb-0">
|
||||
@ViewData["Title"]
|
||||
<small>
|
||||
<a href="https://docs.btcpayserver.org/PaymentRequests/" class="ml-1" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
</small>
|
||||
</h2>
|
||||
<a id="CreateNewInvoice" asp-action="CreateInvoice" class="btn btn-primary mt-3 mt-sm-0">
|
||||
<span class="fa fa-plus"></span>
|
||||
Create an invoice
|
||||
</a>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
<p>Create, search or pay an invoice.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6 mb-5 mb-lg-2 ml-auto">
|
||||
<div class="col-12 col-sm-4 col-lg-6 mb-3">
|
||||
<a id="CreateNewInvoice" asp-action="CreateInvoice" class="btn btn-primary mb-1">
|
||||
<span class="fa fa-plus"></span>
|
||||
Create an invoice
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12 col-sm-8 col-lg-6 mb-3">
|
||||
<form asp-action="ListInvoices" method="get">
|
||||
<input type="hidden" asp-for="Count"/>
|
||||
<input asp-for="TimezoneOffset" type="hidden"/>
|
||||
@ -177,7 +184,7 @@
|
||||
|
||||
@if (Model.Total > 0)
|
||||
{
|
||||
<form method="post" id="MassAction" asp-action="MassAction" class="mt-lg-n5">
|
||||
<form method="post" id="MassAction" asp-action="MassAction" class="mt-3">
|
||||
<span class="mr-2">
|
||||
<button class="btn btn-secondary dropdown-toggle mb-1" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
|
@ -1,2 +1 @@
|
||||
@using BTCPayServer.Services.Invoices
|
||||
@using BTCPayServer.Views.Invoice
|
||||
|
@ -4,7 +4,7 @@
|
||||
ViewData.SetActivePageAndTitle(ManageNavPages.APIKeys, "Manage your API Keys");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<p>
|
||||
The <a asp-controller="Home" asp-action="SwaggerDocs" target="_blank">BTCPay Server Greenfield API</a> offers programmatic access to your instance. You can manage your BTCPay
|
||||
|
@ -7,11 +7,11 @@
|
||||
ViewData.SetActivePageAndTitle(ManageNavPages.APIKeys, "Add API Key");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<p>Generate a new api key to use BTCPay through its API.</p>
|
||||
<h4>@ViewData["Title"]</h4>
|
||||
<partial name="_StatusMessage"/>
|
||||
<p>
|
||||
Generate a new api key to use BTCPay through its API.
|
||||
</p>
|
||||
|
||||
<form method="post" asp-action="AddApiKey">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
@ -109,7 +109,7 @@
|
||||
</form>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
<style>
|
||||
.remove-btn {
|
||||
|
@ -4,6 +4,7 @@
|
||||
}
|
||||
|
||||
<form asp-action="AddU2FDevice" method="post" id="registerForm" class="hidden">
|
||||
|
||||
<input type="hidden" asp-for="AppId"/>
|
||||
<input type="hidden" asp-for="Version"/>
|
||||
<input type="hidden" asp-for="Challenge"/>
|
||||
@ -11,6 +12,7 @@
|
||||
<input type="hidden" asp-for="DeviceResponse"/>
|
||||
</form>
|
||||
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="mb-0">
|
||||
|
@ -5,12 +5,11 @@
|
||||
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
ViewData["Title"] = $"Authorize {Model.ApplicationName ?? "Application"}";
|
||||
ViewData["Title"] = $"Authorize {(Model.ApplicationName ?? "Application")}";
|
||||
var permissions = Permission.ToPermissions(Model.Permissions.Split(';')).GroupBy(permission => permission.Policy);
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
<form method="post" asp-action="AuthorizeAPIKey">
|
||||
<input type="hidden" asp-for="RedirectUrl" value="@Model.RedirectUrl"/>
|
||||
<input type="hidden" asp-for="Permissions" value="@Model.Permissions"/>
|
||||
|
@ -5,26 +5,31 @@
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (!this.ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="OldPassword"></label>
|
||||
<input asp-for="OldPassword" class="form-control"/>
|
||||
<input asp-for="OldPassword" class="form-control" />
|
||||
<span asp-validation-for="OldPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="NewPassword"></label>
|
||||
<input asp-for="NewPassword" class="form-control"/>
|
||||
<input asp-for="NewPassword" class="form-control" />
|
||||
<span asp-validation-for="NewPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ConfirmPassword"></label>
|
||||
<input asp-for="ConfirmPassword" class="form-control"/>
|
||||
<input asp-for="ConfirmPassword" class="form-control" />
|
||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" id="UpdatePassword">Update password</button>
|
||||
@ -33,5 +38,5 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
<partial name="Header" />
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<div class="modal-dialog modal-dialog-centered min-vh-100">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title w-100 text-center">@ViewData["Title"]</h4>
|
||||
|
@ -56,7 +56,7 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
<script type="text/javascript" src="~/js/qrcode.js" asp-append-version="true"></script>
|
||||
<script type="text/javascript">
|
||||
new QRCode(document.getElementById("qrCode"),
|
||||
|
@ -3,28 +3,32 @@
|
||||
ViewData.SetActivePageAndTitle(ManageNavPages.Index, "Profile");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />)
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (!this.ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<form method="post">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label asp-for="Username"></label>
|
||||
<input asp-for="Username" class="form-control" disabled/>
|
||||
<input asp-for="Username" class="form-control" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label asp-for="Email"></label>
|
||||
<input asp-for="Email" class="form-control"/>
|
||||
<input asp-for="Email" class="form-control" />
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3 d-flex align-items-end">
|
||||
@if (Model.IsEmailConfirmed)
|
||||
@if(Model.IsEmailConfirmed)
|
||||
{
|
||||
<span class="badge badge-success p-2 my-1">
|
||||
<span class="fa fa-check"></span>
|
||||
@ -41,5 +45,5 @@
|
||||
</form>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -5,8 +5,7 @@
|
||||
ViewData.SetActivePageAndTitle(ManageNavPages.Notifications, "Notification preferences");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
<form method="post" asp-action="NotificationSettings">
|
||||
@if (Model.All)
|
||||
{
|
||||
|
@ -3,10 +3,8 @@
|
||||
ViewData.SetActivePageAndTitle(ManageNavPages.ChangePassword, "Set password");
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h4>Set your password</h4>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<p class="text-info">
|
||||
You do not have a local username/password for this site. Add a local
|
||||
account so you can log in without an external login.
|
||||
@ -31,5 +29,5 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -83,5 +83,5 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
|
||||
<div class="nav flex-column mb-4">
|
||||
<div class="nav flex-column nav-pills mb-4">
|
||||
<a id="@ManageNavPages.Index.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.Index)" asp-action="Index">Profile</a>
|
||||
<a id="@ManageNavPages.ChangePassword.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.ChangePassword)" asp-action="ChangePassword">Password</a>
|
||||
<a id="@ManageNavPages.TwoFactorAuthentication.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.TwoFactorAuthentication)" asp-action="TwoFactorAuthentication">Two-factor authentication</a>
|
||||
|
@ -2,6 +2,6 @@
|
||||
@using BTCPayServer.Views.Manage
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewBag.CategoryTitle = "Account";
|
||||
ViewBag.MainTitle = "Manage your account";
|
||||
ViewData.SetActiveCategory(typeof(ManageNavPages));
|
||||
}
|
||||
|
@ -4,13 +4,21 @@
|
||||
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
|
||||
ViewData["NavPartialName"] = "../Stores/_Nav";
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, $"{Model.CryptoCode} Settings");
|
||||
}
|
||||
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
@if (Model.Summary != null)
|
||||
{
|
||||
<div class="card">
|
||||
@ -23,11 +31,11 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!Model.WalletFileFound || Model.Summary.WalletHeight == default)
|
||||
@if (!Model.WalletFileFound || Model.Summary.WalletHeight == default(long))
|
||||
{
|
||||
<form method="post" asp-action="GetStoreMoneroLikePaymentMethod"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@Context.GetRouteValue("cryptoCode")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@this.Context.GetRouteValue("cryptoCode")"
|
||||
class="mt-4" enctype="multipart/form-data">
|
||||
|
||||
<div class="card my-2">
|
||||
@ -54,12 +62,12 @@
|
||||
</form>
|
||||
}
|
||||
<form method="post" asp-action="GetStoreMoneroLikePaymentMethod"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@Context.GetRouteValue("cryptoCode")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@this.Context.GetRouteValue("cryptoCode")"
|
||||
class="mt-4" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" asp-for="CryptoCode"/>
|
||||
@if (!Model.WalletFileFound || Model.Summary.WalletHeight == default)
|
||||
@if (!Model.WalletFileFound || Model.Summary.WalletHeight == default(long))
|
||||
{
|
||||
<input type="hidden" asp-for="AccountIndex"/>
|
||||
}
|
||||
@ -82,7 +90,7 @@
|
||||
<div class="input-group my-3">
|
||||
<input type="text" class="form-control" placeholder="New account label" asp-for="NewAccountLabel">
|
||||
<div class="input-group-append">
|
||||
<button name="command" value="add-account" class="btn btn-secondary" type="submit">Add account</button>
|
||||
<button name="command" value="add-account" class="btn btn-secondary"type="submit">Add account</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -99,8 +107,9 @@
|
||||
<button type="submit" class="btn btn-primary" id="SaveButton">Save</button>
|
||||
|
||||
<a class="btn btn-secondary" asp-action="GetStoreMoneroLikePaymentMethods"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@Context.GetRouteValue("cryptoCode")"
|
||||
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@this.Context.GetRouteValue("cryptoCode")"
|
||||
asp-controller="MoneroLikeStore">
|
||||
Back to list
|
||||
</a>
|
||||
|
@ -3,13 +3,22 @@
|
||||
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.ActivePage, "Monero Settings");
|
||||
|
||||
ViewData["NavPartialName"] = "../Stores/_Nav";
|
||||
}
|
||||
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<table class="table table-sm table-responsive-md">
|
||||
<thead>
|
||||
@ -38,7 +47,7 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a id="Modify" asp-action="GetStoreMoneroLikePaymentMethod"
|
||||
asp-route-storeId="@Context.GetRouteValue("storeId")"
|
||||
asp-route-storeId="@this.Context.GetRouteValue("storeId")"
|
||||
asp-route-cryptoCode="@item.CryptoCode">
|
||||
Modify
|
||||
</a>
|
||||
|
@ -5,8 +5,14 @@
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage"/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
|
@ -3,14 +3,24 @@
|
||||
@model BTCPayServer.Models.PaymentRequestViewModels.UpdatePaymentRequestViewModel
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(PaymentRequestsNavPages.Create, (string.IsNullOrEmpty(Model.Id) ? "Create" : "Edit") + " Payment Request");
|
||||
ViewData["Title"] = (string.IsNullOrEmpty(Model.Id) ? "Create" : "Edit") + " Payment Request";
|
||||
}
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<hr class="primary">
|
||||
</div>
|
||||
</div>
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form method="post" action="@Url.Action("EditPaymentRequest", "PaymentRequest", new { id = Model.Id}, Context.Request.Scheme)">
|
||||
@ -76,7 +86,7 @@
|
||||
<div class="form-group">
|
||||
<label asp-for="CustomCSSLink" class="control-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
<span class="fa fa-question-circle-o" title="More information..."></span>
|
||||
</a>
|
||||
<input asp-for="CustomCSSLink" class="form-control" />
|
||||
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||
@ -90,25 +100,28 @@
|
||||
<button type="submit" class="btn btn-primary" id="SaveButton">Save</button>
|
||||
@if (!string.IsNullOrEmpty(Model.Id))
|
||||
{
|
||||
<a class="btn btn-secondary" target="_blank" asp-action="ViewPaymentRequest" asp-route-id="@Context.GetRouteValue("id")" id="@Model.Id" name="ViewAppButton">View</a>
|
||||
<a class="btn btn-secondary" target="_blank" asp-action="ViewPaymentRequest" asp-route-id="@this.Context.GetRouteValue("id")" id="@Model.Id" name="ViewAppButton">View</a>
|
||||
<a class="btn btn-secondary"
|
||||
target="_blank"
|
||||
asp-action="ListInvoices"
|
||||
asp-controller="Invoice"
|
||||
asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(Model.Id)}")">Invoices</a>
|
||||
<a class="btn btn-secondary" asp-route-id="@Context.GetRouteValue("id")" asp-action="ClonePaymentRequest" id="@Model.Id">Clone</a>
|
||||
<a class="btn btn-secondary" asp-route-id="@this.Context.GetRouteValue("id")" asp-action="ClonePaymentRequest" id="@Model.Id">Clone</a>
|
||||
@if (!Model.Archived)
|
||||
{
|
||||
<a class="btn btn-secondary" data-toggle="tooltip" title="Archive this payment request so that it does not appear in the payment request list by default" asp-route-id="@Context.GetRouteValue("id")" asp-controller="PaymentRequest" asp-action="TogglePaymentRequestArchival">Archive</a>
|
||||
<a class="btn btn-secondary" data-toggle="tooltip" title="Archive this payment request so that it does not appear in the payment request list by default" asp-route-id="@this.Context.GetRouteValue("id")" asp-controller="PaymentRequest" asp-action="TogglePaymentRequestArchival">Archive</a>
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="btn btn-secondary" data-toggle="tooltip" title="Unarchive this payment request" asp-route-id="@Context.GetRouteValue("id")" asp-controller="PaymentRequest" asp-action="TogglePaymentRequestArchival">Unarchive</a>
|
||||
<a class="btn btn-secondary" data-toggle="tooltip" title="Unarchive this payment request" asp-route-id="@this.Context.GetRouteValue("id")" asp-controller="PaymentRequest" asp-action="TogglePaymentRequestArchival">Unarchive</a>
|
||||
|
||||
}
|
||||
}
|
||||
<a asp-action="GetPaymentRequests" class="text-muted ml-3">Back to list</a>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<a asp-action="GetPaymentRequests">Back to List</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,25 +6,35 @@
|
||||
}
|
||||
<section>
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<h2 class="mb-0">
|
||||
@ViewData["Title"]
|
||||
<small>
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-12 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 section-heading">
|
||||
<h2>Payment Requests</h2>
|
||||
<hr class="primary">
|
||||
<p>
|
||||
Create, search or pay a payment request.
|
||||
<a href="https://docs.btcpayserver.org/PaymentRequests/" class="ml-1" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
</small>
|
||||
</h2>
|
||||
<a asp-action="EditPaymentRequest" class="btn btn-primary mt-3 mt-sm-0" role="button" id="CreatePaymentRequest">
|
||||
<span class="fa fa-plus"></span>
|
||||
Create a payment request
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6 mb-3 ml-auto">
|
||||
<div class="col-12 col-md-4 col-lg-6 mb-3">
|
||||
<a asp-action="EditPaymentRequest" class="btn btn-primary" role="button" id="CreatePaymentRequest">
|
||||
<span class="fa fa-plus"></span>
|
||||
Create a payment request
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12 col-md-8 col-lg-6 mb-3">
|
||||
<form asp-action="GetPaymentRequests" method="get">
|
||||
<input type="hidden" asp-for="Count"/>
|
||||
<input type="hidden" asp-for="TimezoneOffset" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
@using BTCPayServer.Services.Invoices
|
||||
@using BTCPayServer.Client.Models
|
||||
@model BTCPayServer.Models.PaymentRequestViewModels.ViewPaymentRequestViewModel
|
||||
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
||||
@inject BTCPayServer.HostedServices.CssThemeManager themeManager
|
||||
@ -196,7 +197,7 @@
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" model="@(new ViewDataDictionary(ViewData){ { "Margin", "mb-4" } })" />
|
||||
@await Html.PartialAsync("_StatusMessage", new ViewDataDictionary(ViewData){ { "Margin", "mb-4" } })
|
||||
<div class="row">
|
||||
<div class="col col-12 col-lg-6 mb-4">
|
||||
<div class="jumbotron h-100 m-0 p-sm-5">
|
||||
|
@ -1 +0,0 @@
|
||||
@using BTCPayServer.Views.PaymentRequest
|
@ -76,7 +76,7 @@
|
||||
|
||||
<main class="flex-grow-1 py-4">
|
||||
<div class="container">
|
||||
<partial name="_StatusMessage" model="@(new ViewDataDictionary(ViewData){ { "Margin", "mb-4" } })" />
|
||||
@await Html.PartialAsync("_StatusMessage", new ViewDataDictionary(ViewData){ { "Margin", "mb-4" } })
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
@Html.ValidationSummary(string.Empty, new { @class = "alert alert-danger mb-4 pb-0 text-center" })
|
||||
|
@ -1,29 +1,45 @@
|
||||
@model LndServicesViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"C-Lightning {Model.ConnectionType}");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<h4>C-Lightning @Model.ConnectionType</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<span>BTCPay exposes Clightning-Rest's service for outside consumption, you will find connection information here.<br /></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>Compatible wallets</h5>
|
||||
<div class="form-group">
|
||||
<h5>Compatible wallets</h5>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="https://github.com/ZeusLN/zeus" target="_blank" class="d-inline-block mr-3 mb-3 text-center">
|
||||
<img src="~/img/zeus.jpg" width="100" height="100" asp-append-version="true" alt="Zeus" />
|
||||
<div class="mt-2">Zeus</div>
|
||||
</a>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://github.com/ZeusLN/zeus" target="_blank">
|
||||
<img src="~/img/zeus.jpg" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://github.com/ZeusLN/zeus" target="_blank">Zeus</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@ -131,9 +147,9 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
@if (Model.QRCode != null)
|
||||
@if(Model.QRCode != null)
|
||||
{
|
||||
<script type="text/javascript" src="~/js/qrcode.js" asp-append-version="true"></script>
|
||||
<script type="text/javascript">
|
||||
|
@ -1,9 +1,10 @@
|
||||
@model LightningWalletServices
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "BTCPay Server Configurator");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<h4>BTCPay Server Configurator</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@ -27,5 +28,6 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
}
|
||||
|
@ -2,16 +2,18 @@
|
||||
@model BTCPayServer.Controllers.ServerController.CreateTemporaryFileUrlViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Create temporary file link");
|
||||
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="IsDownload"></label>
|
||||
@ -22,12 +24,12 @@
|
||||
<label asp-for="TimeAmount" class="control-label"></label>
|
||||
<div class="input-group">
|
||||
|
||||
<input type="number" asp-for="TimeAmount" class="form-control">
|
||||
<input type="number" asp-for="TimeAmount" class="form-control">
|
||||
<div class="input-group-append">
|
||||
<select asp-for="TimeType" asp-items="@Html.GetEnumSelectList<ServerController.CreateTemporaryFileUrlViewModel.TmpFileTimeType>()" class="custom-select"></select>
|
||||
<select asp-for="TimeType" asp-items="@Html.GetEnumSelectList< ServerController.CreateTemporaryFileUrlViewModel.TmpFileTimeType>()" class="custom-select"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<span asp-validation-for="TimeAmount" class="text-danger"></span>
|
||||
<span asp-validation-for="TimeType" class="text-danger"></span>
|
||||
</div>
|
||||
@ -37,5 +39,5 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
@model BTCPayServer.Controllers.RegisterFromAdminViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Users, "Create account");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Users, $"Users - Create account");
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
@ -1,22 +1,27 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.DynamicDnsViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Dynamic DNS Service");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>Dynamic DNS Service</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
@if (!this.ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<input type="hidden" asp-for="Modify"/>
|
||||
<input type="hidden" asp-for="Modify" />
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.ServiceUrl"></label>
|
||||
<input id="ServiceUrl" asp-for="Settings.ServiceUrl" class="form-control" placeholder="Url"/>
|
||||
<input id="ServiceUrl" asp-for="Settings.ServiceUrl" class="form-control" placeholder="Url" />
|
||||
<p class="form-text text-muted">
|
||||
Well-known Dynamic DNS providers are:
|
||||
@for (int i = 0; i < Model.KnownServices.Length; i++)
|
||||
@ -29,7 +34,7 @@
|
||||
<label asp-for="Settings.Hostname"></label>
|
||||
@if (Model.Modify)
|
||||
{
|
||||
<input asp-for="Settings.Hostname" class="form-control" readonly placeholder="Hostname"/>
|
||||
<input asp-for="Settings.Hostname" class="form-control" readonly placeholder="Hostname" />
|
||||
<p class="form-text text-muted">
|
||||
<span>The DNS record has been refreshed: </span>
|
||||
@if (Model.LastUpdated != null)
|
||||
@ -40,23 +45,23 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<input asp-for="Settings.Hostname" class="form-control" placeholder="Hostname"/>
|
||||
<input asp-for="Settings.Hostname" class="form-control" placeholder="Hostname" />
|
||||
<span asp-validation-for="Settings.Hostname" class="text-danger"></span>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Login"></label>
|
||||
<input asp-for="Settings.Login" class="form-control" placeholder="Login"/>
|
||||
<input asp-for="Settings.Login" class="form-control" placeholder="Login" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Password"></label>
|
||||
<input asp-for="Settings.Password" class="form-control" placeholder="Password"/>
|
||||
<input asp-for="Settings.Password" class="form-control" placeholder="Password" />
|
||||
</div>
|
||||
@if (Model.Modify)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Enabled"></label>
|
||||
<input asp-for="Settings.Enabled" class="form-check-inline" type="checkbox"/>
|
||||
<input asp-for="Settings.Enabled" class="form-check-inline" type="checkbox" />
|
||||
</div>
|
||||
}
|
||||
<button name="command" class="btn btn-primary" type="submit" value="Save">Save</button>
|
||||
|
@ -1,9 +1,11 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.DynamicDnsViewModel[]
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Dynamic DNS Settings");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>Dynamic DNS Settings</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
|
@ -1,20 +1,21 @@
|
||||
@model BTCPayServer.Storage.Services.Providers.AmazonS3Storage.Configuration.AmazonS3StorageConfiguration
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Amazon S3 Storage");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Storage - Amazon S3");
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="ContainerName"></label>
|
||||
<input class="form-control" asp-for="ContainerName"/>
|
||||
<input class="form-control" asp-for="ContainerName" />
|
||||
<span asp-validation-for="ContainerName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -44,16 +45,16 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ChunkedUploadThreshold"></label>
|
||||
<input class="form-control" type="number" asp-for="ChunkedUploadThreshold"/>
|
||||
<input class="form-control" type="number" asp-for="ChunkedUploadThreshold"/>
|
||||
<span asp-validation-for="ChunkedUploadThreshold" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true">Change Storage provider</a>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true" >Change Storage provider</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
@model BTCPayServer.Storage.Services.Providers.AzureBlobStorage.Configuration.AzureBlobStorageConfiguration
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Azure Blob Storage");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Storage - Azure Blob Storage");
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="ContainerName"></label>
|
||||
<input class="form-control" asp-for="ContainerName"/>
|
||||
<input class="form-control" asp-for="ContainerName" />
|
||||
<span asp-validation-for="ContainerName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -24,11 +25,11 @@
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true">Change Storage provider</a>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true" >Change Storage provider</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
@model BTCPayServer.Storage.Services.Providers.FileSystemStorage.Configuration.FileSystemStorageConfiguration
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Local Filesystem Storage");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Storage - Local Filesystem");
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>Any uploaded files are being saved on the same machine that hosts BTCPay; please pay attention to your storage space.</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<a asp-action="Storage" asp-route-forceChoice="true">Change Storage provider</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
@model BTCPayServer.Storage.Services.Providers.GoogleCloudStorage.Configuration.GoogleCloudStorageConfiguration
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Google Cloud Storage");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"Storage - Google Cloud Storage");
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label asp-for="ContainerName"></label>
|
||||
<input class="form-control" asp-for="ContainerName"/>
|
||||
<input class="form-control" asp-for="ContainerName" />
|
||||
<span asp-validation-for="ContainerName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -34,11 +34,11 @@
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true">Change Storage provider</a>
|
||||
<a asp-action="Storage" asp-route-forceChoice="true" >Change Storage provider</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -3,9 +3,5 @@
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Emails);
|
||||
}
|
||||
|
||||
<partial name="EmailsBody" model="Model" />
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
|
||||
<partial name="EmailsBody" model="@Model"/>
|
||||
|
@ -1,16 +1,16 @@
|
||||
@model ViewFilesViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Files, "File Storage");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Files);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<p>
|
||||
Change your <a asp-action="Services" asp-route-returnurl="@ViewData["ReturnUrl"]">external storage service</a> provider.
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-upload-files-to-btcpay" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
</p>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h4>File Storage</h4>
|
||||
<div class="form-group">
|
||||
<span>Change your <a asp-action="Services" asp-route-returnurl="@ViewData["ReturnUrl"]">external storage service</a> provider</span>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-upload-files-to-btcpay" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
</div>
|
||||
|
||||
@if (Model.Files.Any())
|
||||
{
|
||||
@ -81,16 +81,23 @@ else
|
||||
|
||||
@if (Model.StorageConfigured)
|
||||
{
|
||||
<form asp-action="CreateFile" method="post" enctype="multipart/form-data">
|
||||
<h4 class="mt-5 mb-3">Upload File</h4>
|
||||
<div class="card">
|
||||
<form asp-action="CreateFile" method="post" enctype="multipart/form-data">
|
||||
|
||||
<div class="custom-file mb-3">
|
||||
<input type="file" class="custom-file-input" name="file" id="file" required>
|
||||
<label class="custom-file-label" for="customFile">Choose file</label>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h3 class="header">Upload File</h3>
|
||||
|
||||
<button class="btn btn-primary" role="button"><span class="fa fa-plus"></span> Upload file</button>
|
||||
</form>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" name="file" id="file" required>
|
||||
<label class="custom-file-label" for="customFile">Choose file</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-primary" role="button"><span class="fa fa-plus"></span> Upload file</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<script>
|
||||
|
@ -1,28 +1,34 @@
|
||||
@model ChargeServiceViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "Lightning charge service");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>Lightning charge service</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<p>Lightning charge is a simple API for invoicing on lightning network, you can use it with several plugins:</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/ElementsProject/woocommerce-gateway-lightning" target="_blank">WooCommerce Lightning Gateway</a>: A comprehensive e-commerce application that integrates with stock-management and order-tracking systems</li>
|
||||
<li><a href="https://github.com/ElementsProject/nanopos" target="_blank">Nanopos</a>: A simple point-of-sale system for fixed-price goods</li>
|
||||
<li><a href="https://github.com/ElementsProject/filebazaar" target="_blank">FileBazaar</a>: A system for selling files such as documents, images, and videos</li>
|
||||
<li><a href="https://github.com/ElementsProject/wordpress-lightning-publisher" target="_blank">Lightning Publisher for WordPress</a>: A patronage model for unlocking WordPress blog entries</li>
|
||||
<li><a href="https://github.com/ElementsProject/paypercall" target="_blank">Paypercall</a>: A programmer’s toolkit for Lightning that enables micropayments for individual API calls</li>
|
||||
<li><a href="https://github.com/ElementsProject/ifpaytt" target="_blank">Ifpaytt</a>: An extension of paypercall that allows web developers using IFTTT to request payments for service usage</li>
|
||||
<li><a href="https://github.com/ElementsProject/lightning-jukebox" target="_blank">Lightning Jukebox</a>: A fun demo that reimagines a classic technology for the Lightning Network</li>
|
||||
<li><a href="https://github.com/ElementsProject/nanotip" target="_blank">Nanotip</a>: The simple tip jar, rebuilt to issue Lightning Network invoices</li>
|
||||
</ul>
|
||||
<p>
|
||||
<span>Lightning charge is a simple API for invoicing on lightning network, you can use it with several plugins:</span>
|
||||
<ul>
|
||||
<li><a href="https://github.com/ElementsProject/woocommerce-gateway-lightning" target="_blank">WooCommerce Lightning Gateway</a>: A comprehensive e-commerce application that integrates with stock-management and order-tracking systems</li>
|
||||
<li><a href="https://github.com/ElementsProject/nanopos" target="_blank">Nanopos</a>: A simple point-of-sale system for fixed-price goods</li>
|
||||
<li><a href="https://github.com/ElementsProject/filebazaar" target="_blank">FileBazaar</a>: A system for selling files such as documents, images, and videos</li>
|
||||
<li><a href="https://github.com/ElementsProject/wordpress-lightning-publisher" target="_blank">Lightning Publisher for WordPress</a>: A patronage model for unlocking WordPress blog entries</li>
|
||||
<li><a href="https://github.com/ElementsProject/paypercall" target="_blank">Paypercall</a>: A programmer’s toolkit for Lightning that enables micropayments for individual API calls</li>
|
||||
<li><a href="https://github.com/ElementsProject/ifpaytt" target="_blank">Ifpaytt</a>: An extension of paypercall that allows web developers using IFTTT to request payments for service usage</li>
|
||||
<li><a href="https://github.com/ElementsProject/lightning-jukebox" target="_blank">Lightning Jukebox</a>: A fun demo that reimagines a classic technology for the Lightning Network</li>
|
||||
<li><a href="https://github.com/ElementsProject/nanotip" target="_blank">Nanotip</a>: The simple tip jar, rebuilt to issue Lightning Network invoices</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,11 @@
|
||||
@model LightningWalletServices
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, Model.WalletName);
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>@Model.WalletName</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
@ -17,22 +19,25 @@
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<h5>Browser connection</h5>
|
||||
<p>
|
||||
<span>You can go to @Model.WalletName from your browser by <a href="@Model.ServiceLink">clicking here</a><br/></span>
|
||||
<span>You can go to @Model.WalletName from your browser by <a href="@Model.ServiceLink">clicking here</a><br /></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<h5>QR Code connection</h5>
|
||||
<p>
|
||||
<span>You can use QR Code to connect to your @Model.WalletName from your mobile.<br/></span>
|
||||
<span>You can use QR Code to connect to your @Model.WalletName from your mobile.<br /></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -40,7 +45,7 @@
|
||||
{
|
||||
<div class="form-group">
|
||||
<form method="get">
|
||||
<input type="hidden" asp-for="ShowQR" value="true"/>
|
||||
<input type="hidden" asp-for="ShowQR" value="true" />
|
||||
<button type="submit" class="btn btn-primary">Show Confidential QR Code</button>
|
||||
</form>
|
||||
</div>
|
||||
@ -57,7 +62,7 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
|
@ -88,6 +88,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<style>
|
||||
.version-switch .nav-link { display: inline; }
|
||||
.version-switch .nav-link.active { display: none; }
|
||||
@ -116,7 +118,7 @@
|
||||
|
||||
@if (Model.Installed.Any())
|
||||
{
|
||||
<h2 class="mb-4">Installed Plugins</h2>
|
||||
<h3 class="mb-3">Installed Plugins</h3>
|
||||
<div class="row mb-4">
|
||||
@foreach (var plugin in Model.Installed)
|
||||
{
|
||||
@ -233,10 +235,9 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (availableAndNotInstalled.Any())
|
||||
{
|
||||
<h2 class="mb-4">Available Plugins</h2>
|
||||
<h3 class="mb-3">Available Plugins</h3>
|
||||
<div class="row mb-4">
|
||||
@foreach (var pluginT in availableAndNotInstalled)
|
||||
{
|
||||
@ -249,7 +250,7 @@
|
||||
@plugin.Version
|
||||
@if (pluginT.Item2)
|
||||
{
|
||||
<div class="badge badge-light ml-2" data-toggle="tooltip" title="This plugin has been recommended to be installed by your deployment method." class="text-nowrap">Recommended <span class="fa fa-question-circle-o text-secondary"></span></div>
|
||||
<div class="badge badge-light ml-2" data-toggle="tooltip" title="This plugin has been recommended to be installed by your deployment method." class="text-nowrap">Recommended <span class="fa fa-question-circle-o"></span></div>
|
||||
}
|
||||
</h5>
|
||||
<p class="card-text">@plugin.Description</p>
|
||||
|
@ -23,68 +23,79 @@
|
||||
var sortByAsc = "Sort by ascending...";
|
||||
}
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between mb-4">
|
||||
<h2 class="mb-0">@ViewData["Title"]</h2>
|
||||
<a asp-action="CreateUser" class="btn btn-primary" role="button" id="CreateUser">
|
||||
<span class="fa fa-plus"></span> Add User
|
||||
</a>
|
||||
</div>
|
||||
<form
|
||||
asp-action="ListUsers"
|
||||
asp-route-sortOrder="@(userEmailSortOrder)"
|
||||
>
|
||||
<div class="input-group">
|
||||
<input asp-for="SearchTerm" class="form-control" placeholder="Search by email..." />
|
||||
<div class="input-group-append">
|
||||
<button type="submit" class="btn btn-secondary" title="Search by email">
|
||||
<span class="fa fa-search"></span> Search
|
||||
</button>
|
||||
</div>
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
<div class="row button-row">
|
||||
<div class="col-12 col-sm-4 col-lg-6 mb-3">
|
||||
<a asp-action="CreateUser" class="btn btn-primary" role="button" id="CreateUser">
|
||||
<span class="fa fa-plus"></span> Add User
|
||||
</a>
|
||||
</div>
|
||||
<span asp-validation-for="SearchTerm" class="text-danger"></span>
|
||||
</form>
|
||||
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a
|
||||
asp-action="ListUsers"
|
||||
asp-route-sortOrder="@(nextUserEmailSortOrder ?? "asc")"
|
||||
class="text-nowrap"
|
||||
title="@(nextUserEmailSortOrder == "desc" ? sortByAsc : sortByDesc)"
|
||||
>
|
||||
Email
|
||||
<span class="fa @(sortIconClass)" />
|
||||
</a>
|
||||
</th>
|
||||
<th>Created</th>
|
||||
<th>Verified</th>
|
||||
<th class="text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in Model.Users)
|
||||
{
|
||||
<tr>
|
||||
<td>@user.Email</td>
|
||||
<td>@user.Created?.ToBrowserDate()</td>
|
||||
<td class="text-center">
|
||||
@if (user.Verified)
|
||||
{
|
||||
<span class="text-success fa fa-check"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-danger fa fa-times"></span>
|
||||
}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a asp-action="User" asp-route-userId="@user.Id">Edit</a> <span> - </span> <a asp-action="DeleteUser" asp-route-userId="@user.Id">Remove</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-12 col-sm-8 col-lg-6 mb-3">
|
||||
<form
|
||||
asp-action="ListUsers"
|
||||
asp-route-sortOrder="@(userEmailSortOrder)"
|
||||
>
|
||||
<div class="input-group">
|
||||
<input asp-for="SearchTerm" class="form-control" placeholder="Search by email..." />
|
||||
<div class="input-group-append">
|
||||
<button type="submit" class="btn btn-secondary" title="Search by email">
|
||||
<span class="fa fa-search"></span> Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<span asp-validation-for="SearchTerm" class="text-danger"></span>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<vc:pager view-model="Model"></vc:pager>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-xl-8">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a
|
||||
asp-action="ListUsers"
|
||||
asp-route-sortOrder="@(nextUserEmailSortOrder ?? "asc")"
|
||||
class="text-nowrap"
|
||||
title="@(nextUserEmailSortOrder == "desc" ? sortByAsc : sortByDesc)"
|
||||
>
|
||||
Email
|
||||
<span class="fa @(sortIconClass)" />
|
||||
</a>
|
||||
</th>
|
||||
<th>Created</th>
|
||||
<th>Verified</th>
|
||||
<th class="text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in Model.Users)
|
||||
{
|
||||
<tr>
|
||||
<td>@user.Email</td>
|
||||
<td>@user.Created?.ToBrowserDate()</td>
|
||||
<td class="text-center">
|
||||
@if (user.Verified)
|
||||
{
|
||||
<span class="text-success fa fa-check"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="text-danger fa fa-times"></span>
|
||||
}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a asp-action="User" asp-route-userId="@user.Id">Edit</a> <span> - </span> <a asp-action="DeleteUser" asp-route-userId="@user.Id">Remove</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<vc:pager view-model="Model"></vc:pager>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,14 +1,23 @@
|
||||
@model LndSeedBackupViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "LND Seed Backup");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<h4>LND Seed Backup</h4>
|
||||
|
||||
@if (TempData.HasStatusMessage())
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-8 text-center">
|
||||
<partial name="_StatusMessage" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.IsWalletUnlockPresent)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<p>The LND seed backup is useful to recover funds of your LND wallet in case of a corruption of your server.</p>
|
||||
<p>The recovering process is documented by LND on <a href="https://github.com/lightningnetwork/lnd/blob/master/docs/recovery.md">this page</a>.</p>
|
||||
|
@ -1,150 +1,189 @@
|
||||
@model LndServicesViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, $"LND {Model.ConnectionType}");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
|
||||
<h4>LND @Model.ConnectionType</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<p>
|
||||
BTCPay exposes LND's @Model.ConnectionType service for outside consumption, you will find connection information here.
|
||||
</p>
|
||||
|
||||
<h4 class="mb-3">Compatible wallets</h4>
|
||||
|
||||
<div>
|
||||
@if (Model.Uri == null) // if GRPC
|
||||
{
|
||||
<a href="https://www.pebble.indiesquare.me/" target="_blank" class="d-inline-block mr-3 text-center">
|
||||
<img src="~/img/pebblewallet.jpg" width="100" height="100" asp-append-version="true" alt="Pebble" />
|
||||
<div class="mt-2">Pebble</div>
|
||||
</a>
|
||||
<a href="https://zaphq.io/" target="_blank" class="d-inline-block mr-3 text-center">
|
||||
<img src="~/img/zapwallet.jpg" width="100" height="100" asp-append-version="true" alt="Zap" />
|
||||
<div class="mt-2">Zap</div>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="https://lightningjoule.com/" target="_blank" class="d-inline-block mr-3 mb-3 text-center">
|
||||
<img src="~/img/joule.png" width="100" height="100" asp-append-version="true" alt="Joule" />
|
||||
<div class="mt-2">Joule</div>
|
||||
</a>
|
||||
<a href="https://github.com/ZeusLN/zeus" target="_blank" class="d-inline-block mr-3 mb-3 text-center">
|
||||
<img src="~/img/zeus.jpg" width="100" height="100" asp-append-version="true" alt="Zeus" />
|
||||
<div class="mt-2">Zeus</div>
|
||||
</a>
|
||||
}
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<span>BTCPay exposes LND's @Model.ConnectionType service for outside consumption, you will find connection information here.<br /></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-5 mb-3">QR Code connection</h4>
|
||||
<p>
|
||||
You can use this QR Code to connect external software to your LND instance.<br/>
|
||||
This QR Code is only valid for 10 minutes.
|
||||
</p>
|
||||
|
||||
@if (Model.QRCode == null)
|
||||
<div class="form-group">
|
||||
<h5>Compatible wallets</h5>
|
||||
</div>
|
||||
@if (Model.Uri == null) // if GRPC
|
||||
{
|
||||
<div class="form-group">
|
||||
<form method="post">
|
||||
<button type="submit" class="btn btn-primary">Show QR Code</button>
|
||||
</form>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://www.pebble.indiesquare.me/" target="_blank">
|
||||
<img src="~/img/pebblewallet.jpg" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://www.pebble.indiesquare.me/" target="_blank">Pebble</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://zaphq.io/" target="_blank">
|
||||
<img src="~/img/zapwallet.jpg" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://zaphq.io/" target="_blank">Zap</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="form-group">
|
||||
<div id="qrCode"></div>
|
||||
<div id="qrCodeData" data-url="@Model.QRCode"></div>
|
||||
</div>
|
||||
<p>See QR Code information by clicking <a href="#detailsQR" data-toggle="collapse">here</a>.</p>
|
||||
<div id="detailsQR" class="collapse">
|
||||
<div class="form-group">
|
||||
<label>QR Code data</label>
|
||||
<input asp-for="QRCode" readonly class="form-control"/>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://lightningjoule.com/" target="_blank">
|
||||
<img src="~/img/joule.png" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://lightningjoule.com/" target="_blank">Joule</a></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
Click <a href="@Model.QRCodeLink" target="_blank">here</a> to open the configuration file.
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://github.com/ZeusLN/zeus" target="_blank">
|
||||
<img src="~/img/zeus.jpg" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://github.com/ZeusLN/zeus" target="_blank">Zeus</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<h4 class="mt-5 mb-3">More details</h4>
|
||||
<p>Alternatively, you can see the settings by clicking <a href="#details" data-toggle="collapse">here</a>.</p>
|
||||
|
||||
<div id="details" class="collapse">
|
||||
@if (Model.Uri == null)
|
||||
<div class="form-group">
|
||||
<h5>QR Code connection</h5>
|
||||
<p>
|
||||
<span>You can use this QR Code to connect external software to your LND instance.<br /></span>
|
||||
<span>This QR Code is only valid for 10 minutes</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@if (Model.QRCode == null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Host"></label>
|
||||
<input asp-for="Host" readonly class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="SSL"></label>
|
||||
<input asp-for="SSL" disabled type="checkbox" class="form-check-inline"/>
|
||||
<form method="post">
|
||||
<button type="submit" class="btn btn-primary">Show QR Code</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Uri"></label>
|
||||
<input asp-for="Uri" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.Macaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Macaroon"></label>
|
||||
<input asp-for="Macaroon" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.AdminMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="AdminMacaroon"></label>
|
||||
<input asp-for="AdminMacaroon" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.InvoiceMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="InvoiceMacaroon"></label>
|
||||
<input asp-for="InvoiceMacaroon" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.ReadonlyMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="ReadonlyMacaroon"></label>
|
||||
<input asp-for="ReadonlyMacaroon" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.GRPCSSLCipherSuites != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="GRPCSSLCipherSuites"></label>
|
||||
<input asp-for="GRPCSSLCipherSuites" readonly class="form-control"/>
|
||||
</div>
|
||||
}
|
||||
@if (Model.CertificateThumbprint != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="CertificateThumbprint"></label>
|
||||
<input asp-for="CertificateThumbprint" readonly class="form-control"/>
|
||||
<div id="qrCode"></div>
|
||||
<div id="qrCodeData" data-url="@Model.QRCode"></div>
|
||||
</div>
|
||||
<p>See QR Code information by clicking <a href="#detailsQR" data-toggle="collapse">here</a></p>
|
||||
<div id="detailsQR" class="collapse">
|
||||
<div class="form-group">
|
||||
<label>QR Code data</label>
|
||||
<input asp-for="QRCode" readonly class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
Click <a href="@Model.QRCodeLink" target="_blank">here</a> to open the configuration file.
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<h5>More details...</h5>
|
||||
<p>Alternatively, you can see the settings by clicking <a href="#details" data-toggle="collapse">here</a></p>
|
||||
</div>
|
||||
<div id="details" class="collapse">
|
||||
@if (Model.Uri == null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Host"></label>
|
||||
<input asp-for="Host" readonly class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="SSL"></label>
|
||||
<input asp-for="SSL" disabled type="checkbox" class="form-check-inline" />
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Uri"></label>
|
||||
<input asp-for="Uri" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.Macaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Macaroon"></label>
|
||||
<input asp-for="Macaroon" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.AdminMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="AdminMacaroon"></label>
|
||||
<input asp-for="AdminMacaroon" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.InvoiceMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="InvoiceMacaroon"></label>
|
||||
<input asp-for="InvoiceMacaroon" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.ReadonlyMacaroon != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="ReadonlyMacaroon"></label>
|
||||
<input asp-for="ReadonlyMacaroon" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.GRPCSSLCipherSuites != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="GRPCSSLCipherSuites"></label>
|
||||
<input asp-for="GRPCSSLCipherSuites" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
@if (Model.CertificateThumbprint != null)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="CertificateThumbprint"></label>
|
||||
<input asp-for="CertificateThumbprint" readonly class="form-control" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
@if(Model.QRCode != null)
|
||||
{
|
||||
<script type="text/javascript" src="~/js/qrcode.js" asp-append-version="true"></script>
|
||||
<script type="text/javascript">
|
||||
new QRCode(document.getElementById("qrCode"), {
|
||||
new QRCode(document.getElementById("qrCode"),
|
||||
{
|
||||
text: @Safe.Json(Model.QRCode),
|
||||
width: 200,
|
||||
height: 200,
|
||||
|
@ -1,9 +1,9 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.LogsViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Logs, "Logs");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Logs);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<ul class="list-unstyled">
|
||||
@foreach (var file in Model.LogFiles)
|
||||
@ -41,5 +41,5 @@
|
||||
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.MaintenanceViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Maintenance, "Maintenance");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Maintenance);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<form method="post">
|
||||
<div class="row mb-5">
|
||||
<div class="col-lg-9 col-xl-8">
|
||||
<h4 class="mb-3">Change domain name</h4>
|
||||
<p>You can change the domain name of your server by following <a href="https://docs.btcpayserver.org/ChangeDomain" target="_blank">this guide</a>.</p>
|
||||
<div class="form-group">
|
||||
<h5>Change domain name</h5>
|
||||
<span>You can change the domain name of your server by following <a href="https://docs.btcpayserver.org/ChangeDomain" target="_blank">this guide</a></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-inline">
|
||||
@ -20,25 +22,28 @@
|
||||
</div>
|
||||
<span asp-validation-for="DNSDomain" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-5 mb-3">Update</h4>
|
||||
<p class="text-secondary">Update to the latest version of BTCPay server.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-lg-9 col-xl-8">
|
||||
<h5>Update</h5>
|
||||
<p class="text-secondary mb-2">Update to the latest version of BTCPay server.</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<button name="command" type="submit" class="btn btn-primary" value="update" disabled="@(Model.CanUseSSH ? null : "disabled")">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-5 mb-3">Restart</h4>
|
||||
<p class="text-secondary">Restart BTCPay server and related services.</p>
|
||||
<h5 class="mt-5">Restart</h5>
|
||||
<p class="text-secondary mb-2">Restart BTCPay server and related services.</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<button name="command" type="submit" class="btn btn-primary" value="restart" disabled="@(Model.CanUseSSH ? null : "disabled")">Restart</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-5 mb-3">Clean</h4>
|
||||
<p class="text-secondary">Delete unused docker images present on your system.</p>
|
||||
<h5 class="mt-5">Clean</h5>
|
||||
<p class="text-secondary mb-2">Delete unused docker images present on your system.</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<button name="command" type="submit" class="btn btn-secondary" value="clean" disabled="@(Model.CanUseSSH ? null : "disabled")">Clean</button>
|
||||
@ -49,5 +54,5 @@
|
||||
</form>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
@model LightningWalletServices
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, Model.WalletName);
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>@Model.WalletName</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
@ -16,31 +18,49 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
|
||||
<h4 class="mb-3">Full node connection</h4>
|
||||
<p>This page exposes information to connect remotely to your full node via the P2P protocol.</p>
|
||||
|
||||
<h4 class="mb-3">Compatible wallets</h4>
|
||||
<div>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.greenaddress.greenbits_android_wallet" target="_blank" class="d-inline-block mr-3 mb-3 text-center">
|
||||
<img src="~/img/GreenWallet.png" width="100" height="100" asp-append-version="true" alt="Blockstream Green" />
|
||||
<div class="mt-2">Blockstream Green</div>
|
||||
</a>
|
||||
<a href="https://www.wasabiwallet.io/" target="_blank" class="d-inline-block mr-3 mb-3 text-center">
|
||||
<img src="~/img/wasabi.png" width="100" height="100" asp-append-version="true" alt="Wasabi Wallet" />
|
||||
<div class="mt-2">Wasabi Wallet</div>
|
||||
</a>
|
||||
<div class="form-group">
|
||||
<h5>Full node connection</h5>
|
||||
<p>
|
||||
<span>This page exposes information to connect remotely to your full node via the P2P protocol.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h5>Compatible wallets</h5>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://play.google.com/store/apps/details?id=com.greenaddress.greenbits_android_wallet" target="_blank">
|
||||
<img src="~/img/GreenWallet.png" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://play.google.com/store/apps/details?id=com.greenaddress.greenbits_android_wallet" target="_blank">Blockstream Green Wallet</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
<a href="https://www.wasabiwallet.io/" target="_blank">
|
||||
<img src="~/img/wasabi.png" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://www.wasabiwallet.io/" target="_blank">Wasabi Wallet</a> <a href="https://www.reddit.com/r/WasabiWallet/comments/aqlyia/how_to_connect_wasabi_wallet_to_my_own_full/" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
<h4 class="mt-5 mb-3">QR Code connection</h4>
|
||||
<p>You can use QR Code to connect to @Model.WalletName with compatible wallets.</p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h5>QR Code connection</h5>
|
||||
<p>
|
||||
<span>You can use QR Code to connect to @Model.WalletName with compatible wallets.<br /></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@if (!Model.ShowQR)
|
||||
{
|
||||
@ -70,7 +90,7 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Policies);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["Title"]</h2>
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
@ -14,22 +14,18 @@
|
||||
}
|
||||
|
||||
<form method="post">
|
||||
<div class="form-group mb-5">
|
||||
<h4 class="mb-3">Existing User Settings</h4>
|
||||
<div class="form-group mb-4">
|
||||
<h5>Existing User Settings</h5>
|
||||
<div class="form-check my-1">
|
||||
<input asp-for="AllowLightningInternalNodeForAll" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="AllowLightningInternalNodeForAll" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-LightningNetwork/#how-many-users-can-use-lightning-network-in-btcpay" target="_blank">\
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-LightningNetwork/#how-many-users-can-use-lightning-network-in-btcpay" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="AllowLightningInternalNodeForAll" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-check my-1">
|
||||
<input asp-for="AllowHotWalletForAll" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="AllowHotWalletForAll" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/CreateWallet/#requirements-to-create-wallets" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/CreateWallet/#requirements-to-create-wallets" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="AllowHotWalletForAll" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-check my-1">
|
||||
@ -39,8 +35,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-5">
|
||||
<h4 class="mb-3">New User Settings</h4>
|
||||
<div class="form-group mb-4">
|
||||
<h5>New User Settings</h5>
|
||||
<div class="form-check my-1">
|
||||
@{
|
||||
var emailSettings = (await _SettingsRepository.GetSettingAsync<EmailSettings>()) ?? new EmailSettings();
|
||||
@ -50,9 +46,7 @@
|
||||
}
|
||||
<input asp-for="RequiresConfirmedEmail" type="checkbox" class="form-check-input" disabled="@(isEmailConfigured ? null : "disabled")"/>
|
||||
<label asp-for="RequiresConfirmedEmail" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-allow-registration-on-my-btcpay-server" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-allow-registration-on-my-btcpay-server" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="RequiresConfirmedEmail" class="text-danger"></span>
|
||||
@if (!isEmailConfigured)
|
||||
{
|
||||
@ -74,28 +68,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-5">
|
||||
<h4 class="mb-3">Notification Settings</h4>
|
||||
<div class="form-group mb-4">
|
||||
<h5>Notification Settings</h5>
|
||||
<div class="form-check my-1">
|
||||
<input asp-for="DisableInstantNotifications" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="DisableInstantNotifications" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Notifications/#notifications" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/Notifications/#notifications" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="DisableInstantNotifications" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-check my-1">
|
||||
<input asp-for="DisableStoresToUseServerEmailSettings" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="DisableStoresToUseServerEmailSettings" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/Notifications/#server-emails" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/Notifications/#server-emails" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="DisableStoresToUseServerEmailSettings" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-5">
|
||||
<h4 class="mb-3">Maintenance Settings</h4>
|
||||
<div class="form-group mb-4">
|
||||
<h5>Maintenance Settings</h5>
|
||||
@if (ViewBag.UpdateUrlPresent)
|
||||
{
|
||||
<div class="form-check my-1">
|
||||
@ -107,14 +97,12 @@
|
||||
<div class="form-check my-1">
|
||||
<input asp-for="DiscourageSearchEngines" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="DiscourageSearchEngines" class="form-check-label"></label>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-hide-my-btcpay-server-from-search-engines" target="_blank">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<a href="https://docs.btcpayserver.org/FAQ/FAQ-ServerSettings/#how-to-hide-my-btcpay-server-from-search-engines" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
|
||||
<span asp-validation-for="DiscourageSearchEngines" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mb-3">Customization Settings</h4>
|
||||
<h5>Customization Settings</h5>
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="RootAppId"></label>
|
||||
|
@ -1,9 +1,11 @@
|
||||
@model LightningWalletServices
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, Model.WalletName);
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>@Model.WalletName</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
@ -16,37 +18,55 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
|
||||
<h4 class="mb-3">Full node connection</h4>
|
||||
<p>This page exposes information to connect remotely to your full node via the RPC protocol.</p>
|
||||
|
||||
<h4 class="mb-3">Compatible wallets</h4>
|
||||
<div>
|
||||
<a href="https://apps.apple.com/us/app/fully-noded/id1436425586" target="_blank" class="d-inline-block mr-3 text-center">
|
||||
<img src="~/img/fullynoded.png" width="100" height="100" asp-append-version="true" alt="Fully Noded" />
|
||||
<div class="mt-2">Fully Noded</div>
|
||||
</a>
|
||||
<a href="https://github.com/cryptoadvance/specter-desktop" target="_blank" class="d-inline-block mr-3 text-center">
|
||||
<img src="~/img/specter.png" width="100" height="100" asp-append-version="true" alt="Specter Desktop" />
|
||||
<div class="mt-2">Specter Desktop</div>
|
||||
</a>
|
||||
<div class="form-group">
|
||||
<h5>Full node connection</h5>
|
||||
<p>
|
||||
<span>This page exposes information to connect remotely to your full node via the RPC protocol.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h5>Compatible wallets</h5>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-3 ml-auto text-center">
|
||||
<a href="https://apps.apple.com/us/app/fully-noded/id1436425586" target="_blank">
|
||||
<img src="~/img/fullynoded.png" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://apps.apple.com/us/app/fully-noded/id1436425586" target="_blank">Fully Noded</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
<a href="https://github.com/cryptoadvance/specter-desktop" target="_blank">
|
||||
<img src="~/img/Specter.png" height="100" asp-append-version="true" />
|
||||
</a>
|
||||
<p><a href="https://github.com/cryptoadvance/specter-desktop" target="_blank">Specter</a></p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
<h4 class="mt-5 mb-3">QR Code connection</h4>
|
||||
<p>You can use QR Code to connect to @Model.WalletName with compatible wallets.</p>
|
||||
</div>
|
||||
<div class="col-lg-3 mr-auto text-center">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h5>QR Code connection</h5>
|
||||
<p>
|
||||
<span>You can use QR Code to connect to @Model.WalletName with compatible wallets.<br /></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@if (!Model.ShowQR)
|
||||
{
|
||||
<div class="form-group">
|
||||
<form method="get">
|
||||
<input type="hidden" asp-for="ShowQR" value="true"/>
|
||||
<input type="hidden" asp-for="ShowQR" value="true" />
|
||||
<button type="submit" class="btn btn-primary">Show Confidential QR Code</button>
|
||||
</form>
|
||||
</div>
|
||||
@ -61,7 +81,7 @@
|
||||
<div id="detailsQR" class="collapse">
|
||||
<div class="form-group">
|
||||
<label>QR Code data</label>
|
||||
<input asp-for="ServiceLink" readonly class="form-control"/>
|
||||
<input asp-for="ServiceLink" readonly class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@ -70,7 +90,7 @@
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
||||
@if (Model.ShowQR)
|
||||
{
|
||||
|
@ -1,11 +1,19 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.SSHServiceViewModel
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services, "SSH settings");
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||
|
||||
<h4>SSH settings</h4>
|
||||
<partial name="_StatusMessage" />
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<p>
|
||||
@ -13,10 +21,6 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user