Merge branch 'master' into feature/lndseedbackup

This commit is contained in:
rockstardev 2019-11-14 21:02:56 -06:00
commit 7bce316e78
100 changed files with 10524 additions and 18163 deletions

View file

@ -4,7 +4,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.9" Condition="'$(TargetFramework)' == 'netcoreapp2.1'" />
<FrameworkReference Include="Microsoft.AspNetCore.App" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<PackageReference Include="NBXplorer.Client" Version="2.0.0.21" />
<FrameworkReference Include="Microsoft.AspNetCore.App" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<PackageReference Include="NBXplorer.Client" Version="2.0.0.23" />
</ItemGroup>
</Project>

View file

@ -8,11 +8,11 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.9" Condition="'$(TargetFramework)' == 'netcoreapp2.1'" />
<FrameworkReference Include="Microsoft.AspNetCore.App" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<FrameworkReference Include="Microsoft.AspNetCore.App" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.1" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.5.3" />
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.6.3" />
</ItemGroup>
<ItemGroup>

View file

@ -36,27 +36,27 @@ namespace BTCPayServer.Services.Rates
{
await new SynchronizationContextRemover();
var rates = await _ExchangeAPI.GetTickersAsync();
lock (notFoundSymbols)
{
var exchangeRates =
rates
var exchangeRateTasks = rates
.Where(t => t.Value.Ask != 0m && t.Value.Bid != 0m)
.Select(t => CreateExchangeRate(t))
.Where(t => t != null)
.ToArray();
return new ExchangeRates(exchangeRates);
}
.Select(t => CreateExchangeRate(t));
var exchangeRates = await Task.WhenAll(exchangeRateTasks);
return new ExchangeRates(exchangeRates
.Where(t => t != null)
.ToArray());
}
// ExchangeSymbolToGlobalSymbol throws exception which would kill perf
ConcurrentDictionary<string, string> notFoundSymbols = new ConcurrentDictionary<string, string>();
private ExchangeRate CreateExchangeRate(KeyValuePair<string, ExchangeTicker> ticker)
private async Task<ExchangeRate> CreateExchangeRate(KeyValuePair<string, ExchangeTicker> ticker)
{
if (notFoundSymbols.ContainsKey(ticker.Key))
if (notFoundSymbols.TryGetValue(ticker.Key, out _))
return null;
try
{
var tickerName = _ExchangeAPI.ExchangeSymbolToGlobalSymbol(ticker.Key);
var tickerName = await _ExchangeAPI.ExchangeMarketSymbolToGlobalMarketSymbolAsync(ticker.Key);
if (!CurrencyPair.TryParse(tickerName, out var pair))
{
notFoundSymbols.TryAdd(ticker.Key, ticker.Key);

View file

@ -91,7 +91,7 @@ namespace BTCPayServer.Services.Rates
{
var result = new ExchangeRates();
var symbols = await GetSymbolsAsync(cancellationToken);
var normalizedPairsList = symbols.Where(s => !notFoundSymbols.ContainsKey(s)).Select(s => _Helper.NormalizeSymbol(s)).ToList();
var normalizedPairsList = symbols.Where(s => !notFoundSymbols.ContainsKey(s)).Select(s => _Helper.NormalizeMarketSymbol(s)).ToList();
var csvPairsList = string.Join(",", normalizedPairsList);
JToken apiTickers = await MakeJsonRequestAsync<JToken>("/0/public/Ticker", null, new Dictionary<string, object> { { "pair", csvPairsList } }, cancellationToken: cancellationToken);
var tickers = new List<KeyValuePair<string, ExchangeTicker>>();
@ -114,7 +114,7 @@ namespace BTCPayServer.Services.Rates
}
else
{
global = _Helper.ExchangeSymbolToGlobalSymbol(symbol);
global = await _Helper.ExchangeMarketSymbolToGlobalMarketSymbolAsync(symbol);
}
if (CurrencyPair.TryParse(global, out var pair))
result.Add(new ExchangeRate("kraken", pair.Inverse(), new BidAsk(ticker.Bid, ticker.Ask)));
@ -142,10 +142,10 @@ namespace BTCPayServer.Services.Rates
Last = last,
Volume = new ExchangeVolume
{
BaseVolume = ticker["v"][1].ConvertInvariant<decimal>(),
BaseSymbol = symbol,
ConvertedVolume = ticker["v"][1].ConvertInvariant<decimal>() * last,
ConvertedSymbol = symbol,
BaseCurrencyVolume = ticker["v"][1].ConvertInvariant<decimal>(),
BaseCurrency = symbol,
QuoteCurrencyVolume = ticker["v"][1].ConvertInvariant<decimal>() * last,
QuoteCurrency = symbol,
Timestamp = DateTime.UtcNow
}
};

View file

@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Rating;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Services.Rates
{
public class NdaxRateProvider : IRateProvider, IHasExchangeName
{
private readonly HttpClient _httpClient;
public NdaxRateProvider(HttpClient httpClient)
{
_httpClient = httpClient ?? new HttpClient();
}
public string ExchangeName => "ndax";
public async Task<ExchangeRates> GetRatesAsync(CancellationToken cancellationToken)
{
var response = await _httpClient.GetAsync("https://ndax.io/api/returnTicker", cancellationToken);
var jobj = await response.Content.ReadAsAsync<Dictionary<string, JObject>>(cancellationToken);
return new ExchangeRates(jobj.Select(pair => new ExchangeRate(ExchangeName, CurrencyPair.Parse(pair.Key),
new BidAsk(GetValue(pair.Value["highestBid"]), GetValue(pair.Value["lowestAsk"])))));
}
private static decimal GetValue(JToken jobj)
{
return string.IsNullOrEmpty(jobj.ToString()) ? 0 : jobj.Value<decimal>();
}
}
}

View file

@ -9,6 +9,7 @@ using ExchangeSharp;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MemoryCache = Microsoft.Extensions.Caching.Memory.MemoryCache;
namespace BTCPayServer.Services.Rates
{
@ -103,7 +104,8 @@ namespace BTCPayServer.Services.Rates
Providers.Add("binance", new ExchangeSharpRateProvider("binance", new ExchangeBinanceAPI(), true));
Providers.Add("bittrex", new ExchangeSharpRateProvider("bittrex", new ExchangeBittrexAPI(), true));
Providers.Add("poloniex", new ExchangeSharpRateProvider("poloniex", new ExchangePoloniexAPI(), true));
Providers.Add("hitbtc", new ExchangeSharpRateProvider("hitbtc", new ExchangeHitbtcAPI(), false));
Providers.Add("hitbtc", new ExchangeSharpRateProvider("hitbtc", new ExchangeHitBTCAPI(), true));
Providers.Add("ndax", new ExchangeSharpRateProvider("ndax", new ExchangeNDAXAPI(), true));
// Cryptopia is often not available
// Disabled because of https://twitter.com/Cryptopia_NZ/status/1085084168852291586
@ -115,7 +117,6 @@ namespace BTCPayServer.Services.Rates
Providers.Add("bylls", new ByllsRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BYLLS")));
Providers.Add("bitbank", new BitbankRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITBANK")));
Providers.Add("bitpay", new BitpayRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_BITPAY")));
Providers.Add("ndax", new NdaxRateProvider(_httpClientFactory?.CreateClient("EXCHANGE_NDAX")));
// Those exchanges make multiple requests when calling GetTickers so we remove them
//DirectProviders.Add("gemini", new ExchangeSharpRateProvider("gemini", new ExchangeGeminiAPI()));
@ -172,7 +173,7 @@ namespace BTCPayServer.Services.Rates
// Add other exchanges supported here
exchanges.Add(new CoinAverageExchange(CoinAverageRateProvider.CoinAverageName, "Coin Average", $"https://apiv2.bitcoinaverage.com/indices/global/ticker/short"));
exchanges.Add(new CoinAverageExchange("bylls", "Bylls", "https://bylls.com/api/price?from_currency=BTC&to_currency=CAD"));
//exchanges.Add(new CoinAverageExchange("ndax", "NDAX", "https://ndax.io/api/returnTicker")); Buggy
exchanges.Add(new CoinAverageExchange("ndax", "NDAX", "https://ndax.io/api/returnTicker"));
exchanges.Add(new CoinAverageExchange("bitbank", "Bitbank", "https://public.bitbank.cc/prices"));
return exchanges;

View file

@ -230,9 +230,10 @@ namespace BTCPayServer.Tests
rateProvider.Providers.Add("bittrex", bittrex);
}
Logs.Tester.LogInformation("Waiting site is operational...");
await WaitSiteIsOperational();
Logs.Tester.LogInformation("Site is now operational");
}
private async Task WaitSiteIsOperational()

View file

@ -35,7 +35,7 @@ namespace BTCPayServer.Tests
Logs.LogProvider = new XUnitLogProvider(helper);
}
[Fact]
[Fact(Timeout = TestTimeout)]
[Trait("Integration", "Integration")]
public async Task CanCreateAndDeleteCrowdfundApp()
{
@ -75,7 +75,7 @@ namespace BTCPayServer.Tests
[Fact]
[Fact(Timeout = TestTimeout)]
[Trait("Integration", "Integration")]
public async Task CanContributeOnlyWhenAllowed()
{
@ -100,7 +100,7 @@ namespace BTCPayServer.Tests
crowdfundViewModel.Enabled = false;
crowdfundViewModel.EndDate = null;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
var anonAppPubsController = tester.PayTester.GetController<AppsPublicController>();
var publicApps = user.GetController<AppsPublicController>();
@ -126,7 +126,7 @@ namespace BTCPayServer.Tests
crowdfundViewModel.StartDate= DateTime.Today.AddDays(2);
crowdfundViewModel.Enabled = true;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
Assert.IsType<NotFoundObjectResult>(await anonAppPubsController.ContributeToCrowdfund(appId, new ContributeToCrowdfund()
{
Amount = new decimal(0.01)
@ -138,7 +138,7 @@ namespace BTCPayServer.Tests
crowdfundViewModel.EndDate= DateTime.Today.AddDays(-1);
crowdfundViewModel.Enabled = true;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
Assert.IsType<NotFoundObjectResult>(await anonAppPubsController.ContributeToCrowdfund(appId, new ContributeToCrowdfund()
{
Amount = new decimal(0.01)
@ -152,7 +152,7 @@ namespace BTCPayServer.Tests
crowdfundViewModel.TargetAmount = 1;
crowdfundViewModel.TargetCurrency = "BTC";
crowdfundViewModel.EnforceTargetAmount = true;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
Assert.IsType<NotFoundObjectResult>(await anonAppPubsController.ContributeToCrowdfund(appId, new ContributeToCrowdfund()
{
Amount = new decimal(1.01)
@ -167,7 +167,7 @@ namespace BTCPayServer.Tests
}
}
[Fact]
[Fact(Timeout = TestTimeout)]
[Trait("Integration", "Integration")]
public async Task CanComputeCrowdfundModel()
{
@ -195,7 +195,7 @@ namespace BTCPayServer.Tests
crowdfundViewModel.TargetCurrency = "BTC";
crowdfundViewModel.UseAllStoreInvoices = true;
crowdfundViewModel.EnforceTargetAmount = true;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
var anonAppPubsController = tester.PayTester.GetController<AppsPublicController>();
var publicApps = user.GetController<AppsPublicController>();
@ -253,7 +253,7 @@ namespace BTCPayServer.Tests
Assert.Contains(AppService.GetAppInternalTag(appId), invoiceEntity.InternalTags);
crowdfundViewModel.UseAllStoreInvoices = false;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
Logs.Tester.LogInformation("Because UseAllStoreInvoices is false, let's make sure the invoice is not tagged");
invoice = user.BitPay.CreateInvoice(new Invoice()
@ -272,7 +272,7 @@ namespace BTCPayServer.Tests
Logs.Tester.LogInformation("After turning setting a softcap, let's check that only actual payments are counted");
crowdfundViewModel.EnforceTargetAmount = false;
crowdfundViewModel.UseAllStoreInvoices = true;
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel).Result);
Assert.IsType<RedirectToActionResult>(apps.UpdateCrowdfund(appId, crowdfundViewModel, "save").Result);
invoice = user.BitPay.CreateInvoice(new Invoice()
{
Buyer = new Buyer() { email = "test@fwf.com" },

View file

@ -60,6 +60,7 @@ using Microsoft.Extensions.DependencyInjection;
using NBXplorer.DerivationStrategy;
using BTCPayServer.U2F.Models;
using BTCPayServer.Security.Bitpay;
using MemoryCache = Microsoft.Extensions.Caching.Memory.MemoryCache;
namespace BTCPayServer.Tests
{
@ -702,7 +703,7 @@ namespace BTCPayServer.Tests
FullNotifications = true,
ExtendedNotifications = true
});
BitcoinUrlBuilder url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP21);
BitcoinUrlBuilder url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP21, tester.NetworkProvider.BTC.NBitcoinNetwork);
bool receivedPayment = false;
bool paid = false;
bool confirmed = false;
@ -2020,7 +2021,7 @@ noninventoryitem:
//verify invoices where created
invoices = user.BitPay.GetInvoices();
Assert.Equal(2, invoices.Count(invoice => invoice.ItemCode.Equals("noninventoryitem")));
var inventoryItemInvoice = invoices.SingleOrDefault(invoice => invoice.ItemCode.Equals("inventoryitem"));
var inventoryItemInvoice = Assert.Single(invoices.Where(invoice => invoice.ItemCode.Equals("inventoryitem")));
Assert.NotNull(inventoryItemInvoice);
//let's mark the inventoryitem invoice as invalid, thsi should return the item to back in stock

View file

@ -8,19 +8,15 @@
<Compile Remove="Build\**" />
<Compile Remove="Storage\Services\Providers\GoogleCloudStorage\**" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
<Compile Remove="wwwroot\bundles\jqueryvalidate\**" />
<Compile Remove="wwwroot\css\**" />
<Compile Remove="wwwroot\vendor\jquery-nice-select\**" />
<Content Remove="Build\**" />
<Content Remove="wwwroot\bundles\jqueryvalidate\**" />
<Content Remove="wwwroot\css\**" />
<Content Remove="wwwroot\vendor\jquery-nice-select\**" />
<EmbeddedResource Remove="Build\**" />
<EmbeddedResource Remove="wwwroot\bundles\jqueryvalidate\**" />
<EmbeddedResource Remove="wwwroot\css\**" />
<EmbeddedResource Remove="wwwroot\vendor\jquery-nice-select\**" />
<None Remove="Build\**" />
<None Remove="wwwroot\bundles\jqueryvalidate\**" />
<None Remove="wwwroot\css\**" />
<None Remove="wwwroot\vendor\jquery-nice-select\**" />
</ItemGroup>
<ItemGroup>
@ -80,7 +76,7 @@
</ItemGroup>
<ItemGroup>
<None Include="wwwroot\vendor\bootstrap4-creativestart\creative.js" />
<None Include="wwwroot\main\bootstrap4-creativestart\creative.js" />
<None Include="wwwroot\vendor\font-awesome\fonts\fontawesome-webfont.svg" />
<None Include="wwwroot\vendor\font-awesome\fonts\fontawesome-webfont.woff2" />
<None Include="wwwroot\vendor\font-awesome\less\animated.less" />

View file

@ -58,7 +58,16 @@ namespace BTCPayServer.Configuration
public static string GetDebugLog(IConfiguration configuration)
{
return configuration.GetValue<string>("debuglog", null);
var logfile = configuration.GetValue<string>("debuglog", null);
if (!string.IsNullOrEmpty(logfile))
{
if (!Path.IsPathRooted(logfile))
{
var networkType = DefaultConfiguration.GetNetworkType(configuration);
logfile = Path.Combine(configuration.GetDataDir(networkType), logfile);
}
}
return logfile;
}
public static LogEventLevel GetDebugLogLevel(IConfiguration configuration)
{
@ -207,11 +216,6 @@ namespace BTCPayServer.Configuration
LogFile = GetDebugLog(conf);
if (!string.IsNullOrEmpty(LogFile))
{
if (!Path.IsPathRooted(LogFile))
LogFile = Path.Combine(DataDir, LogFile);
}
if (!string.IsNullOrEmpty(LogFile))
{
Logs.Configuration.LogInformation("LogFile: " + LogFile);
Logs.Configuration.LogInformation("Log Level: " + GetDebugLogLevel(conf));

View file

@ -364,7 +364,7 @@ namespace BTCPayServer.Controllers
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Register(string returnUrl = null, bool logon = true)
public async Task<IActionResult> Register(string returnUrl = null, bool logon = true, bool useBasicLayout = false)
{
var policies = await _SettingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
if (policies.LockSubscription && !User.IsInRole(Roles.ServerAdmin))
@ -372,6 +372,7 @@ namespace BTCPayServer.Controllers
ViewData["ReturnUrl"] = returnUrl;
ViewData["Logon"] = logon.ToString(CultureInfo.InvariantCulture).ToLowerInvariant();
ViewData["AllowIsAdmin"] = _Options.AllowAdminRegistration;
ViewData["UseBasicLayout"] = useBasicLayout;
return View();
}

View file

@ -68,7 +68,7 @@ namespace BTCPayServer.Controllers
}
[HttpPost]
[Route("{appId}/settings/crowdfund")]
public async Task<IActionResult> UpdateCrowdfund(string appId, UpdateCrowdfundViewModel vm)
public async Task<IActionResult> UpdateCrowdfund(string appId, UpdateCrowdfundViewModel vm, string command)
{
if (!string.IsNullOrEmpty( vm.TargetCurrency) && _currencies.GetCurrencyData(vm.TargetCurrency, false) == null)
ModelState.AddModelError(nameof(vm.TargetCurrency), "Invalid currency");
@ -156,16 +156,25 @@ namespace BTCPayServer.Controllers
app.TagAllInvoices = vm.UseAllStoreInvoices;
app.SetSettings(newSettings);
await _AppService.UpdateOrCreateApp(app);
_EventAggregator.Publish(new AppUpdated()
if (command == "save")
{
AppId = appId,
StoreId = app.StoreDataId,
Settings = newSettings
});
TempData[WellKnownTempData.SuccessMessage] = "App updated";
return RedirectToAction(nameof(UpdateCrowdfund), new {appId});
await _AppService.UpdateOrCreateApp(app);
_EventAggregator.Publish(new AppUpdated()
{
AppId = appId,
StoreId = app.StoreDataId,
Settings = newSettings
});
TempData[WellKnownTempData.SuccessMessage] = "App updated";
return RedirectToAction(nameof(UpdateCrowdfund), new { appId });
}
else if (command == "viewapp")
{
return RedirectToAction(nameof(AppsPublicController.ViewCrowdfund), "AppsPublic", new { appId });
}
return NotFound();
}
}
}

View file

@ -165,26 +165,39 @@ namespace BTCPayServer.Controllers
}
}
var store = await _AppService.GetStore(app);
var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
try
{
ItemCode = choice?.Id,
ItemDesc = title,
Currency = settings.Currency,
Price = price,
BuyerEmail = email,
OrderId = orderId,
NotificationURL =
string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
NotificationEmail = settings.NotificationEmail,
RedirectURL = redirectUrl ?? Request.GetDisplayUrl(),
FullNotifications = true,
ExtendedNotifications = true,
PosData = string.IsNullOrEmpty(posData) ? null : posData,
RedirectAutomatically = settings.RedirectAutomatically,
}, store, HttpContext.Request.GetAbsoluteRoot(),
new List<string>() { AppService.GetAppInternalTag(appId) },
cancellationToken);
return RedirectToAction(nameof(InvoiceController.Checkout), "Invoice", new { invoiceId = invoice.Data.Id });
var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
{
ItemCode = choice?.Id,
ItemDesc = title,
Currency = settings.Currency,
Price = price,
BuyerEmail = email,
OrderId = orderId,
NotificationURL =
string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
NotificationEmail = settings.NotificationEmail,
RedirectURL = redirectUrl ?? Request.GetDisplayUrl(),
FullNotifications = true,
ExtendedNotifications = true,
PosData = string.IsNullOrEmpty(posData) ? null : posData,
RedirectAutomatically = settings.RedirectAutomatically,
}, store, HttpContext.Request.GetAbsoluteRoot(),
new List<string>() { AppService.GetAppInternalTag(appId) },
cancellationToken);
return RedirectToAction(nameof(InvoiceController.Checkout), "Invoice", new { invoiceId = invoice.Data.Id });
}
catch (BitpayHttpException e)
{
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Html = e.Message.Replace("\n", "<br />", StringComparison.OrdinalIgnoreCase),
Severity = StatusMessageModel.StatusSeverity.Error,
AllowDismiss = true
});
return RedirectToAction(nameof(ViewPointOfSale), new { appId = appId });
}
}
[HttpGet]

View file

@ -121,7 +121,7 @@ namespace BTCPayServer.Controllers
try
{
BitcoinUrlBuilder urlBuilder = new BitcoinUrlBuilder(vm.BitpayLink);
BitcoinUrlBuilder urlBuilder = new BitcoinUrlBuilder(vm.BitpayLink, Network.Main);
#pragma warning disable CS0618 // Type or member is obsolete
if (!urlBuilder.PaymentRequestUrl.DnsSafeHost.EndsWith("bitpay.com", StringComparison.OrdinalIgnoreCase))
{

View file

@ -398,11 +398,15 @@ namespace BTCPayServer.Controllers
[BitpayAPIConstraint(false)]
public async Task<IActionResult> ListInvoices(string searchTerm = null, int skip = 0, int count = 50, int timezoneOffset = 0)
{
var fs = new SearchString(searchTerm);
var storeIds = fs.GetFilterArray("storeid") != null ? fs.GetFilterArray("storeid") : new List<string>().ToArray();
var model = new InvoicesModel
{
SearchTerm = searchTerm,
Skip = skip,
Count = count,
StoreIds = storeIds,
TimezoneOffset = timezoneOffset
};
InvoiceQuery invoiceQuery = GetInvoiceQuery(searchTerm, timezoneOffset);

View file

@ -21,19 +21,29 @@ namespace BTCPayServer.HostedServices
{
public void Update(ThemeSettings data)
{
if (String.IsNullOrWhiteSpace(data.ThemeCssUri))
_themeUri = "/main/themes/classic.css";
else
_themeUri = data.ThemeCssUri;
if (String.IsNullOrWhiteSpace(data.BootstrapCssUri))
_bootstrapUri = "/vendor/bootstrap4/css/bootstrap.css?v=" + DateTime.Now.Ticks;
_bootstrapUri = "/main/bootstrap/bootstrap.css";
else
_bootstrapUri = data.BootstrapCssUri;
if (String.IsNullOrWhiteSpace(data.CreativeStartCssUri))
_creativeStartUri = "/vendor/bootstrap4-creativestart/creative.css?v=" + DateTime.Now.Ticks;
_creativeStartUri = "/main/bootstrap4-creativestart/creative.css";
else
_creativeStartUri = data.CreativeStartCssUri;
FirstRun = data.FirstRun;
}
private string _themeUri;
public string ThemeUri
{
get { return _themeUri; }
}
private string _bootstrapUri;
public string BootstrapUri
{
@ -77,7 +87,7 @@ namespace BTCPayServer.HostedServices
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
@ -94,6 +104,10 @@ namespace BTCPayServer.HostedServices
{
policies.Clear();
}
if (manager.ThemeUri != null && Uri.TryCreate(manager.ThemeUri, UriKind.Absolute, out uri))
{
policies.Clear();
}
}
}
}

View file

@ -13,8 +13,8 @@ namespace BTCPayServer.Models.InvoicingModels
public int Total { get; set; }
public string SearchTerm { get; set; }
public int? TimezoneOffset { get; set; }
public List<InvoiceModel> Invoices { get; set; } = new List<InvoiceModel>();
public string[] StoreIds { get; set; }
}
public class InvoiceModel

View file

@ -78,5 +78,6 @@ namespace BTCPayServer.Models.InvoicingModels
public string RootPath { get; set; }
public decimal CoinSwitchAmountMarkupPercentage { get; set; }
public bool RedirectAutomatically { get; set; }
public string RateBaseAmount { get; set; } = "1";
}
}

View file

@ -185,6 +185,7 @@ namespace BTCPayServer.Payments.Lightning
model.BtcPaid = Money.Parse(model.BtcPaid).ToUnit(MoneyUnit.Satoshi).ToString(CultureInfo.InvariantCulture);
model.NetworkFee = new Money(model.NetworkFee, MoneyUnit.BTC).ToUnit(MoneyUnit.Satoshi);
model.OrderAmount = Money.Parse(model.OrderAmount).ToUnit(MoneyUnit.Satoshi).ToString(CultureInfo.InvariantCulture);
model.RateBaseAmount = Money.FromUnit(1, MoneyUnit.BTC).Satoshi.ToString(CultureInfo.InvariantCulture);
}
}
public override string GetCryptoImage(PaymentMethodId paymentMethodId)

View file

@ -21,6 +21,7 @@ using BTCPayServer.Models.InvoicingModels;
using BTCPayServer.Logging;
using BTCPayServer.Payments;
using System.Data.Common;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Services.Invoices
{
@ -448,8 +449,19 @@ retry:
#pragma warning disable CS0618
entity.Payments = invoice.Payments.Select(p =>
{
var paymentEntity = ToObject<PaymentEntity>(p.Blob, null);
paymentEntity.Network = _Networks.GetNetwork<BTCPayNetworkBase>(paymentEntity.CryptoCode);
var unziped = ZipUtils.Unzip(p.Blob);
var cryptoCode = GetCryptoCode(unziped);
var network = _Networks.GetNetwork<BTCPayNetworkBase>(cryptoCode);
PaymentEntity paymentEntity = null;
if (network == null)
{
paymentEntity = NBitcoin.JsonConverters.Serializer.ToObject<PaymentEntity>(unziped, null);
}
else
{
paymentEntity = network.ToObject<PaymentEntity>(unziped);
}
paymentEntity.Network = network;
paymentEntity.Accounted = p.Accounted;
// PaymentEntity on version 0 does not have their own fee, because it was assumed that the payment method have fixed fee.
// We want to hide this legacy detail in InvoiceRepository, so we fetch the fee from the PaymentMethod and assign it to the PaymentEntity.
@ -491,6 +503,13 @@ retry:
return entity;
}
private string GetCryptoCode(string json)
{
if (JObject.Parse(json).TryGetValue("cryptoCode", out var v) && v.Type == JTokenType.String)
return v.Value<string>();
return "BTC";
}
private IQueryable<Data.InvoiceData> GetInvoiceQuery(ApplicationDbContext context, InvoiceQuery queryObject)
{
IQueryable<Data.InvoiceData> query = context.Invoices;
@ -688,7 +707,7 @@ retry:
PaymentData data = new PaymentData
{
Id = paymentData.GetPaymentId(),
Blob = ToBytes(entity, null),
Blob = ToBytes(entity, network),
InvoiceDataId = invoiceId,
Accounted = accounted
};
@ -717,7 +736,7 @@ retry:
var data = new PaymentData();
data.Id = paymentData.GetPaymentId();
data.Accounted = payment.Accounted;
data.Blob = ToBytes(payment, null);
data.Blob = ToBytes(payment, payment.Network);
context.Attach(data);
context.Entry(data).Property(o => o.Accounted).IsModified = true;
context.Entry(data).Property(o => o.Blob).IsModified = true;
@ -732,14 +751,6 @@ retry:
entity.Networks = _Networks;
return entity;
}
private T ToObject<T>(byte[] value, BTCPayNetworkBase network)
{
if (network == null)
{
return NBitcoin.JsonConverters.Serializer.ToObject<T>(ZipUtils.Unzip(value), null);
}
return network.ToObject<T>(ZipUtils.Unzip(value));
}
private byte[] ToBytes<T>(T obj, BTCPayNetworkBase network = null)
{

View file

@ -9,6 +9,11 @@ namespace BTCPayServer.Services
{
public class ThemeSettings
{
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
[MaxLength(500)]
[Display(Name = "Select Theme")]
public string ThemeCssUri { get; set; }
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
[MaxLength(500)]
[Display(Name = "Custom bootstrap CSS file")]

View file

@ -157,14 +157,22 @@ namespace BTCPayServer.U2F
var authenticationRequest =
UserAuthenticationRequests[userId].First(f =>
f.KeyHandle.Equals(authenticateResponse.KeyHandle, StringComparison.InvariantCulture));
var registration = new DeviceRegistration(device.KeyHandle, device.PublicKey,
device.AttestationCert, Convert.ToUInt32(device.Counter));
var authentication = new StartedAuthentication(authenticationRequest.Challenge,
authenticationRequest.AppId, authenticationRequest.KeyHandle);
global::U2F.Core.Crypto.U2F.FinishAuthentication(authentication, authenticateResponse, registration);
var challengeAuthenticationRequestMatch = UserAuthenticationRequests[userId].First(f =>
f.Challenge.Equals( authenticateResponse.GetClientData().Challenge, StringComparison.InvariantCulture));
if (authentication.Challenge != challengeAuthenticationRequestMatch.Challenge)
{
authentication = new StartedAuthentication(challengeAuthenticationRequestMatch.Challenge, authenticationRequest.AppId, authenticationRequest.KeyHandle);
}
global::U2F.Core.Crypto.U2F.FinishAuthentication(authentication, authenticateResponse, registration);
UserAuthenticationRequests.AddOrReplace(userId, new List<U2FDeviceAuthenticationRequest>());

View file

@ -13,12 +13,14 @@
</div>
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="row justify-content-center">
<div class="col-md-6 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
<div class="col-md-4">
</div>
<div class="row justify-content-center">
<div class="col-md-6">
<form asp-action="ForgotPassword" method="post">
<h4>Start password reset</h4>
<hr />

View file

@ -5,8 +5,8 @@
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>

View file

@ -3,8 +3,8 @@
<section>
<div class="container-fluid">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">Two-factor authentication</h2>
<div class="col-lg-12 section-heading">
<h2>Two-factor authentication</h2>
<hr class="primary">
</div>
</div>
@ -28,7 +28,7 @@
<div class="form-group">
<button type="submit" class="btn btn-primary">Log in</button>
</div>
</form>
</div>
<div class="row">

View file

@ -8,8 +8,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<p>
You have requested to login with a recovery code. This login will not be remembered until you provide

View file

@ -5,7 +5,10 @@
<input type="hidden" asp-for="Challenge" />
<input type="hidden" asp-for="AppId" />
<input type="hidden" asp-for="DeviceResponse" />
<input type="hidden" asp-for="Challenges" />
@for (int i = 0; i < Model.Challenges.Count; i++)
{
@Html.HiddenFor(m => m.Challenges[i])
}
<input type="hidden" asp-for="UserId" />
<input type="hidden" asp-for="RememberMe" />
</form>
@ -13,10 +16,10 @@
<section>
<div class="container-fluid">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading"><span class="fa fa-spinner fa-spin"></span>U2F Authentication</h2>
<div class="col-lg-12 section-heading">
<h2><span class="fa fa-spinner fa-spin"></span>U2F Authentication</h2>
<hr class="primary">
<p>Insert your U2F device or a hardware wallet into your computer's USB port. If it has a button, tap on it.</p>
</div>
</div>
@ -32,7 +35,7 @@
1: 'Unknown error, try again',
2: "Bad request error, try again",
3: "This key isn't supported, please try another one",
4: 'The device is already registered, please login',
4: 'The device is not registered, please try another one',
5: 'Authentication timed out. Please reload to try again.'
};
setTimeout(function() {

View file

@ -1,10 +1,12 @@
@model RegisterViewModel
@{
ViewData["Title"] = "Register";
Layout = "_WelcomeLayout.cshtml";
var useBasicLayout = ViewData["UseBasicLayout"] is true;
Layout = useBasicLayout ? "../Shared/_Layout.cshtml" : "_WelcomeLayout.cshtml";
}
<div class="modal-dialog modal-login">
<!-- We want to center the dialog box in case we are not using the Welcome layout -->
<div class="modal-dialog @(useBasicLayout ? "modal-dialog-centered" : "")">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Create account</h4>

View file

@ -8,24 +8,24 @@
@if (Model.LoginWith2FaViewModel != null && Model.LoginWithU2FViewModel != null)
{
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</div>
}else if (Model.LoginWith2FaViewModel == null && Model.LoginWithU2FViewModel == null)
{
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading bg-danger">Both 2FA and U2F Authentication Methods are not available. Please go to the https endpoint</h2>
<div class="col-lg-12 section-heading">
<h2 class="bg-danger">Both 2FA and U2F Authentication Methods are not available. Please go to the https endpoint</h2>
<hr class="danger">
</div>
</div>
}
<div class="row justify-content-center">
@if (Model.LoginWith2FaViewModel != null)
{

View file

@ -7,28 +7,61 @@
<head>
<partial name="Header" />
<link href="~/main/css/Montserrat.css" rel="stylesheet">
<link href="~/main/fonts/Montserrat.css" rel="stylesheet">
<style>
.content-wrapper {
padding: 70px 0;
}
@@media screen and (min-width: 768px) {
.content-wrapper {
padding: 100px 0;
}
}
.col-head {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
text-align: center;
}
@@media screen and (min-width: 768px) {
.col-head {
text-align: left;
flex-direction: row;
justify-content: start;
}
}
.head-logo {
height: 100px;
margin-right: 50px;
height: 70px;
margin-bottom: 1rem;
}
@@media screen and (min-width: 768px) {
.head-logo {
height: 100px;
margin-bottom: 0;
margin-right: 50px;
}
}
.lead-title {
font-family: Montserrat;
font-style: normal;
font-weight: bold;
font-size: 40px;
font-size: 24px;
line-height: 1.2;
/* or 150% */
letter-spacing: 0.1em;
color: #000000;
}
@@media screen and (min-width: 768px) {
.lead-title {
font-size: 40px;
}
}
.lead-login {
@ -39,7 +72,6 @@
line-height: 33px;
/* or 183% */
letter-spacing: 0.1em;
color: #000000;
}
.lead-h {
@ -52,12 +84,11 @@
/* identical to box height, or 129% */
letter-spacing: 0.1em;
text-transform: uppercase;
color: #000000;
}
</style>
</head>
<body class="bg-light">
<section>
<body>
<section class="content-wrapper">
<!-- Dummy navbar-brand, hackish way to keep test AssertNoError passing -->
<div class="navbar-brand" style="display:none;"></div>
<div class="container">
@ -71,7 +102,7 @@
<div class="col-md-7 order-md-1 order-2">
<hr class="primary ml-0" style="margin:30px auto;">
<p class="lead-login" style="margin-bottom:69px;">BTCPay Server lets you process Bitcoin transactions seemlessly, enabling global and near-instant peer-to-peer payments</p>
<h3 class="lead-h">Our supporters</h3>
<h3 class="lead-h">Our supporters <a href="https://foundation.btcpayserver.org/" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a></h3>
<div class="figure">
<a href="https://twitter.com/sqcrypto" target="_blank">
<img src="~/img/squarecrypto.svg" alt="Sponsor Square Crypto" height="75" />
@ -80,7 +111,15 @@
<a href="https://twitter.com/sqcrypto" class="text-muted small" target="_blank">Square Crypto</a>
</div>
</div>
<div class="figure ml-2">
<div class="figure ml-4">
<a href="https://www.dglab.com/en/" target="_blank">
<img src="~/img/dglab.svg" alt="Sponsor DG lab" height="75" />
</a>
<div class="figure-caption text-center">
<a href="https://www.dglab.com/en/" class="text-muted small" target="_blank">DG Lab</a>
</div>
</div>
<div class="figure ml-4">
<a href="https://acinq.co/" target="_blank">
<img src="~/img/acinq-logo.svg" alt="Sponsor ACINQ" height="75" />
</a>
@ -96,7 +135,10 @@
{
<div class="input-group form-group">
<div class="input-group-prepend">
<a href="@env.OnionUrl" class="input-group-text"><span class="input-group-addon"></span><img style="display:inline" src="~/img/icons/Onion_Color.svg" height="20" /></a>
<a href="@env.OnionUrl" class="input-group-text">
<span class="input-group-addon"></span>
<img src="~/img/icons/Onion_Color.svg" height="16" />
</a>
</div>
<input class="form-control" onClick="this.select();" type="text" style="font-size:0.75em;" value="@env.OnionUrl" readonly>
</div>

View file

@ -5,8 +5,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>

View file

@ -14,57 +14,58 @@
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<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 no-gutter" style="margin-bottom: 5px;">
<div class="col-lg-6">
<div class="row button-row">
<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/features/apps" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
</div>
</div>
<div class="row">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th>Store</th>
<th>Name</th>
<th>App type</th>
<th style="text-align:right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var app in Model.Apps)
{
<div class="col-lg-12">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<td>
@if (app.IsOwner)
{
<span><a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@app.StoreId">@app.StoreName</a></span>
}
else
{
<span>@app.StoreName</span>
}
</td>
<td>@app.AppName</td>
<td>@app.AppType</td>
<td style="text-align:right">
@if (app.IsOwner)
{
<a asp-action="@app.UpdateAction" asp-controller="Apps" asp-route-appId="@app.Id">Settings</a><span> - </span>
}
<a asp-action="@app.ViewAction" asp-controller="AppsPublic" asp-route-appId="@app.Id">View</a><span> - </span>
<a asp-action="DeleteApp" asp-route-appId="@app.Id">Remove</a>
</td>
<th>Store</th>
<th>Name</th>
<th>App type</th>
<th style="text-align:right">Actions</th>
</tr>
}
</tbody>
</table>
</thead>
<tbody>
@foreach (var app in Model.Apps)
{
<tr>
<td>
@if (app.IsOwner)
{
<span><a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@app.StoreId">@app.StoreName</a></span>
}
else
{
<span>@app.StoreName</span>
}
</td>
<td>@app.AppName</td>
<td>@app.AppType</td>
<td style="text-align:right">
@if (app.IsOwner)
{
<a asp-action="@app.UpdateAction" asp-controller="Apps" asp-route-appId="@app.Id">Settings</a><span> - </span>
}
<a asp-action="@app.ViewAction" asp-controller="AppsPublic" asp-route-appId="@app.Id">View</a><span> - </span>
<a asp-action="DeleteApp" asp-route-appId="@app.Id">Remove</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</section>

View file

@ -25,8 +25,8 @@
</div>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>
@ -215,9 +215,9 @@
</div>
<input type="hidden" asp-for="NotificationEmailWarning" />
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save Settings" id="SaveSettings" />
<button name="command" type="submit" class="btn btn-primary" value="save" id="SaveSettings">Save settings</button>
<a class="btn btn-secondary" target="_blank" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
<a class="btn btn-secondary" target="_blank" asp-action="ViewCrowdfund" asp-controller="AppsPublic" asp-route-appId="@Model.AppId" id="ViewApp">View App</a>
<button name="command" type="submit" value="viewapp" class="btn btn-secondary" id="ViewApp">View App</button>
<a class="btn btn-secondary" target="_blank" asp-action="ListApps">Back to the app list</a>
</div>
</form>

View file

@ -25,8 +25,8 @@
</div>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>

View file

@ -14,6 +14,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="@Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
<link href="@Context.Request.GetRelativePathOrAbsolute(themeManager.ThemeUri)" rel="stylesheet" />
@if (Model.CustomCSSLink != null)
{
<link href="@Model.CustomCSSLink" rel="stylesheet" />
@ -32,7 +33,7 @@
<bundle name="wwwroot/bundles/crowdfund-bundle.min.css"></bundle>
@if (!string.IsNullOrEmpty(Model.EmbeddedCSS))
{
@Safe.Raw($"<style>{Model.EmbeddedCSS}</style>");
@Safe.Raw($"<style>{Model.EmbeddedCSS}</style>");
}
</head>

View file

@ -22,6 +22,7 @@
<link rel="manifest" href="~/manifest.json">
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.ThemeUri)" rel="stylesheet" />
@if (Model.CustomCSSLink != null)
{
<link href="@Model.CustomCSSLink" rel="stylesheet" />
@ -47,15 +48,19 @@
max-width: 320px;
margin: auto;
}
.js-cart-item-count::-webkit-inner-spin-button,
.js-cart-item-count::-webkit-outer-spin-button {
.js-cart-item-count {
-moz-appearance:textfield;
margin: 0;
text-align: right;
}
.js-cart-item-count::-webkit-inner-spin-button,
.js-cart-item-count::-webkit-outer-spin-button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0;
}
</style>
@if (!string.IsNullOrEmpty(Model.EmbeddedCSS))
{
@ -69,10 +74,10 @@
<tr data-id="{id}">
{image}
<td class="align-middle pr-0 pl-2"><b>{title}</b></td>
<td class="align-middle px-0" align="right">
<td class="align-middle px-0">
<a class="js-cart-item-remove btn btn-link" href="#"><i class="fa fa-trash text-muted"></i></a>
</td>
<td class="align-middle px-0" align="right">
<td class="align-middle px-0">
<div class="input-group align-items-center">
<div class="input-group-prepend">
<a class="js-cart-item-minus btn btn-link px-2" href="#"><i class="fa fa-minus-circle fa-fw text-danger"></i></a>
@ -85,7 +90,7 @@
</div>
</div>
</td>
<td class="align-middle" align="right">{price}</td>
<td class="align-middle text-right">{price}</td>
</tr>
</script>
@ -112,7 +117,7 @@
<script id="template-cart-extra" type="text/template">
@if(Model.ShowCustomAmount){
<tr>
<td colspan="5" class="border-0 pb-0">
<th colspan="5" class="border-0 pb-0">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-shopping-cart fa-fw"></i></span>
@ -122,13 +127,13 @@
<a class="js-cart-custom-amount-remove btn btn-danger" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
</td>
</th>
</tr>
}
@if (@Model.ShowDiscount)
{
<tr>
<td colspan="5" class="border-top-0">
<th colspan="5" class="border-top-0">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-percent fa-fw"></i></span>
@ -138,7 +143,7 @@
<a class="js-cart-discount-remove btn btn-danger" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
</td>
</th>
</tr>
}
</script>
@ -147,10 +152,10 @@
@if (Model.EnableTips)
{
<tr class="h5">
<td colspan="5" class="border-top-0 pt-4">@Model.CustomTipText</td>
<th colspan="5" class="border-top-0 pt-4">@Model.CustomTipText</th>
</tr>
<tr>
<td colspan="5" class="border-0">
<th colspan="5" class="border-0">
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-money fa-fw"></i></span>
@ -173,18 +178,22 @@
}
</div>
</td>
</th>
</tr>}
</script>
<script id="template-cart-total" type="text/template">
<tr class="h4 table-light">
<td colspan="1" class="pb-4">Total</td>
<td colspan="4" align="right" class="pb-4">
<tr class="h4">
<th colspan="1" class="pb-4">Total</th>
<th colspan="4" class="pb-4 text-right">
<span class="js-cart-total">{total}</span>
</td>
</th>
</tr>
</script>
@if (this.TempData.HasStatusMessage())
{
<partial name="_StatusMessage" />
}
@if (Model.EnableShoppingCart)
{
@ -265,7 +274,7 @@
<div class="p-2 p-sm-4">
<div class="row">
<div class="col-sm-4 col-lg-2 order-sm-last text-right mb-2">
<a class="js-cart btn btn-lg btn-warning text-white text-right" href="#">
<a class="js-cart btn btn-lg btn-outline-primary" href="#">
<i class="fa fa-shopping-basket"></i>&nbsp;
<span class="badge badge-light badge-pill">
<span id="js-cart-items">0</span>
@ -314,7 +323,7 @@
<span class="text-muted small">@String.Format(Model.ButtonText, @item.Price.Formatted)</span>
@if (item.Inventory.HasValue)
{
<div class="w-100 pt-2 text-center text-muted">
@if (item.Inventory > 0)
{
@ -338,16 +347,16 @@
<!-- Sidebar -->
<nav id="sidebar" class="bg-dark">
<div class="bg-warning p-3 clearfix">
<div class="bg-primary p-3 clearfix">
<h3 class="text-white m-0 pull-left">Cart</h3>
<a class="js-cart btn btn-sm bg-white text-black pull-right ml-5" href="#">
<i class="fa fa-times fa-lg"></i>
</a>
<a class="js-cart-destroy btn bg-white text-danger pull-right" href="#" style="display: none;">Empty cart <i class="fa fa-trash fa-fw fa-lg"></i></a>
<a class="js-cart-destroy btn btn-danger pull-right" href="#" style="display: none;">Empty cart <i class="fa fa-trash fa-fw fa-lg"></i></a>
</div>
<table id="js-cart-list" class="table table-responsive bg-light mt-0 mb-0">
<thead class="thead-dark">
<table id="js-cart-list" class="table table-responsive bg-light text-secondary mt-0 mb-0">
<thead class="thead-light">
<tr>
<th colspan="3" width="55%">Product</th>
<th class="text-center" width="20%">
@ -362,7 +371,7 @@
</table>
<table id="js-cart-extra" class="table bg-light mt-0 mb-0">
<tbody></tbody>
<thead class="thead-light"></thead>
</table>
<button id="js-cart-confirm" data-toggle="modal" data-target="#cartModal" class="btn btn-primary btn-lg btn-block mb-3 p-3" disabled="disabled" type="submit">
@ -370,7 +379,7 @@
</button>
<div class="text-center mb-5 pb-5">
<img src="~/img/logo-white.png" height="40">
<img src="~/img/logo.svg" class="logo" height="40">
</div>
</nav>
</div>
@ -449,7 +458,7 @@
</div>
}else if (anyInventoryItems)
{
<div class="w-100 pt-2">&nbsp</div>
<div class="w-100 pt-2">&nbsp</div>
}
</div>
</div>

View file

@ -14,8 +14,8 @@
<section>
<div class="card container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">Authorization Request</h2>
<div class="col-lg-12 section-heading">
<h2>Authorization Request</h2>
<hr class="primary">
<p>@Model.ApplicationName is requesting access to your account.</p>
</div>

View file

@ -21,8 +21,8 @@
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">The Bitpay Translator</h2>
<div class="col-lg-12 section-heading">
<h2>The Bitpay Translator</h2>
<hr class="primary">
<p>Bitpay is using a deprecated standard in their invoices that most wallets do not support. Use this tool to transform their invoices to a regular address/amount.</p>
</div>

View file

@ -3,7 +3,6 @@
ViewBag.AlwaysShrinkNavBar = false;
}
<header class="masthead">
<div class="header-content">
<div class="header-content-inner text-white">
@ -19,7 +18,7 @@
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">A Payment Server for Bitcoin</h2>
<h2>A Payment Server for Bitcoin</h2>
<hr class="primary">
</div>
</div>
@ -28,22 +27,22 @@
<div class="row">
<div class="col-lg-4 col-md-6 text-center">
<div class="service-box">
<img src="~/img/lock-logo.png" />
<h3 class="text-dark">Secure</h3>
<img src="~/img/lock-logo.png" alt="" />
<h3>Secure</h3>
<p class="text-muted">The payment server does not need to know your private keys, so your money can't be stolen.</p>
</div>
</div>
<div class="col-lg-4 col-md-6 text-center">
<div class="service-box">
<img src="~/img/qr-logo.png" />
<h3 class="text-dark">Easy</h3>
<img src="~/img/qr-logo.png" alt="" />
<h3>Easy</h3>
<p class="text-muted">A user-friendly Bitcoin checkout page for your customers.</p>
</div>
</div>
<div class="col-lg-4 col-md-6 text-center">
<div class="service-box">
<img src="~/img/money-logo.png" />
<h3 class="text-dark">Visibility</h3>
<img src="~/img/money-logo.png" alt="" />
<h3>Visibility</h3>
<p class="text-muted">Manage, generate reports, and search for your invoices easily.</p>
</div>
</div>
@ -51,21 +50,15 @@
</div>
</section>
<div class="call-to-action bg-dark text-white">
<div class="container text-center">
<h2>Video tutorials</h2>
<div class="row">
<div class="col-md-2 text-center">
</div>
<div class="col-md-8 text-center">
<div class="col-lg-12 text-center">
<a href="https://www.youtube.com/channel/UCpG9WL6TJuoNfFVkaDMp9ug" target="_blank">
<img src="~/img/youtube.png" class="img-fluid" />
</a>
</div>
<div class="col-md-2 text-center">
</div>
</div>
</div>
</div>
@ -73,7 +66,7 @@
<div class="container">
<div class="row">
<div class="col-lg-8 mx-auto text-center">
<h2 class="section-heading">Donate</h2>
<h2>Donate</h2>
<hr class="primary">
<p>
BTCPay Server is proudly free and open-source, built and maintained<br /> by a world-wide community of passionate contributors.<br />
@ -81,7 +74,28 @@
</p>
<p>
<a href="https://btcpayserver.org/donate/">
<input type="image" src="~/img/paybutton/donateto.svg" name="submit" style="width:209px" alt="Donate to BtcPayServer">
<svg viewBox="0 0 208 55" width="208" xmlns="http://www.w3.org/2000/svg">
<path d="m208 48c0 3.866-3.135 7-7 7h-194c-3.866 0-7-3.134-7-7v-41c0-3.866 3.134-7 7-7h194c3.865 0 7 3.134 7 7z" fill="var(--btcpay-bg-cta, #0f3723)"/>
<g fill="#fff">
<path d="m125.169 20.648c.519 0 1.017.051 1.495.153.479.103.898.276 1.261.522s.654.57.873.972c.22.402.329.903.329 1.503 0 .336-.052.664-.156.981-.104.318-.25.606-.439.864-.19.258-.415.477-.674.657-.26.18-.551.306-.873.378v.036c.793.108 1.428.447 1.899 1.017.474.57.708 1.275.708 2.115 0 .204-.017.436-.052.693s-.104.521-.207.792c-.104.271-.254.537-.45.801-.195.265-.458.495-.785.693-.328.198-.731.36-1.209.485-.479.127-1.052.189-1.72.189h-4.368v-12.851zm0 5.634c.472 0 .881-.057 1.228-.171.346-.114.633-.27.863-.468s.403-.429.518-.693.174-.546.174-.846c0-1.608-.928-2.412-2.782-2.412h-3.192v4.59zm0 6.174c.438 0 .853-.039 1.244-.117s.737-.219 1.037-.423c.299-.204.536-.477.708-.818.173-.343.259-.771.259-1.287 0-.828-.278-1.449-.838-1.863s-1.362-.621-2.41-.621h-3.192v5.13h3.192z"/>
<path d="m137.534 20.648v1.044h-3.167v11.808h-1.176v-11.808h-3.15v-1.044z"/>
<path d="m146.747 23.301c-.231-.381-.513-.7-.845-.958s-.697-.454-1.096-.589c-.4-.135-.82-.202-1.259-.202-.799 0-1.485.158-2.06.475-.574.316-1.045.736-1.41 1.257-.366.522-.637 1.111-.811 1.768-.176.657-.263 1.332-.263 2.023 0 .68.087 1.351.263 2.013.174.663.443 1.255.811 1.777.365.521.835.941 1.41 1.258.574.316 1.261.475 2.06.475.563 0 1.069-.104 1.521-.315.451-.212.838-.499 1.166-.862.326-.363.591-.789.793-1.275.203-.485.332-1.011.388-1.574h1.147c-.078.774-.252 1.473-.522 2.094-.271.622-.619 1.148-1.047 1.583-.427.435-.931.769-1.511 1.002s-1.225.353-1.934.353c-.945 0-1.775-.18-2.49-.537-.716-.358-1.31-.836-1.781-1.435-.473-.599-.828-1.29-1.064-2.075s-.354-1.613-.354-2.479c0-.868.117-1.694.354-2.48.236-.785.592-1.479 1.064-2.084.473-.604 1.065-1.084 1.781-1.442.715-.357 1.545-.537 2.49-.537.574 0 1.135.088 1.68.264s1.041.437 1.486.783c.444.346.816.771 1.114 1.275s.487 1.085.565 1.741h-1.147c-.101-.485-.267-.916-.499-1.297z"/>
<path d="m154.704 20.648c.553 0 1.054.081 1.503.243s.835.402 1.158.72c.322.318.57.705.742 1.161.174.456.26.972.26 1.548s-.086 1.943-.26 2.399c-.172.456-.42.843-.742 1.161s-.708.558-1.158.72-.95.243-1.503.243h-2.884v4.657h-1.176v-12.852zm-.259 7.151c.818 0 1.479-.216 1.986-.648.508-.432.762-1.943.762-2.831s-.254-1.548-.762-1.98c-.507-.432-1.168-.648-1.986-.648h-2.625v6.107z"/>
<path d="m164.361 20.648 4.84 12.852h-1.262l-1.504-3.996h-5.615l-1.486 3.996h-1.244l4.959-12.852zm1.677 7.812-2.384-6.588-2.473 6.588z"/>
<path d="m167.398 20.648h1.381l4.06 6.516 4.043-6.516h1.399l-4.872 7.56v5.292h-1.177v-5.292z"/>
<path d="m27.005 22.02c.782-.118 1.711-.207 2.729-.207 1.844 0 3.158.428 4.028 1.24.885.812 1.402 1.962 1.402 3.571 0 1.623-.502 2.951-1.432 3.866-.929.93-2.464 1.432-4.397 1.432-.915 0-1.682-.045-2.331-.118v-9.784zm1.284 8.793c.324.06.796.074 1.298.074 2.745 0 4.235-1.534 4.235-4.221.015-2.346-1.313-3.836-4.028-3.836-.664 0-1.166.059-1.505.133z"/>
<path d="m43.312 28.202c0 2.642-1.83 3.792-3.556 3.792-1.933 0-3.423-1.416-3.423-3.674 0-2.391 1.564-3.792 3.542-3.792 2.05 0 3.437 1.49 3.437 3.674zm-5.666.073c0 1.564.9 2.745 2.169 2.745 1.239 0 2.169-1.166 2.169-2.774 0-1.21-.605-2.745-2.14-2.745-1.533 0-2.198 1.417-2.198 2.774z"/>
<path d="m44.953 26.623c0-.738-.015-1.343-.059-1.933h1.151l.074 1.181h.03c.354-.679 1.18-1.343 2.361-1.343.988 0 2.523.59 2.523 3.04v4.265h-1.298v-4.117c0-1.151-.428-2.11-1.653-2.11-.855 0-1.52.605-1.741 1.328-.059.163-.089.384-.089.605v4.294h-1.298v-5.21z"/>
<path d="m57.099 31.832-.104-.9h-.044c-.398.561-1.166 1.062-2.184 1.062-1.446 0-2.184-1.018-2.184-2.051 0-1.727 1.534-2.671 4.293-2.656v-.148c0-.59-.162-1.652-1.623-1.652-.664 0-1.357.207-1.859.531l-.294-.856c.59-.384 1.446-.634 2.346-.634 2.184 0 2.715 1.49 2.715 2.921v2.671c0 .62.03 1.225.118 1.712zm-.192-3.644c-1.417-.029-3.025.221-3.025 1.608 0 .841.561 1.239 1.225 1.239.93 0 1.52-.59 1.727-1.195.044-.133.074-.28.074-.413v-1.239z"/>
<path d="m61.764 22.639v2.051h1.859v.989h-1.859v3.852c0 .886.251 1.387.974 1.387.339 0 .59-.044.752-.088l.059.974c-.251.104-.649.177-1.151.177-.605 0-1.092-.191-1.402-.546-.369-.384-.502-1.018-.502-1.859v-3.896h-1.106v-.99h1.106v-1.711z"/>
<path d="m65.72 28.497c.029 1.756 1.151 2.479 2.449 2.479.93 0 1.49-.163 1.977-.369l.222.93c-.458.206-1.24.442-2.376.442-2.198 0-3.512-1.446-3.512-3.601s1.269-3.851 3.35-3.851c2.332 0 2.951 2.051 2.951 3.364 0 .266-.03.472-.044.605h-5.017zm3.806-.93c.015-.826-.339-2.11-1.8-2.11-1.313 0-1.889 1.209-1.992 2.11z"/>
<path d="m77.084 22.639v2.051h1.859v.989h-1.859v3.852c0 .886.251 1.387.974 1.387.339 0 .59-.044.752-.088l.059.974c-.251.104-.649.177-1.151.177-.605 0-1.092-.191-1.402-.546-.369-.384-.502-1.018-.502-1.859v-3.896h-1.106v-.99h1.106v-1.711z"/>
<path d="m86.78 28.202c0 2.642-1.83 3.792-3.556 3.792-1.933 0-3.423-1.416-3.423-3.674 0-2.391 1.564-3.792 3.542-3.792 2.05 0 3.437 1.49 3.437 3.674zm-5.666.073c0 1.564.9 2.745 2.169 2.745 1.239 0 2.169-1.166 2.169-2.774 0-1.21-.605-2.745-2.14-2.745-1.534 0-2.198 1.417-2.198 2.774z"/>
</g>
<path d="m98.329 22.548v-8.32l10.112 4.812-7.447 5.435 3.511 2.537 8.67-6.263c.888-.685 1.47-1.238 1.421-2.137-.07-1.287-.923-1.772-1.695-2.081l-15.397-7.293s-1.7-.78-2.801.482c-.384.44-.453 1.765-.453 1.765v31.58h.029c-.036-1.295 1.166-1.9 1.166-1.9l2.884-1.372v-8.321z" fill="#cdd932"/>
<path d="m104.505 27.01-6.176-4.462v8.929z" fill="#1d7a44"/>
<path d="m113.176 33.271-8.67-6.262-3.511 2.536 7.446 5.435-10.111 4.813-2.884 1.372s-1.202.604-1.166 1.901c.009.324.093.688.294 1.101.745 1.521 2.93.615 2.93.615l15.398-7.292c.771-.309 1.625-.793 1.693-2.081.05-.899-.533-1.452-1.419-2.138z" fill="#51b13e"/>
</svg>
</a>
</p>
</div>
@ -92,7 +106,7 @@
<div class="container">
<div class="row">
<div class="col-lg-8 mx-auto text-center">
<h2 class="section-heading">Let's Get In Touch!</h2>
<h2>Let's Get In Touch!</h2>
<hr class="primary">
<p>
An open source project is nothing without its community<br />
@ -100,35 +114,31 @@
</p>
</div>
</div>
<div class="row">
<div class="col-lg-3 ml-auto text-center">
<div class="row social-row">
<div class="col-6 col-md-3 ml-auto text-center">
<a href="https://chat.btcpayserver.org/" target="_blank">
<img src="~/img/mattermost.png" height="100" />
<img src="~/img/mattermost.svg" alt="Mattermost" class="social-logo" />
<span>On Mattermost</span>
</a>
<p><a href="https://chat.btcpayserver.org/" target="_blank">On Mattermost</a></p>
</div>
<div class="col-lg-3 ml-auto text-center">
<div class="col-6 col-md-3 ml-auto text-center">
<a href="https://slack.btcpayserver.org/" target="_blank">
<img src="~/img/slack.png" height="100" />
<img src="~/img/slack.svg" alt="Slack" class="social-logo" />
<span>On Slack</span>
</a>
<p><a href="https://slack.btcpayserver.org/" target="_blank">On Slack</a></p>
</div>
<div class="col-lg-3 mr-auto text-center">
<div class="col-6 col-md-3 mr-auto text-center">
<a href="https://twitter.com/BtcpayServer" target="_blank">
<img src="~/img/twitter.png" height="100" />
<img src="~/img/twitter.svg" alt="Twitter" class="social-logo" />
<span>On Twitter</span>
</a>
<p>
<a href="https://twitter.com/BtcpayServer" target="_blank">On Twitter</a>
</p>
</div>
<div class="col-lg-3 mr-auto text-center">
<div class="col-6 col-md-3 mr-auto text-center">
<a href="https://github.com/btcpayserver/btcpayserver" target="_blank">
<img src="~/img/github.png" height="100" />
<img src="~/img/github.svg" alt="Github" class="social-logo" />
<span>On Github</span>
</a>
<p>
<a href="https://github.com/btcpayserver/btcpayserver" target="_blank">On Github</a>
</p>
</div>
</div>
</div>

View file

@ -100,7 +100,7 @@
<span>{{ srvModel.btcDue }} {{ srvModel.cryptoCode }}</span>
</div>
<div class="single-item-order__right__ex-rate" v-if="srvModel.orderAmountFiat && srvModel.cryptoCode">
1 {{ srvModel.cryptoCodeSrv }} = {{ srvModel.rate }}
{{srvModel.rateBaseAmount}} {{ srvModel.cryptoCodeSrv }} = {{ srvModel.rate }}
</div>
</div>
<span class="fa fa-angle-double-down"></span>

View file

@ -13,8 +13,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>

View file

@ -27,8 +27,8 @@
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>

View file

@ -18,8 +18,8 @@
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<p>Create, search or pay an invoice. (<a href="#help" data-toggle="collapse">Help</a>)</p>
<div id="help" class="collapse text-left">
@ -45,7 +45,7 @@
</div>
</div>
<div class="row no-gutter" style="margin-bottom: 5px;">
<div class="row button-row">
<div class="col-lg-6">
<a asp-action="CreateInvoice" class="btn btn-primary" role="button" id="CreateNewInvoice"><span class="fa fa-plus"></span> Create a new invoice</a>
<a class="btn btn-primary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -73,17 +73,25 @@
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
@{
var storeIds = String.Join(
"",
Model.StoreIds.Select(storeId => string.Format(",storeid:{0}", storeId))
);
}
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=status%3Ainvalid">Invalid Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=status%3Apaid%2Cstatus%3Aconfirmed%2Cstatus%3Acomplete">Paid Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidLate">Paid Late Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidPartial">Paid Partial Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidOver">Paid Over Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=unusual%3Atrue">Unusual Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=status%3Ainvalid@{@storeIds}">Invalid Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=status%3Apaid%2Cstatus%3Aconfirmed%2Cstatus%3Acomplete@{@storeIds}">Paid Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidLate@{@storeIds}s">Paid Late Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidPartial@{@storeIds}">Paid Partial Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=exceptionstatus%3ApaidOver@{@storeIds}">Paid Over Invoices</a>
<a class="dropdown-item" href="/invoices?Count=@Model.Count&SearchTerm=unusual%3Atrue@{@storeIds}">Unusual Invoices</a>
<div role="separator" class="dropdown-divider"></div>
<a class="dropdown-item last24" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast24">Last 24 hours</a>
<a class="dropdown-item last72" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast72">Last 3 days</a>
<a class="dropdown-item last168" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast168">Last 7 days</a>
<a class="dropdown-item last24" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast24@{@storeIds}">Last 24 hours</a>
<a class="dropdown-item last72" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast72@{@storeIds}">Last 3 days</a>
<a class="dropdown-item last168" href="/invoices?Count=@Model.Count&timezoneoffset=0&SearchTerm=startDate%3Alast168@{@storeIds}">Last 7 days</a>
<button type="button" class="dropdown-item" data-toggle="modal" data-target="#customRangeModal" data-backdrop="static">Custom Range</button>
<div role="separator" class="dropdown-divider"></div>
<a class="dropdown-item" href="/invoices">Unfiltered</a>
@ -175,152 +183,154 @@
@* Custom Range Modal *@
<div class="row">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th style="min-width: 90px;" class="col-md-auto">
Date
<a href="javascript:switchTimeFormat()">
<span class="fa fa-clock-o" title="Switch date format"></span>
</a>
</th>
<th style="max-width: 180px;">OrderId</th>
<th>InvoiceId</th>
<th style="min-width: 150px;">Status</th>
<th style="text-align:right">Amount</th>
<th style="text-align:right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var invoice in Model.Invoices)
{
<div class="col-lg-12">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<td>
<span class="switchTimeFormat" data-switch="@invoice.Date.ToTimeAgo()">
@invoice.Date.ToBrowserDate()
</span>
</td>
<td style="max-width: 180px;">
@if (invoice.RedirectUrl != string.Empty)
{
<a href="@invoice.RedirectUrl" class="wraptext200">@invoice.OrderId</a>
}
else
{
<span>@invoice.OrderId</span>
}
</td>
<td>@invoice.InvoiceId</td>
<td>
@if (invoice.CanMarkStatus)
{
<div id="pavpill_@invoice.InvoiceId">
<span class="dropdown-toggle dropdown-toggle-split pavpill pavpil-@invoice.Status.ToString().ToLower()"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@invoice.StatusString
</span>
<div class="dropdown-menu pull-right">
@if (invoice.CanMarkInvalid)
{
<button class="dropdown-item small cursorPointer" onclick="changeInvoiceState(this, '@invoice.InvoiceId', 'invalid')">
Mark as invalid <span class="fa fa-times"></span>
</button>
}
@if (invoice.CanMarkComplete)
{
<button class="dropdown-item small cursorPointer" onclick="changeInvoiceState(this, '@invoice.InvoiceId', 'complete')">
Mark as complete <span class="fa fa-check-circle"></span>
</button>
}
</div>
</div>
}
else
{
<span class="pavpill pavpil-@invoice.Status.ToString().ToLower()">@invoice.StatusString</span>
}
</td>
<td style="text-align:right">@invoice.AmountCurrency</td>
<td style="text-align:right">
@if (invoice.ShowCheckout)
{
<span>
<a asp-action="Checkout" class="invoice-checkout-link" id="invoice-checkout-@invoice.InvoiceId" asp-route-invoiceId="@invoice.InvoiceId">Checkout</a>
<a href="javascript:btcpay.showInvoice('@invoice.InvoiceId')">[^]</a>
@if (!invoice.CanMarkStatus)
{
<span>-</span>
}
</span>
}
&nbsp;
<a asp-action="Invoice" class="invoice-details-link" asp-route-invoiceId="@invoice.InvoiceId">Details</a>
@*<span title="Details" class="fa fa-list"></span>*@
&nbsp;
<a href="javascript:void(0);" onclick="detailsToggle(this, '@invoice.InvoiceId')">
<span title="Invoice Details Toggle" class="fa fa-1x fa-angle-double-down"></span>
<th style="min-width: 90px;" class="col-md-auto">
Date
<a href="javascript:switchTimeFormat()">
<span class="fa fa-clock-o" title="Switch date format"></span>
</a>
</td>
</th>
<th style="max-width: 180px;">OrderId</th>
<th>InvoiceId</th>
<th style="min-width: 150px;">Status</th>
<th style="text-align:right">Amount</th>
<th style="text-align:right">Actions</th>
</tr>
<tr id="invoice_@invoice.InvoiceId" style="display:none;">
<td colspan="99">
<div style="margin-left: 15px; margin-bottom: 0px;">
<partial name="InvoicePaymentsPartial" model="invoice.Details" />
</div>
</td>
</tr>
}
</tbody>
</table>
<nav aria-label="..." class="w-100">
<ul class="pagination float-left">
<li class="page-item @(Model.Skip == 0 ? "disabled" : null)">
<a class="page-link" tabindex="-1" href="@listInvoices(-1, Model.Count)">&laquo;</a>
</li>
<li class="page-item disabled">
<span class="page-link">@(Model.Skip + 1) to @(Model.Skip + Model.Invoices.Count) of @Model.Total</span>
</li>
<li class="page-item @(Model.Total > (Model.Skip + Model.Invoices.Count) ? null : "disabled")">
<a class="page-link" href="@listInvoices(1, Model.Count)">&raquo;</a>
</li>
</ul>
<ul class="pagination float-right">
<li class="page-item disabled">
<span class="page-link">Page Size:</span>
</li>
<li class="page-item @(Model.Count == 50 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 50)">50</a>
</li>
<li class="page-item @(Model.Count == 100 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 100)">100</a>
</li>
<li class="page-item @(Model.Count == 250 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 250)">250</a>
</li>
<li class="page-item @(Model.Count == 500 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 500)">500</a>
</li>
</ul>
</nav>
@{
string listInvoices(int prevNext, int count)
{
var skip = Model.Skip;
if (prevNext == -1)
skip = Math.Max(0, Model.Skip - Model.Count);
else if (prevNext == 1)
skip = Model.Skip + count;
var act = Url.Action("ListInvoices", new
</thead>
<tbody>
@foreach (var invoice in Model.Invoices)
{
<tr>
<td>
<span class="switchTimeFormat" data-switch="@invoice.Date.ToTimeAgo()">
@invoice.Date.ToBrowserDate()
</span>
</td>
<td style="max-width: 180px;">
@if (invoice.RedirectUrl != string.Empty)
{
<a href="@invoice.RedirectUrl" class="wraptext200">@invoice.OrderId</a>
}
else
{
<span>@invoice.OrderId</span>
}
</td>
<td>@invoice.InvoiceId</td>
<td>
@if (invoice.CanMarkStatus)
{
<div id="pavpill_@invoice.InvoiceId">
<span class="dropdown-toggle dropdown-toggle-split pavpill pavpil-@invoice.Status.ToString().ToLower()"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@invoice.StatusString
</span>
<div class="dropdown-menu pull-right">
@if (invoice.CanMarkInvalid)
{
<button class="dropdown-item small cursorPointer" onclick="changeInvoiceState(this, '@invoice.InvoiceId', 'invalid')">
Mark as invalid <span class="fa fa-times"></span>
</button>
}
@if (invoice.CanMarkComplete)
{
<button class="dropdown-item small cursorPointer" onclick="changeInvoiceState(this, '@invoice.InvoiceId', 'complete')">
Mark as complete <span class="fa fa-check-circle"></span>
</button>
}
</div>
</div>
}
else
{
<span class="pavpill pavpil-@invoice.Status.ToString().ToLower()">@invoice.StatusString</span>
}
</td>
<td style="text-align:right">@invoice.AmountCurrency</td>
<td style="text-align:right">
@if (invoice.ShowCheckout)
{
<span>
<a asp-action="Checkout" class="invoice-checkout-link" id="invoice-checkout-@invoice.InvoiceId" asp-route-invoiceId="@invoice.InvoiceId">Checkout</a>
<a href="javascript:btcpay.showInvoice('@invoice.InvoiceId')">[^]</a>
@if (!invoice.CanMarkStatus)
{
<span>-</span>
}
</span>
}
&nbsp;
<a asp-action="Invoice" class="invoice-details-link" asp-route-invoiceId="@invoice.InvoiceId">Details</a>
@*<span title="Details" class="fa fa-list"></span>*@
&nbsp;
<a href="javascript:void(0);" onclick="detailsToggle(this, '@invoice.InvoiceId')">
<span title="Invoice Details Toggle" class="fa fa-1x fa-angle-double-down"></span>
</a>
</td>
</tr>
<tr id="invoice_@invoice.InvoiceId" style="display:none;">
<td colspan="99">
<div style="margin-left: 15px; margin-bottom: 0px;">
<partial name="InvoicePaymentsPartial" model="invoice.Details" />
</div>
</td>
</tr>
}
</tbody>
</table>
<nav aria-label="..." class="w-100">
<ul class="pagination float-left">
<li class="page-item @(Model.Skip == 0 ? "disabled" : null)">
<a class="page-link" tabindex="-1" href="@listInvoices(-1, Model.Count)">&laquo;</a>
</li>
<li class="page-item disabled">
<span class="page-link">@(Model.Skip + 1) to @(Model.Skip + Model.Invoices.Count) of @Model.Total</span>
</li>
<li class="page-item @(Model.Total > (Model.Skip + Model.Invoices.Count) ? null : "disabled")">
<a class="page-link" href="@listInvoices(1, Model.Count)">&raquo;</a>
</li>
</ul>
<ul class="pagination float-right">
<li class="page-item disabled">
<span class="page-link">Page Size:</span>
</li>
<li class="page-item @(Model.Count == 50 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 50)">50</a>
</li>
<li class="page-item @(Model.Count == 100 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 100)">100</a>
</li>
<li class="page-item @(Model.Count == 250 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 250)">250</a>
</li>
<li class="page-item @(Model.Count == 500 ? "active" : null)">
<a class="page-link" href="@listInvoices(0, 500)">500</a>
</li>
</ul>
</nav>
@{
string listInvoices(int prevNext, int count)
{
searchTerm = Model.SearchTerm,
skip = skip,
count = count,
});
var skip = Model.Skip;
if (prevNext == -1)
skip = Math.Max(0, Model.Skip - Model.Count);
else if (prevNext == 1)
skip = Model.Skip + count;
return act;
var act = Url.Action("ListInvoices", new
{
searchTerm = Model.SearchTerm,
skip = skip,
count = count,
});
return act;
}
}
}
</div>
</div>
</div>

View file

@ -4,7 +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"/>
@ -14,13 +14,19 @@
<div class="card">
<h3 class="card-title px-1"><span class="fa fa-spinner fa-spin"></span>Registering U2F Device</h3>
<div class="card-header">
<h4 style="margin-bottom:0;">
<span class="fa fa-spinner fa-spin" style="margin-right:.25rem;"></span>
Registering U2F Device
</h4>
</div>
<div class="card-body">
<p>Insert your U2F device or a hardware wallet into your computer's USB port. If it has a button, tap on it.</p>
<a id="error-response" class="text-danger" href="javascript:window.location.reload()"> </a>
</div>
<div class="card-footer">
<a class="btn btn-secondary" asp-action="U2FAuthentication" id="btn-back">Abort</a>
</div>

View file

@ -5,8 +5,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@(string.IsNullOrEmpty(Model.Id) ? "Create" : "Edit") Payment Request</h2>
<div class="col-lg-12 section-heading">
<h2>@(string.IsNullOrEmpty(Model.Id) ? "Create" : "Edit") Payment Request</h2>
<hr class="primary">
</div>
</div>

View file

@ -14,74 +14,77 @@
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">Payment Requests</h2>
<div class="col-lg-12 section-heading">
<h2>Payment Requests</h2>
<hr class="primary">
</div>
</div>
<div class="row no-gutter" style="margin-bottom: 5px;">
<div class="col-lg-6">
<div class="row button-row">
<div class="col-lg-12">
<a asp-action="EditPaymentRequest" class="btn btn-primary" role="button" id="CreatePaymentRequest"><span class="fa fa-plus"></span> Create a new payment request</a>
<a href="https://docs.btcpayserver.org/features/paymentrequests" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
</div>
</div>
<div class="row">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th>Title</th>
<th>Expiry</th>
<th class="text-right">Price</th>
<th class="text-right">Status</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<div class="col-lg-12">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<td>@item.Title</td>
<td>@(item.ExpiryDate?.ToString("g") ?? "No Expiry")</td>
<td class="text-right">@item.Amount @item.Currency</td>
<td class="text-right">@item.Status</td>
<td class="text-right">
<a asp-action="EditPaymentRequest" asp-route-id="@item.Id">Edit</a>
<span> - </span>
<a asp-action="ViewPaymentRequest" asp-route-id="@item.Id">View</a>
<span> - </span>
<a target="_blank" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(item.Id)}")">Invoices</a>
<span> - </span>
<a target="_blank" asp-action="PayPaymentRequest" asp-route-id="@item.Id">Pay</a>
<span> - </span>
<a target="_blank" asp-action="ClonePaymentRequest" asp-route-id="@item.Id">Clone</a>
<span> - </span>
<a asp-action="RemovePaymentRequestPrompt" asp-route-id="@item.Id">Remove</a>
</td>
<th>Title</th>
<th>Expiry</th>
<th class="text-right">Price</th>
<th class="text-right">Status</th>
<th class="text-right">Actions</th>
</tr>
}
</tbody>
</table>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr>
<td>@item.Title</td>
<td>@(item.ExpiryDate?.ToString("g") ?? "No Expiry")</td>
<td class="text-right">@item.Amount @item.Currency</td>
<td class="text-right">@item.Status</td>
<td class="text-right">
<a asp-action="EditPaymentRequest" asp-route-id="@item.Id">Edit</a>
<span> - </span>
<a asp-action="ViewPaymentRequest" asp-route-id="@item.Id">View</a>
<span> - </span>
<a target="_blank" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@($"orderid:{PaymentRequestRepository.GetOrderIdForPaymentRequest(item.Id)}")">Invoices</a>
<span> - </span>
<a target="_blank" asp-action="PayPaymentRequest" asp-route-id="@item.Id">Pay</a>
<span> - </span>
<a target="_blank" asp-action="ClonePaymentRequest" asp-route-id="@item.Id">Clone</a>
<span> - </span>
<a asp-action="RemovePaymentRequestPrompt" asp-route-id="@item.Id">Remove</a>
</td>
</tr>
}
</tbody>
</table>
<nav aria-label="...">
<ul class="pagination">
<li class="page-item @(Model.Skip == 0 ? "disabled" : null)">
<a class="page-link" tabindex="-1" href="@Url.Action("GetPaymentRequests", new
{
skip = Math.Max(0, Model.Skip - Model.Count),
count = Model.Count,
})">Previous</a>
</li>
<li class="page-item disabled">
<span class="page-link">@(Model.Skip + 1) to @(Model.Skip + Model.Count) of @Model.Total</span>
</li>
<li class="page-item @(Model.Total > (Model.Skip + Model.Count) ? null : "disabled")">
<a class="page-link" href="@Url.Action("GetPaymentRequests", new
{
skip = Model.Skip + Model.Count,
count = Model.Count,
})">Next</a>
</li>
</ul>
</nav>
<nav aria-label="...">
<ul class="pagination">
<li class="page-item @(Model.Skip == 0 ? "disabled" : null)">
<a class="page-link" tabindex="-1" href="@Url.Action("GetPaymentRequests", new
{
skip = Math.Max(0, Model.Skip - Model.Count),
count = Model.Count,
})">Previous</a>
</li>
<li class="page-item disabled">
<span class="page-link">@(Model.Skip + 1) to @(Model.Skip + Model.Count) of @Model.Total</span>
</li>
<li class="page-item @(Model.Total > (Model.Skip + Model.Count) ? null : "disabled")">
<a class="page-link" href="@Url.Action("GetPaymentRequests", new
{
skip = Model.Skip + Model.Count,
count = Model.Count,
})">Next</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</section>

View file

@ -12,19 +12,19 @@
<div class="row mb-4">
<div class="col-sm-12 col-md-12 col-lg-6 ">
<ul class="w-100 list-group list-group-flush">
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Request amount:</span>
<span class="h2">@Model.AmountFormatted</span>
</div>
</li>
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Paid so far:</span>
<span class="h2">@Model.AmountCollectedFormatted</span>
</div>
</li>
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Amount due:</span>
<span class="h2">@Model.AmountDueFormatted</span>
@ -143,7 +143,7 @@
{
<form method="get" asp-action="CancelUnpaidPendingInvoice">
<button class="btn btn-secondary btn-lg mt-1" type="submit">
Cancel current invoice</button>
Cancel current invoice</button>
</form>
}
}

View file

@ -15,6 +15,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="@Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
<link href="@Context.Request.GetRelativePathOrAbsolute(themeManager.ThemeUri)" rel="stylesheet" />
@if (Model.CustomCSSLink != null)
{
<link href="@Model.CustomCSSLink" rel="stylesheet" />
@ -31,7 +32,7 @@
}
<bundle name="wwwroot/bundles/payment-request-bundle.min.css"></bundle>
@Safe.Raw(Model.EmbeddedCSS)
</head>
<body>
@ -67,19 +68,19 @@ else
<div class="row mb-4">
<div class="col-sm-12 col-md-12 col-lg-6 ">
<ul class="w-100 list-group list-group-flush">
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Request amount:</span>
<span class="h2">{{srvModel.amountFormatted}}</span>
</div>
</li>
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Paid so far:</span>
<span class="h2">{{srvModel.amountCollectedFormatted}}</span>
</div>
</li>
<li class="list-group-item">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Amount due:</span>
<span class="h2">{{srvModel.amountDueFormatted}}</span>
@ -185,8 +186,8 @@ else
Pay now
</button>
<button class="btn btn-secondary btn-lg mt-1"
v-if="srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments"
<button class="btn btn-secondary btn-lg mt-1"
v-if="srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments"
v-on:click="cancelPayment()"
:disabled="loading">
<div v-if="loading" class="spinner-grow spinner-grow-sm" role="status">
@ -195,7 +196,6 @@ else
Cancel current invoice</button>
</template>
</td>
</tr>
</tbody>
@ -206,12 +206,11 @@ else
</div>
<div class="card-footer text-muted d-flex justify-content-between">
<div >
<div>
<span v-on:click="print" class="btn-link d-print-none" style="cursor: pointer"> <span class="fa fa-print"></span> Print</span>
<span>Updated {{lastUpdated}}</span>
</div>
<div >
<div>
<span class="text-muted">Powered by </span><a href="https://btcpayserver.org" target="_blank">BTCPay Server</a>
</div>
</div>

View file

@ -19,6 +19,7 @@
<link rel="manifest" href="~/manifest.json">
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.ThemeUri)" rel="stylesheet" />
<link href="~/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<bundle name="wwwroot/bundles/lightning-node-info-bundle.min.js" />

View file

@ -5,13 +5,14 @@
<partial name="_StatusMessage" />
<div class="row">
<div class="row button-row">
<div class="col align-self-center">Total Users: @Model.Total</div>
<div class="col text-right">
<a asp-controller="Account"
asp-action="Register"
asp-route-returnUrl="@Context.Request.GetCurrentPath()"
asp-route-logon="false"
asp-route-useBasicLayout="true"
class="btn btn-primary"
role="button">
<span class="fa fa-plus"></span> Add User

View file

@ -13,6 +13,14 @@
<div class="row">
<div class="col-lg-6">
<form method="post">
<div class="form-group">
<label asp-for="ThemeCssUri"></label>
<select id=themes asp-for="ThemeCssUri" class="form-control">
<option value="/main/themes/classic.css">Classic</option>
<option value="/main/themes/casa.css">Casa</option>
</select>
<span asp-validation-for="ThemeCssUri" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BootstrapCssUri"></label>
<a href="https://docs.btcpayserver.org/development/theme#bootstrap-themes" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a>
@ -32,7 +40,6 @@
is used on top of Bootstrap
</p>
</div>
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
</form>
</div>

View file

@ -13,6 +13,7 @@
@* CSS *@
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.CreativeStartUri)" rel="stylesheet" />
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.ThemeUri)" rel="stylesheet" />
<bundle name="wwwroot/bundles/main-bundle.min.css" />
@* JS *@
<bundle name="wwwroot/bundles/main-bundle.min.js" />

View file

@ -29,7 +29,8 @@
<nav class='navbar navbar-expand-lg navbar-dark fixed-top @additionalStyle' id="mainNav">
<div class="container">
<a class="navbar-brand js-scroll-trigger" href="~/">
<img src="~/img/btcpay-logo-white-txt.svg" height="45">
<img src="~/img/logo.svg" class="logo" />
@if (env.NetworkType != NBitcoin.NetworkType.Mainnet)
{
<span class="badge badge-warning" style="font-size:10px;">@env.NetworkType.ToString()</span>
@ -84,7 +85,7 @@
{
<div class="alert alert-danger alert-dismissible" style="position:absolute; top:75px;" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<span>Your access to BTCPay Server is over an unsecured network. If you are using the docker deployment method with NGINX and HTTPS is not available, you probably did not configure your DNS settings correctly. <br />
<span>Your access to BTCPay Server is over an unsecured network. If you are using the docker deployment method with NGINX and HTTPS is not available, you probably did not configure your DNS settings correctly. <br />
We disabled the register and login link so you don't leak your credentials.</span>
</div>
}
@ -96,7 +97,7 @@
@if (User.Identity.IsAuthenticated)
{
<footer class="siteFooter bg-dark text-white">
<footer class="footer">
<div class="container text-right">@env.ToString()</div>
</footer>
}

View file

@ -11,10 +11,10 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="col-lg-12 section-heading">
@if (ViewBag.ShowMenu)
{
<h4 class="section-heading">@title</h4>
<h2>@title</h2>
<hr class="primary ml-0">
}
</div>

View file

@ -50,7 +50,6 @@
<div class="dropdown-menu dropdown-menu-right w-100" aria-labelledby="hardwarewlletimportdropdown">
<button class="dropdown-item" type="button" data-toggle="modal" data-target="#coldcardimport">Coldcard</button>
<button class="dropdown-item check-for-ledger" data-toggle="modal" data-target="#ledgerimport" type="button">Ledger Wallet</button>
@* <button class="dropdown-item check-for-trezor" type="button" data-toggle="modal" data-target="#trezorimport">Trezor</button> *@
</div>
</div>
</div>
@ -163,9 +162,6 @@
@await Html.PartialAsync("_ValidationScriptsPartial")
<script src="~/js/ledgerwebsocket.js" type="text/javascript" defer="defer"></script>
<script src="~/js/StoreAddDerivationScheme.js" type="text/javascript" defer="defer"></script>
<script src="~/vendor/trezor/trezor.js-umd.min.js" defer="defer"></script>
<script src="~/js/trezor/trezor-client.js" type="text/javascript" defer="defer"></script>
<script src="~/js/trezor/trezor-add-derivation-scheme.js" type="text/javascript" defer="defer"></script>
<script>
window.coinName = "@Model.Network.DisplayName.ToLowerInvariant()";
</script>

View file

@ -80,91 +80,3 @@
</form>
</div>
</div>
<div class="modal fade" id="trezorimport" tabindex="-1" role="dialog" aria-labelledby="trezorimport" aria-hidden="true">
<div class="modal-dialog" role="document">
<form class="modal-content" form method="post" id="trezor-submit">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Import Trezor Wallet</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p id="trezor-loading" style="display: none;">
<span class="fa fa-question-circle" style="color: orange"></span> <span>Detecting Trezor hardware wallet...</span>
</p>
<p id="trezor-error" class="text-danger" style="display: none;">
<span class="fa fa-times-circle" style="color: red;"></span> <span class="hw-label">An error happened</span>
</p>
<p id="trezor-success" style="display: none;">
<span class="fa fa-check-circle" style="color: green;"></span> <span class="hw-label">Trezor wallet detected! Name: <kbd id="trezor-devicename"></kbd></span>
</p>
<div class="form-group display-when-trezor-connected" style="display: none">
<label class="control-label">Wallet address type</label>
<select class="form-control" id="trezor-address-type-select">
<option data-hide=".trezor-account-dropdown" selected>Select an address type</option>
<option data-show="#trezor-account-dropdown-legacy" data-hide=".trezor-account-dropdown"> Legacy</option>
@if (Model.Network.NBitcoinNetwork.Consensus.SupportSegwit)
{
<option data-show="#trezor-account-dropdown-p2sh" data-hide=".trezor-account-dropdown"> P2SH-Segwit</option>
<option data-show="#trezor-account-dropdown-segwit" data-hide=".trezor-account-dropdown"> Segwit( Bech32 )</option>
}
</select>
</div>
@if (Model.Network.NBitcoinNetwork.Consensus.SupportSegwit)
{
<div class="form-group trezor-account-dropdown" style="display: none" id="trezor-account-dropdown-p2sh">
<label class="control-label">Wallet account</label>
<select class="form-control">
<option>Select a wallet account</option>
@for (var i = 0; i < 20; i++)
{
<option
data-derivation-suffix="-[p2sh]"
data-trezorkeypath="@Model.Network.GetRootKeyPath(DerivationType.SegwitP2SH).Derive(i, true)"
>Account @i (@Model.Network.GetRootKeyPath(DerivationType.SegwitP2SH).Derive(i, true))</option>
}
</select>
</div>
<div class="form-group trezor-account-dropdown" style="display: none" id="trezor-account-dropdown-segwit">
<label class="control-label">Wallet account</label>
<select class="form-control">
<option>Select a wallet account</option>
@for (var i = 0; i < 20; i++)
{
<option
data-derivation-suffix=""
data-trezorkeypath="@Model.Network.GetRootKeyPath(DerivationType.Segwit).Derive(i, true)" href="#">Account @i (@Model.Network.GetRootKeyPath(DerivationType.Segwit).Derive(i, true))</option>
}
</select>
</div>
}
<div class="form-group trezor-account-dropdown" style="display: none" id="trezor-account-dropdown-legacy">
<label class="control-label">Wallet account</label>
<select class="form-control">
<option>Select a wallet account</option>
@for (var i = 0; i < 20; i++)
{
<option
data-derivation-suffix="-[legacy]"
data-trezorkeypath="@Model.Network.GetRootKeyPath(DerivationType.Legacy).Derive(i, true)">Account @i (@Model.Network.GetRootKeyPath(DerivationType.Legacy).Derive(i, true))</option>
}
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button class="btn btn-primary" id="trezorsubmitbutton">Submit</button>
</div>
</form>
</div>
</div>

View file

@ -6,8 +6,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<p>Create and manage store settings.</p>
</div>

View file

@ -5,8 +5,8 @@
<section>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
</div>
</div>

View file

@ -14,47 +14,53 @@
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<p>Create and manage store settings.</p>
</div>
</div>
<div class="row">
<a asp-action="CreateStore" class="btn btn-primary" role="button" id="CreateStore"><span class="fa fa-plus"></span> Create a new store</a>
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th>Name</th>
<th>Website</th>
<th style="text-align:right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var store in Model.Stores)
{
<tr id="store-@store.Id">
<td>@store.Name</td>
<td>
@if (!string.IsNullOrEmpty(store.WebSite))
{
<a href="@store.WebSite">@store.WebSite</a>
}
</td>
<td style="text-align:right">
<a asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchTerm="storeid:@store.Id">Invoices</a><span> - </span>
@if (store.IsOwner)
{
<a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@store.Id" id="update-store-@store.Id">Settings</a><span> - </span>
}
<a asp-action="DeleteStore" asp-controller="Stores" asp-route-storeId="@store.Id">Remove</a>
</td>
</tr>
}
</tbody>
</table>
<div class="row button-row">
<div class="col-lg-12">
<a asp-action="CreateStore" class="btn btn-primary" role="button" id="CreateStore"><span class="fa fa-plus"></span> Create a new store</a>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th>Name</th>
<th>Website</th>
<th style="text-align:right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var store in Model.Stores)
{
<tr id="store-@store.Id">
<td>@store.Name</td>
<td>
@if (!string.IsNullOrEmpty(store.WebSite))
{
<a href="@store.WebSite">@store.WebSite</a>
}
</td>
<td style="text-align:right">
<a asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchTerm="storeid:@store.Id">Invoices</a><span> - </span>
@if (store.IsOwner)
{
<a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@store.Id" id="update-store-@store.Id">Settings</a><span> - </span>
}
<a asp-action="DeleteStore" asp-controller="Stores" asp-route-storeId="@store.Id">Remove</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</section>

View file

@ -15,44 +15,46 @@
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">@ViewData["Title"]</h2>
<div class="col-lg-12 section-heading">
<h2>@ViewData["Title"]</h2>
<hr class="primary">
<p>Create and manage wallets. <a href="https://docs.btcpayserver.org/features/wallet" target="_blank"><span class="fa fa-question-circle-o" title="More information..."></span></a></p>
</div>
</div>
<div class="row">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
<th>Store Name</th>
<th>Crypto Code</th>
<th>Balance</th>
<th style="text-align:right">Actions</th>
</tr>
</thead>
<tbody>
@foreach (var wallet in Model.Wallets)
{
<div class="col-lg-12">
<table class="table table-sm table-responsive-md">
<thead>
<tr>
@if (wallet.IsOwner)
{
<td><a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@wallet.StoreId">@wallet.StoreName</a></td>
}
else
{
<td>@wallet.StoreName</td>
}
<td>@wallet.CryptoCode</td>
<td>@wallet.Balance</td>
<td style="text-align:right">
<a asp-action="WalletTransactions" asp-route-walletId="@wallet.Id">Manage</a>
</td>
<th>Store Name</th>
<th>Crypto Code</th>
<th>Balance</th>
<th style="text-align:right">Actions</th>
</tr>
}
</tbody>
</table>
</thead>
<tbody>
@foreach (var wallet in Model.Wallets)
{
<tr>
@if (wallet.IsOwner)
{
<td><a asp-action="UpdateStore" asp-controller="Stores" asp-route-storeId="@wallet.StoreId">@wallet.StoreName</a></td>
}
else
{
<td>@wallet.StoreName</td>
}
<td>@wallet.CryptoCode</td>
<td>@wallet.Balance</td>
<td style="text-align:right">
<a asp-action="WalletTransactions" asp-route-walletId="@wallet.Id">Manage</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</section>

View file

@ -12,8 +12,8 @@
</div>
}
<div class="row">
<div class="col-lg-12 text-center">
<h2 class="section-heading">Transaction review</h2>
<div class="col-lg-12 section-heading">
<h2>Transaction review</h2>
<hr class="primary">
@if (Model.CanCalculateBalance)
{

View file

@ -6,7 +6,7 @@
ViewData.SetActivePageAndTitle(WalletsNavPages.Send);
}
<div class="row no-gutters">
<div class="row">
<div class="@(Model.Outputs.Count==1? "col-lg-6 transaction-output-form": "col-lg-8")">
<form method="post">
<input type="hidden" asp-for="Divisibility" />
@ -37,7 +37,7 @@
<div class="input-group">
<input asp-for="Outputs[0].Amount" type="number" step="any" asp-format="{0}" class="form-control output-amount" />
<div class="input-group-prepend">
<span class="input-group-text text-muted fiat-value" style="display:none;"></span>
<span class="input-group-text fiat-value" style="display:none;"></span>
</div>
</div>
<span asp-validation-for="Outputs[0].Amount" class="text-danger"></span>
@ -68,7 +68,7 @@
<div class="input-group">
<input asp-for="Outputs[index].Amount" type="number" step="any" asp-format="{0}" class="form-control output-amount" />
<div class="input-group-prepend">
<span class="input-group-text text-muted fiat-value" style="display:none;"></span>
<span class="input-group-text fiat-value" style="display:none;"></span>
</div>
</div>
<p class="form-text text-muted crypto-info">
@ -118,13 +118,9 @@
</div>
}
<div class="card">
<div class="card-header" id="accordian-dev-info-notification-header">
<h2 class="mb-0">
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#accordian-advanced" aria-expanded="false" aria-controls="accordian-advanced">
Advanced settings
</button>
</h2>
</div>
<button class="btn btn-light collapsed" type="button" data-toggle="collapse" data-target="#accordian-advanced" aria-expanded="false" aria-controls="accordian-advanced">
Advanced settings
</button>
<div id="accordian-advanced" class="collapse" aria-labelledby="accordian-advanced-header" data-parent="#accordian-advanced">
<div class="card-body">
<div class="form-check">

View file

@ -2,12 +2,12 @@
{
"outputFileName": "wwwroot/bundles/main-bundle.min.css",
"inputFiles": [
"wwwroot/vendor/bootstrap4-creativestart/Open-Sans.css",
"wwwroot/vendor/magnific-popup/magnific-popup.css",
"wwwroot/vendor/font-awesome/css/font-awesome.css",
"wwwroot/main/**/*.css",
"wwwroot/vendor/animatecss/animate.css",
"wwwroot/vendor/flatpickr/flatpickr.css"
"wwwroot/vendor/flatpickr/flatpickr.css",
"wwwroot/main/fonts/OpenSans.css",
"wwwroot/main/site.css"
]
},
{
@ -15,14 +15,14 @@
"inputFiles": [
"wwwroot/vendor/jquery/jquery.js",
"wwwroot/vendor/popper/popper.js",
"wwwroot/vendor/bootstrap4/js/bootstrap.js",
"wwwroot/main/bootstrap/bootstrap.js",
"wwwroot/main/bootstrap4-creativestart/creative.js",
"wwwroot/vendor/jquery-easing/jquery.easing.js",
"wwwroot/vendor/scrollreveal/scrollreveal.min.js",
"wwwroot/vendor/magnific-popup/jquery.magnific-popup.js",
"wwwroot/vendor/bootstrap4-creativestart/*.js",
"wwwroot/vendor/moment/moment.min.js",
"wwwroot/vendor/flatpickr/flatpickr.js",
"wwwroot/main/**/*.js"
"wwwroot/main/site.js"
]
},
{
@ -56,7 +56,6 @@
"wwwroot/checkout/**/*.js"
]
},
{
"outputFileName": "wwwroot/bundles/lightning-node-info-bundle.min.js",
"inputFiles": [
@ -71,12 +70,11 @@
"outputFileName": "wwwroot/bundles/cart-bundle.min.js",
"inputFiles": [
"wwwroot/vendor/jquery/jquery.js",
"wwwroot/vendor/bootstrap4/js/bootstrap.js",
"wwwroot/vendor/bootstrap/bootstrap.js",
"wwwroot/cart/js/cart.js",
"wwwroot/cart/js/cart.jquery.js"
]
},
{
"outputFileName": "wwwroot/bundles/crowdfund-bundle-1.min.js",
"inputFiles": [
@ -89,7 +87,6 @@
"wwwroot/crowdfund/**/*.js"
]
},
{
"outputFileName": "wwwroot/bundles/crowdfund-bundle-2.min.js",
"inputFiles": [
@ -133,7 +130,6 @@
"wwwroot/vendor/summernote/summernote-bs4.css"
]
},
{
"outputFileName": "wwwroot/bundles/crowdfund-bundle.min.css",
"inputFiles": [
@ -142,7 +138,6 @@
"wwwroot/crowdfund/**/*.css"
]
},
{
"outputFileName": "wwwroot/bundles/payment-request-admin-bundle.min.js",
"inputFiles": [
@ -150,14 +145,12 @@
"wwwroot/payment-request-admin/**/*.js"
]
},
{
"outputFileName": "wwwroot/bundles/payment-request-admin-bundle.min.css",
"inputFiles": [
"wwwroot/vendor/summernote/summernote-bs4.css"
]
},
{
"outputFileName": "wwwroot/bundles/payment-request-bundle-1.min.js",
"inputFiles": [
@ -170,7 +163,6 @@
"wwwroot/payment-request/**/*.js"
]
},
{
"outputFileName": "wwwroot/bundles/payment-request-bundle-2.min.js",
"inputFiles": [

File diff suppressed because it is too large Load diff

View file

@ -18,7 +18,7 @@ function Cart() {
this.listItems();
this.bindEmptyCart();
this.updateItemsCount();
this.updateAmount();
this.updatePosData();
@ -108,8 +108,8 @@ Cart.prototype.getTotalProducts = function() {
// Always calculate the total amount based on the cart content
for (var key in this.content) {
if (
this.content.hasOwnProperty(key) &&
typeof this.content[key] != 'undefined' &&
this.content.hasOwnProperty(key) &&
typeof this.content[key] != 'undefined' &&
!this.content[key].disabled
) {
var price = this.toCents(this.content[key].price.value);
@ -180,7 +180,7 @@ Cart.prototype.incrementItem = function(id) {
if(!result){
this.items = oldItemsCount;
}
this.updateAll();
return result;
}
@ -239,13 +239,13 @@ Cart.prototype.decrementItem = function(id) {
Cart.prototype.removeItemAll = function(id) {
var self = this;
this.items = 0;
// Remove by item
if (typeof id != 'undefined') {
this.content.filter(function(obj, index, arr){
if (obj.id === id) {
self.removeItem(id, index, arr);
for (var i = 0; i < obj.count; i++) {
self.items--;
}
@ -264,7 +264,7 @@ Cart.prototype.removeItemAll = function(id) {
Cart.prototype.removeItem = function(id, index, arr) {
// Remove from the array
arr.splice(index, 1);
arr.splice(index, 1);
// Remove from the DOM
this.$list.find('tr').eq(index+1).remove();
}
@ -386,7 +386,7 @@ Cart.prototype.template = function($template, obj) {
// Build the cart skeleton
Cart.prototype.buildUI = function() {
var $table = $('#js-cart-extra').find('tbody'),
var $table = $('#js-cart-extra').find('thead'),
list = [];
tableTemplate = this.template($('#template-cart-extra'), {
@ -420,7 +420,7 @@ Cart.prototype.listItems = function() {
self = this,
list = [],
tableTemplate = '';
if (this.content.length > 0) {
// Prepare the list of items in the cart
for (var key in this.content) {
@ -453,7 +453,7 @@ Cart.prototype.listItems = function() {
prevQty = parseInt($(this).data('prev')),
qtyDiff = Math.abs(qty - prevQty),
qtyIncreased = qty > prevQty;
if (isQty) {
$(this).data('prev', qty);
} else {
@ -509,10 +509,10 @@ Cart.prototype.listItems = function() {
// Increment item
$('.js-cart-item-plus').off().on('click', function(event){
event.preventDefault();
if(self.incrementItem($(this).closest('tr').data('id'))){
if(self.incrementItem($(this).closest('tr').data('id'))){
var $val = $(this).parents('.input-group').find('.js-cart-item-count'),
val = parseInt($val.val() || $val.data('prev')) + 1;
$val.val(val);
$val.data('prev', val);
self.resetTip();
@ -625,8 +625,8 @@ Cart.prototype.percentage = function(amount, percentage) {
/*
* Storage
*/
Cart.prototype.getStorageKey = function (name) {
return (name + srvModel.appId + srvModel.currencyCode);
Cart.prototype.getStorageKey = function (name) {
return (name + srvModel.appId + srvModel.currencyCode);
}
Cart.prototype.saveLocalStorage = function() {
@ -644,7 +644,7 @@ Cart.prototype.loadLocalStorage = function() {
continue;
}
//check if the pos items still has the cached cart items
//check if the pos items still has the cached cart items
var matchedItem = srvModel.items.find(function(item){
return item.id === self.content[i].id;
});
@ -653,7 +653,7 @@ Cart.prototype.loadLocalStorage = function() {
this.content.splice(i,1);
continue;
}else{
if(matchedItem.inventory != null && matchedItem.inventory <= 0){
//item is out of stock
this.content.splice(i,1);
@ -663,7 +663,7 @@ Cart.prototype.loadLocalStorage = function() {
}
//update its stock
this.content[i].inventory = matchedItem.inventory;
}
this.items += this.content[i].count;
// Delete the disabled flag if any
@ -730,7 +730,7 @@ $.fn.inputAmount = function(obj, type) {
$.fn.removeAmount = function(obj, type) {
$(this).off().on('click', function(event){
event.preventDefault();
switch (type) {
case 'customAmount':
obj.resetCustomAmount();
@ -745,6 +745,6 @@ $.fn.removeAmount = function(obj, type) {
obj.resetTip();
obj.updateTotal();
obj.updateSummaryTotal();
obj.emptyCartToggle();
obj.emptyCartToggle();
});
}

Binary file not shown.

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー_1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 400 400"
style="enable-background:new 0 0 400 400;" xml:space="preserve">
<g>
<g>
<rect x="0.3" y="0" width="400" height="400"/>
<path class="st0" fill="#FFFFFF" d="M88.51,195.08V86.72h50.52c21.05,0,50.16,19.81,50.16,55.11c0,31.89-24.15,53.25-52.94,53.25h-18.65v-21.67
h18.65c16.41,0,30.03-16.1,30.03-31.73c0-21.52-15.33-33.28-33.44-33.28h-21.42v86.69H88.51z M287.02,118.46
c-5.88-6.65-16.72-11.92-28.02-11.92c-19.5,0-32.97,15.63-32.97,33.75c0,18.11,13.47,33.75,32.97,33.75
c13.47,0,26.78-10.68,28.95-23.06h-30.03v-20.13h54.18v14.71c0,21.36-18.58,51.39-54.95,51.39c-32.35,0-55.26-25.54-55.26-56.04
c0-30.5,22.91-56.04,55.26-56.04c15.02,0,31.42,4.33,44.43,16.87L287.02,118.46z M111.5,206.38v73.02
c0,9.94,4.04,12.74,11.81,12.74h17.25v22.99h-22.84c-17.4,0-29.21-8.7-29.21-32.63v-76.13H111.5z M150.78,315.13v-70.85
c0-18.95,10.72-39.77,39-39.77c28.28,0,39.15,20.82,39.15,39.77v70.85h-24.24v-39.15h-23.61v-21.13h23.61v-14.6
c0-8.08-3.73-14.6-14.91-14.6c-11.19,0-14.76,6.53-14.76,14.6v74.89H150.78z M239.08,315.13v-71.78c0-27.5,14.6-38.84,36.2-38.84
c18.33,0,32.78,13.05,32.78,31.69c0,8.23-3.73,16.47-10.88,20.82c10.25,5.13,14.92,15.07,14.92,26.26
c0,18.02-11.5,31.85-29.68,31.85h-15.85v-21.75h12.27c6.52,0,10.25-5.13,10.25-12.12c0-9.32-5.44-12.59-11.81-12.59h-10.72
v-18.95h5.75c7.77,0,12.74-3.73,12.74-11.34c0-6.84-4.19-12.12-11.5-12.12c-7.46,0-12.74,4.35-12.74,14.91v73.95H239.08z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,6 @@
<svg width="121" height="119" xmlns="http://www.w3.org/2000/svg">
<g fill="#161514" fill-rule="evenodd">
<path d="M.221 60.833c0 26.681 17.303 49.317 41.297 57.302 3.018.559 4.126-1.31 4.126-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.479-3.748.413-3.671.413-3.671 6.064.426 9.257 6.223 9.257 6.223 5.386 9.232 14.127 6.563 17.573 5.02.542-3.903 2.107-6.567 3.834-8.075-13.413-1.527-27.513-6.705-27.513-29.844 0-6.593 2.359-11.98 6.222-16.209-.627-1.521-2.694-7.663.585-15.981 0 0 5.071-1.623 16.611 6.19 4.817-1.338 9.983-2.009 15.115-2.032 5.132.023 10.302.694 15.128 2.032 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.318 1.219 14.46.592 15.981 3.872 4.229 6.215 9.616 6.215 16.209 0 23.194-14.127 28.301-27.574 29.796 2.166 1.874 4.096 5.549 4.096 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.087 3.49 4.148 2.897 23.981-7.994 41.262-30.622 41.262-57.294 0-33.352-27.037-60.388-60.387-60.388C27.262.445.221 27.481.221 60.833z"/>
<path d="M23.093 87.149c-.133.3-.605.39-1.035.184-.438-.197-.684-.606-.542-.907.13-.309.603-.395 1.04-.188.439.197.689.61.537.911M25.539 89.877c-.288.267-.851.143-1.233-.279-.395-.421-.469-.984-.177-1.255.297-.267.843-.142 1.239.279.395.426.472.985.171 1.255M27.92 93.355c-.37.257-.975.016-1.349-.521-.37-.537-.37-1.181.008-1.439.375-.258.971-.026 1.35.507.369.546.369 1.19-.009 1.453M31.182 96.715c-.331.365-1.036.267-1.552-.231-.528-.487-.675-1.178-.343-1.543.335-.366 1.044-.263 1.564.231.524.486.684 1.182.331 1.543M35.682 98.666c-.146.473-.825.688-1.509.487-.683-.207-1.13-.761-.992-1.239.142-.476.824-.7 1.513-.485.682.206 1.13.756.988 1.237M40.624 99.028c.017.498-.563.911-1.281.92-.722.016-1.306-.387-1.314-.877 0-.503.567-.912 1.289-.924.718-.014 1.306.386 1.306.881M45.223 98.245c.086.486-.413.985-1.126 1.118-.701.128-1.35-.172-1.439-.654-.087-.498.421-.997 1.121-1.126.714-.124 1.353.168 1.444.662"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,10 @@
<svg class="logo" viewBox="0 0 192 84" xmlns="http://www.w3.org/2000/svg">
<g>
<path d="M5.206 83.433a4.86 4.86 0 01-4.859-4.861V5.431a4.86 4.86 0 119.719 0v73.141a4.861 4.861 0 01-4.86 4.861" fill="#CEDC21" class="logo-brand-light"/>
<path d="M5.209 83.433a4.862 4.862 0 01-2.086-9.253L32.43 60.274 2.323 38.093a4.861 4.861 0 015.766-7.826l36.647 26.999a4.864 4.864 0 01-.799 8.306L7.289 82.964a4.866 4.866 0 01-2.08.469" fill="#51B13E" class="logo-brand-medium"/>
<path d="M5.211 54.684a4.86 4.86 0 01-2.887-8.774L32.43 23.73 3.123 9.821a4.861 4.861 0 014.166-8.784l36.648 17.394a4.86 4.86 0 01.799 8.305l-36.647 27a4.844 4.844 0 01-2.878.948" fill="#CEDC21" class="logo-brand-light"/>
<path d="M10.066 31.725v20.553L24.01 42.006z" fill="#1E7A44" class="logo-brand-dark"/>
<path d="M10.066 5.431A4.861 4.861 0 005.206.57 4.86 4.86 0 00.347 5.431v61.165h9.72V5.431h-.001z" fill="#CEDC21" class="logo-brand-light"/>
<path d="M74.355 41.412c3.114.884 4.84 3.704 4.84 7.238 0 5.513-3.368 8.082-7.955 8.082H60.761V27.271h9.259c4.504 0 7.997 2.146 7.997 7.743 0 2.821-1.179 5.43-3.662 6.398m-4.293-.716c3.324 0 6.018-1.179 6.018-5.724 0-4.586-2.776-5.808-6.145-5.808h-7.197v11.531h7.324v.001zm1.052 14.099c3.366 0 6.06-1.768 6.06-6.145 0-4.713-3.072-6.144-6.901-6.144h-7.534v12.288h8.375v.001zM98.893 27.271v1.81h-8.122v27.651h-1.979V29.081h-8.123v-1.81zM112.738 26.85c5.01 0 9.554 2.524 10.987 8.543h-1.895c-1.348-4.923-5.303-6.732-9.134-6.732-6.944 0-10.605 5.681-10.605 13.341 0 8.08 3.661 13.256 10.646 13.256 4.125 0 7.828-1.85 9.26-7.279h1.895c-1.264 6.271-6.229 9.174-11.154 9.174-7.87 0-12.583-5.808-12.583-15.15 0-8.966 4.969-15.153 12.583-15.153M138.709 27.271c5.091 0 8.795 3.326 8.795 9.764 0 6.06-3.704 9.722-8.795 9.722h-7.746v9.976h-1.935V27.271h9.681zm0 17.549c3.745 0 6.816-2.397 6.816-7.827 0-5.429-2.947-7.869-6.816-7.869h-7.746V44.82h7.746zM147.841 56.732v-.255l11.741-29.29h.885l11.615 29.29v.255h-2.062l-3.322-8.501H153.27l-3.324 8.501h-2.105zm12.164-26.052l-6.059 15.697h12.078l-6.019-15.697zM189.551 27.271h2.104v.293l-9.176 16.92v12.248h-2.02V44.484l-9.216-16.961v-.252h2.147l3.997 7.492 4.043 7.786h.04l4.081-7.786z" fill="#FFF" class="logo-brand-text"/>
</g>
</svg>

View file

@ -0,0 +1,6 @@
<svg width="206" height="206" xmlns="http://www.w3.org/2000/svg">
<g>
<path d="M163.012 19.596l1.082 21.794c17.667 19.519 24.641 47.161 15.846 73.14-13.129 38.782-56.419 59.169-96.693 45.535-40.272-13.633-62.278-56.124-49.15-94.905 8.825-26.066 31.275-43.822 57.276-48.524L105.422.038C61.592-1.15 20.242 26.056 5.448 69.76c-18.178 53.697 10.616 111.963 64.314 130.142 53.698 18.178 111.964-10.617 130.143-64.315 14.77-43.633-1.474-90.283-36.893-115.99"/>
<path d="M137.097 53.436l-.596-17.531-.404-15.189s.084-7.322-.17-9.043a2.776 2.776 0 00-.305-.914l-.05-.109-.06-.094a2.378 2.378 0 00-1.293-1.07 2.382 2.382 0 00-1.714.078l-.033.014-.18.092a2.821 2.821 0 00-.75.518c-1.25 1.212-5.63 7.08-5.63 7.08l-9.547 11.82-11.123 13.563-19.098 23.75s-8.763 10.938-6.827 24.4c1.937 13.464 11.946 20.022 19.71 22.65 7.765 2.63 19.7 3.5 29.417-6.019 9.716-9.518 9.397-23.53 9.397-23.53l-.744-30.466z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 916 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

@ -0,0 +1,8 @@
<svg viewBox="0 0 54 54" xmlns="http://www.w3.org/2000/svg">
<g>
<path d="M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381 5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386" fill="#36C5F0"></path>
<path d="M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376 5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381 0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0 5.376 5.387 5.381 5.381 0 0 0 5.376-5.387" fill="#2EB67D"></path>
<path d="M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381 5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386" fill="#ECB22E"></path>
<path d="M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0 5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381 5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381 0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387" fill="#E01E5A"></path>
</g>
</svg>

View file

@ -0,0 +1,3 @@
<svg width="250" height="204" xmlns="http://www.w3.org/2000/svg">
<path d="M78.62 203.59c94.34 0 145.94-78.16 145.94-145.94 0-2.22 0-4.43-.15-6.63A104.36 104.36 0 00250 24.47a102.38 102.38 0 01-29.46 8.07 51.47 51.47 0 0022.55-28.37 102.79 102.79 0 01-32.57 12.45C194.62-.286 169.357-4.424 148.895 6.527c-20.461 10.95-31.032 34.266-25.785 56.873A145.62 145.62 0 0117.4 9.81C3.786 33.246 10.74 63.229 33.28 78.28A50.91 50.91 0 0110 71.86v.65c.007 24.416 17.218 45.445 41.15 50.28a51.21 51.21 0 01-23.16.88c6.72 20.894 25.976 35.208 47.92 35.62a102.92 102.92 0 01-63.7 22A104.41 104.41 0 010 180.55a145.21 145.21 0 0078.62 23" fill="#1DA1F2" fill-rule="nonzero"/>
</svg>

After

Width:  |  Height:  |  Size: 671 B

View file

@ -1,81 +0,0 @@
$(document).ready(function() {
var trezorInit = false;
$(".check-for-trezor").on("click",
function() {
if (!trezorInit || !window.trezorDevice) {
trezorClient.init();
trezorInit = true;
}
});
$("[data-trezorkeypath]").on("click",
function() {
$("#trezor-error").hide();
var keypath = $(this).data("trezorkeypath");
var suffix = $(this).data("derivation-suffix");
var keys = keypath.split("/");
if (trezorDevice != null) {
var hardeningConstant = 0x80000000;
trezorDevice.waitForSessionAndRun(function(session) {
var path = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (keys[i].endsWith("'")) {
key = key.substring(0, key.length - 1);
path.push((parseInt(key) | hardeningConstant) >>> 0);
continue;
}
path.push(parseInt(key));
}
return session.getHDNode(path, window.coinName);
})
.then(function(hdNode) {
$("#RootFingerprint").val(hdNode.parentFingerprint);
$("#KeyPath").val(keys[keys.length - 1]);
$("#DerivationScheme").val(hdNode.toBase58()+ suffix);
$("#trezorsubmitbutton").show();
}).catch(function(e){
alert(e.message);
$("#trezor-error").text("An error occurred when communicating with the trezor device. try with a different USB port?").show();
})
}
});
$("[data-hide]").on("click", function(){
$($(this).data("hide")).hide();
});
$("[data-show]").on("click", function(){
$($(this).data("show")).show();
});
$(".trezor-account-dropdown select").on("input", function(){
$(this).find(":selected").click();
});
$("#trezor-address-type-select").on("input", function(){
$(this).find(":selected").click();
$("#RootFingerprint").val("");
$("#KeyPath").val("");
$("#DerivationScheme").val("");
$("#trezorsubmitbutton").hide();
});
});
function onTrezorDeviceFound(device) {
$(".display-when-trezor-connected").show();
}
function onTrezorDeviceLost(){
$(".display-when-trezor-connected").hide();
$("#RootFingerprint").val("");
$(".trezor-account-dropdown").hide();
$("#KeyPath").val("");
$("#DerivationScheme").val("");
$("#trezorsubmitbutton").hide();
}

View file

@ -1,73 +0,0 @@
window.deviceList = null;
window.trezorClient = {
init: function () {
document.getElementById("trezor-loading").style.display = "block";
window.trezorDeviceList = new trezor.DeviceList({
config: window.trezorConfig || null,
debug: true,
transport: new trezorLink.Lowlevel(new trezorLink.WebUsb(), function () {
return null;
})
});
trezorDeviceList.on("connect", trezorClient.onDeviceConnected);
trezorDeviceList.on("connectUnacquired", function(e){
e.steal.then(trezorClient.onDeviceConnected);
});
trezorDeviceList.on("transport", function(){
if (trezorDeviceList.asArray().length < 1 || trezorDeviceList.requestNeeded) {
if (!navigator.usb) {
document.getElementById("trezor-loading").style.display = "none";
document.getElementById("trezor-error").style.display = "block";
document.getElementById("trezor-error").innerHTML = 'Your browser does not support WebUsb. Please switch to a <a href="https://caniuse.com/#feat=webusb" target="_blank">supported browser</a> or request Trezor to implement <a href="https://github.com/trezor/trezord-go/issues/155" target="_blank">this feature</a>.';
return;
}
trezorClient.requestDevice();
}
});
},
requestDevice: function () {
return trezorDeviceList.requestDevice().catch(function () {
document.getElementById("trezor-loading").style.display = "none";
document.getElementById("trezor-error").style.display = "block";
document.getElementById("trezor-error").innerText = 'Device could not be acquired. Do you have another app using the device?';
})
},
onDeviceConnected: function (device) {
window.trezorDevice = null;
document.getElementById("trezor-error").style.display = "none";
document.getElementById("trezor-error").innerText = 'Device could not be used.';
device.on('disconnect', function () {
window.trezorDevice = null;
document.getElementById("trezor-error").style.display = "block";
document.getElementById("trezor-error").innerText = 'Device was disconnected';
document.getElementById("trezor-loading").style.display = "block";
document.getElementById("trezor-success").style.display = "none";
if (window.onTrezorDeviceLost) {
window.onTrezorDeviceLost();
}
});
if (device.isBootloader()) {
document.getElementById("trezor-error").style.display = "block";
document.getElementById("trezor-error").innerText = 'Device is in Bootloader, please reconnect it.';
return;
}
if (!device.isInitialized()) {
document.getElementById("trezor-error").style.display = "block";
document.getElementById("trezor-error").innerText = 'Device is not yet setup.';
return;
}
document.getElementById("trezor-loading").style.display = "none";
document.getElementById("trezor-success").style.display = "block";
window.trezorDevice = device;
if (window.onTrezorDeviceFound) {
document.getElementById("trezor-devicename").innerText = device.features.label;
window.onTrezorDeviceFound(device);
}
}
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,170 @@
/*!
* Start Bootstrap - Creative v4.0.0-beta (http://startbootstrap.com/template-overviews/creative)
* Copyright 2013-2017 Start Bootstrap
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-creative/blob/master/LICENSE)
*/
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--btcpay-font-family-head);
}
section {
padding: 100px 0;
}
p {
margin-bottom: 1.5rem;
}
hr {
width: 50px;
height: 3px;
background: var(--btcpay-color-primary);
display: inline-block;
}
hr.light {
background: var(--btcpay-color-white);
}
#mainNav {
color: var(--btcpay-header-color, var(--btcpay-color-neutral-100));
background: var(--btcpay-header-bg, var(--btcpay-bg-dark));
font-family: var(--btcpay-font-family-head);
transition-property: background, color;
transition-duration: 0.2s;
}
@media (min-width: 992px) {
#mainNav {
background: transparent;
}
#mainNav.navbar-shrink {
background: var(--btcpay-header-bg, var(--btcpay-bg-dark));
}
}
#mainNav .navbar-nav > li.nav-item > a.nav-link {
font-size: 13px;
font-weight: bold;
text-transform: uppercase;
color: var(--btcpay-header-color-link, var(--btcpay-color-neutral-100));
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus,
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover {
color: var(--btcpay-header-color-link-accent, var(--btcpay-color-white));
}
#mainNav .navbar-nav > li.nav-item > a.nav-link.active,
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:focus,
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover {
color: var(--btcpay-header-color-link-active, var(--btcpay-color-white));
}
header.masthead {
position: relative;
display: block;
min-height: auto;
text-align: center;
}
header.masthead::before {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background-image: url("../../img/bg.png");
background-position: center;
background-size: cover;
}
header.masthead .header-content {
position: relative;
width: 100%;
padding: 150px 15px 100px;
text-align: center;
}
header.masthead .header-content .header-content-inner h1 {
font-size: 30px;
font-weight: 700;
margin-top: 0;
margin-bottom: 0;
text-transform: uppercase;
}
header.masthead .header-content .header-content-inner hr {
margin: 30px auto;
}
header.masthead .header-content .header-content-inner p {
font-size: 16px;
font-weight: 300;
margin-bottom: 50px;
}
@media (min-width: 768px) {
header.masthead {
height: 70%;
min-height: 600px;
}
header.masthead .header-content {
position: absolute;
top: 50%;
padding: 0 50px;
transform: translateY(-50%);
}
header.masthead .header-content .header-content-inner {
max-width: 1000px;
margin-right: auto;
margin-left: auto;
}
header.masthead .header-content .header-content-inner h1 {
font-size: 50px;
}
header.masthead .header-content .header-content-inner p {
font-size: 18px;
max-width: 80%;
margin-right: auto;
margin-left: auto;
}
}
.service-box {
max-width: 400px;
margin: 50px auto 0;
}
@media (min-width: 992px) {
.service-box {
margin: 20px auto 0;
}
}
.service-box p {
margin-bottom: 0;
}
.call-to-action {
padding: 50px 0;
}
.call-to-action h2 {
margin: 0 auto 20px;
}
.no-gutter > [class*='col-'] {
padding-right: 0;
padding-left: 0;
}

View file

@ -1,131 +0,0 @@
html {
position: relative;
min-height: 100%;
}
.siteFooter {
position: absolute;
left: 0;
bottom: 0;
height: 18px;
line-height: 18px;
vertical-align: middle;
font-size: 8px;
width: 100%;
overflow: hidden;
}
.only-for-js, .input-group-clear {
display: none;
}
#content {
background: #fff;
border: 1px solid #DFE3E8;
padding: 16px;
border-radius: 4px;
}
.table {
background: #fff;
border: 1px solid #DFE3E8;
border-radius: 4px;
border-collapse: separate !important;
border-spacing: 0px !important;
margin-top: 16px;
margin-bottom: 16px;
}
.table thead > tr {
height: 36px;
}
.table thead th {
border-bottom: none;
border-top: none;
vertical-align: middle;
padding: 4px 12px 4px 12px;
}
.table tbody tr:hover {
background-color: #f8fafc;
}
.table tr {
height: 36px;
}
.table th {
display: table-cell;
padding: 4px 12px 4px 12px;
vertical-align: middle;
}
.table td {
display: table-cell;
padding: 4px 12px 4px 12px;
text-align: left;
color: #12161B;
font-size: 0.8125rem;
font-weight: 400;
vertical-align: middle;
}
.removetopborder tr:first-child td {
border-top: none;
}
.removetopborder tr:first-child th {
border-top: none;
}
a.nav-link {
color: #66788A;
}
.nav-pills .nav-link.active {
color: var(--gray-dark);
font-weight: 500;
}
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
color: #66788A;
background-color: #d9f7ef;
border-left: 5px solid var(--primary);
font-weight: 500;
}
.display-when-ledger-connected {
display: none;
}
.wraptextAuto {
max-width: 300px;
text-overflow: ellipsis;
overflow: hidden;
display: block;
white-space: nowrap;
}
@media (min-width: 768px) {
.wraptextAuto {
max-width: 600px;
}
}
.invoice-details a{
/* Prevent layout from breaking on hyperlinks with very long URLs as the visible text */
word-break: break-word;
}
.smMaxWidth {
max-width: 150px;
}
@media (min-width: 768px) {
.smMaxWidth {
max-width: 300px;
}
}

View file

@ -0,0 +1,117 @@
/* General and site-wide Bootstrap modifications */
html {
position: relative;
min-height: 100%;
}
.logo {
height: 45px;
}
.only-for-js,
.input-group-clear {
display: none;
}
.wraptextAuto {
max-width: 300px;
text-overflow: ellipsis;
overflow: hidden;
display: block;
white-space: nowrap;
}
@media (min-width: 768px) {
.wraptextAuto {
max-width: 600px;
}
}
.smMaxWidth {
max-width: 150px;
}
@media (min-width: 768px) {
.smMaxWidth {
max-width: 300px;
}
}
a {
transition-duration: 0.2s;
transition-property: background, color;
}
/* Admin Sections */
.section-heading {
text-align: var(--btcpay-section-heading-text-align, center);
}
/* Admin Sidebar Navigation */
a.nav-link {
color: var(--btcpay-nav-color-link, var(--btcpay-color-neutral-600));
background: var(--btcpay-bg-nav-link, transparent);
}
a.nav-link:focus,
a.nav-link:hover {
color: var(--btcpay-nav-color-link-accent, var(--btcpay-color-neutral-700));
background: var(--btcpay-bg-nav-link-hover, transparent);
}
.col-md-3 .nav-pills {
margin-left: -1rem;
}
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
color: var(--btcpay-nav-color-link-active, var(--btcpay-color-neutral-900));
background: var(--btcpay-bg-nav-link-active, var(--btcpay-color-primary-backdrop));
font-weight: 500;
}
.display-when-ledger-connected {
display: none;
}
/* Homepage */
#services img {
margin-bottom: 1rem;
}
.social-row {
margin: 2rem 0;
}
.social-row > div {
margin-bottom: 3rem;
}
.social-row img {
height: 50px;
}
.social-row span {
display: block;
margin-top: 1rem;
}
/* Footer */
.footer {
position: absolute;
left: 0;
bottom: 0;
height: 18px;
line-height: 18px;
vertical-align: middle;
font-size: 8px;
width: 100%;
overflow: hidden;
color: var(--btcpay-color-footer, var(--btcpay-color-neutral-100));
background: var(--btcpay-footer-bg, var(--btcpay-bg-dark));
}
/* Prevent layout from breaking on hyperlinks with very long URLs as the visible text */
.invoice-details a {
word-break: break-word;
}

View file

@ -0,0 +1,106 @@
:root {
/* General color definitions */
--btcpay-brand-light: #B498FF;
--btcpay-brand-medium: #8064ef;
--btcpay-brand-dark: #321a6e;
--btcpay-brand-darker: #19154B;
--btcpay-brand-darkest: #02000C;
--btcpay-color-white: #fff;
--btcpay-color-black: #000;
--btcpay-color-neutral-100: #F3F1FF;
--btcpay-color-neutral-200: #DCD7FC;
--btcpay-color-neutral-300: #CDC6F3;
--btcpay-color-neutral-400: #AEA7D7;
--btcpay-color-neutral-500: #7a72a0;
--btcpay-color-neutral-600: #8880ad;
--btcpay-color-neutral-700: #49308b;
--btcpay-color-neutral-800: #181334;
--btcpay-color-neutral-900: #100d20;
/* Color definitions for specific purposes - map the general colors or define additional ones */
--btcpay-color-primary: var(--btcpay-brand-medium); /* Usage: Text color */
--btcpay-color-primary-backdrop: #baa4fd; /* Usage: Backgrounds, borders, shadows */
--btcpay-color-primary-accent: #4b3bc0; /* Usage: Background on Focus/Hover */
--btcpay-color-secondary: var(--btcpay-color-neutral-600);
--btcpay-color-secondary-backdrop: var(--btcpay-color-neutral-100);
--btcpay-color-secondary-accent: var(--btcpay-color-neutral-500);
--btcpay-color-success: #25933d;
--btcpay-color-success-backdrop: #c3e6cb;
--btcpay-color-success-accent: #137929;
--btcpay-color-info: #0698c9;
--btcpay-color-info-backdrop: #c0eefe;
--btcpay-color-info-accent: #0698c9;
--btcpay-color-warning: #e5ac00;
--btcpay-color-warning-backdrop: #ffeeba;
--btcpay-color-warning-accent: #e5ac00;
--btcpay-color-danger: #bd2130;
--btcpay-color-danger-backdrop: #EDA1B0;
--btcpay-color-danger-accent: #bd2130;
--btcpay-color-light: var(--btcpay-color-neutral-600);
--btcpay-color-light-backdrop: var(--btcpay-color-neutral-100);
--btcpay-color-light-accent: var(--btcpay-color-neutral-500);
--btcpay-color-dark: var(--btcpay-color-neutral-400);
--btcpay-color-dark-backdrop: var(--btcpay-brand-darker);
--btcpay-color-dark-accent: var(--btcpay-color-neutral-400);
/* Color definitions for specific sections - try to reuse colors defined above */
--btcpay-bg-body: var(--btcpay-brand-darkest);
--btcpay-bg-dark: var(--btcpay-brand-darker);
--btcpay-bg-tile: var(--btcpay-brand-dark);
--btcpay-bg-cta: var(--btcpay-brand-dark);
--btcpay-body-color: var(--btcpay-color-neutral-100);
--btcpay-body-color-link: var(--btcpay-color-primary);
--btcpay-body-color-link-accent: var(--btcpay-color-primary-accent);
--btcpay-section-heading-text-align: left;
--btcpay-nav-color-link-accent: var(--btcpay-color-neutral-100);
--btcpay-header-bg: var(--btcpay-brand-darker);
--btcpay-footer-bg: var(--btcpay-brand-darkest);
--btcpay-font-size-base: 16px;
--btcpay-font-family-head: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
--btcpay-font-family-base: -apple-system, 'Open Sans', BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--btcpay-font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/* Bootstrap modifications */
html {
font-size: var(--btcpay-font-size-base);
}
body {
background: linear-gradient(var(--btcpay-header-bg), var(--btcpay-footer-bg));
background-attachment: fixed;
}
.logo,
.head-logo,
.social-logo {
filter: contrast(0) brightness(200%);
}
.bg-dark {
background-color: var(--btcpay-bg-dark) !important;
}
#mainNav {
background: var(--btcpay-header-bg) !important;
}
header.masthead::before,
.service-box img {
filter: hue-rotate(100deg) opacity(60%) contrast(125%);
}
.table {
margin: 1.5rem 0 3rem;
}
.table th {
border-top: 0;
}

View file

@ -0,0 +1,103 @@
:root {
/* General color definitions */
--btcpay-brand-light: #CEDC21;
--btcpay-brand-medium: #51B13E;
--btcpay-brand-dark: #137547;
--btcpay-brand-darker: #0F3B21;
--btcpay-brand-darkest: #05120a;
--btcpay-color-white: #fff;
--btcpay-color-black: #000;
--btcpay-color-neutral-100: #f8f9fa;
--btcpay-color-neutral-200: #e9ecef;
--btcpay-color-neutral-300: #dee2e6;
--btcpay-color-neutral-400: #ced4da;
--btcpay-color-neutral-500: #adb5bd;
--btcpay-color-neutral-600: #6c757d;
--btcpay-color-neutral-700: #495057;
--btcpay-color-neutral-800: #343a40;
--btcpay-color-neutral-900: #212529;
/* Color definitions for specific purposes - map the general colors or define additional ones */
--btcpay-color-primary: #329f80;
--btcpay-color-primary-backdrop: rgba(81, 173, 147, 0.25);
--btcpay-color-primary-accent: #267861;
--btcpay-color-secondary: var(--btcpay-color-neutral-600);
--btcpay-color-secondary-backdrop: rgba(130, 138, 145, 0.25);
--btcpay-color-secondary-accent: var(--btcpay-color-neutral-800);
--btcpay-color-success: #329f80;
--btcpay-color-success-backdrop: rgba(72, 180, 97, 0.25);
--btcpay-color-success-accent: #1e7e34;
--btcpay-color-info: #17a2b8;
--btcpay-color-info-backdrop: rgba(58, 176, 195, 0.25);
--btcpay-color-info-accent: #117a8b;
--btcpay-color-warning: #ffc107;
--btcpay-color-warning-backdrop: #fff3cd;
--btcpay-color-warning-accent: #d39e00;
--btcpay-color-danger: #dc3545;
--btcpay-color-danger-backdrop: rgba(225, 83, 97, 0.25);
--btcpay-color-danger-accent: #bd2130;
--btcpay-color-light: var(--btcpay-color-neutral-600);
--btcpay-color-light-backdrop: var(--btcpay-color-neutral-100);
--btcpay-color-light-accent: var(--btcpay-color-neutral-500);
--btcpay-color-dark: var(--btcpay-color-neutral-400);
--btcpay-color-dark-backdrop: var(--btcpay-color-neutral-700);
--btcpay-color-dark-accent: var(--btcpay-color-neutral-400);
/* Color definitions for specific sections - try to reuse colors defined above */
--btcpay-bg-body: var(--btcpay-color-neutral-100);
--btcpay-bg-dark: var(--btcpay-brand-darker);
--btcpay-bg-tile: var(--btcpay-color-white);
--btcpay-bg-cta: var(--btcpay-bg-dark);
--btcpay-body-color: var(--btcpay-color-neutral-900);
--btcpay-body-color-link: var(--btcpay-color-primary);
--btcpay-body-color-link-accent: var(--btcpay-color-primary-accent);
--btcpay-bg-nav-link-active: #d9f7ef;
--btcpay-font-size-base: 14px;
--btcpay-font-family-head: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
--btcpay-font-family-base: 'Helvetica Neue', Arial, sans-serif;
--btcpay-font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/* Bootstrap modifications */
html {
font-size: var(--btcpay-font-size-base);
}
.bg-dark {
background-color: var(--btcpay-bg-dark) !important;
}
.table {
margin: 1.5rem 0;
background: var(--btcpay-color-white);
border: 1px solid var(--btcpay-color-neutral-300);
border-radius: 4px;
border-collapse: separate !important;
border-spacing: 0px !important;
}
.table thead > tr {
height: 36px;
}
.table thead th {
border-bottom: none;
border-top: none;
}
.table th,
.table td {
display: table-cell;
padding: 8px 12px;
vertical-align: middle;
}
.removetopborder tr:first-child th,
.removetopborder tr:first-child td {
border-top: none;
}

View file

@ -0,0 +1,76 @@
:root {
--btcpay-color-white: #fff;
--btcpay-color-black: #000;
--btcpay-color-neutral-100: #FBFAF8;
--btcpay-color-neutral-200: #F5F5F3;
--btcpay-color-neutral-300: #E5E5E5;
--btcpay-color-neutral-400: #ced4da;
--btcpay-color-neutral-500: #adb5bd;
--btcpay-color-neutral-600: #536E8D;
--btcpay-color-neutral-700: #465C76;
--btcpay-color-neutral-800: #244B71;
--btcpay-color-neutral-900: #202C39;
--btcpay-color-primary: #329f80;
--btcpay-color-primary-accent: #267861;
--btcpay-color-primary-backdrop: rgba(81, 173, 147, 0.2);
--btcpay-color-secondary: var(--btcpay-color-neutral-600);
--btcpay-color-secondary-accent: var(--btcpay-color-neutral-800);
--btcpay-color-secondary-backdrop: rgba(130, 138, 145, 0.25);
--btcpay-color-success: #329f80;
--btcpay-color-success-accent: #1e7e34;
--btcpay-color-success-backdrop: rgba(72, 180, 97, 0.25);
--btcpay-color-info: #17a2b8;
--btcpay-color-info-accent: #117a8b;
--btcpay-color-info-backdrop: rgba(58, 176, 195, 0.25);
--btcpay-color-warning: #ffc107;
--btcpay-color-warning-accent: #d39e00;
--btcpay-color-warning-backdrop: rgba(222, 170, 12, 0.25);
--btcpay-color-danger: #dc3545;
--btcpay-color-danger-accent: #bd2130;
--btcpay-color-danger-backdrop: rgba(225, 83, 97, 0.25);
--btcpay-color-light: var(--btcpay-color-neutral-100);
--btcpay-color-light-accent: #dae0e5;
--btcpay-color-light-backdrop: rgba(216, 217, 219, 0.25);
--btcpay-color-dark: var(--btcpay-color-neutral-900);
--btcpay-color-dark-accent: #1d2124;
--btcpay-color-dark-backdrop: rgba(82, 88, 93, 0.25);
--btcpay-bg-body: var(--btcpay-color-neutral-100);
--btcpay-bg-dark: var(--btcpay-color-neutral-900);
--btcpay-bg-tile: var(--btcpay-color-white);
--btcpay-bg-cta: var(--btcpay-bg-dark);
--btcpay-body-color: var(--btcpay-color-neutral-900);
--btcpay-body-color-link: var(--btcpay-color-primary);
--btcpay-body-color-link-accent: var(--btcpay-color-primary-accent);
--btcpay-section-heading-text-align: left;
--btcpay-font-size-base: 16px;
--btcpay-font-family-head: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
--btcpay-font-family-base: -apple-system, 'Open Sans', BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--btcpay-font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/* Bootstrap modifications */
html {
font-size: var(--btcpay-font-size-base);
}
.bg-dark {
background-color: var(--btcpay-bg-dark) !important;
}
header.masthead::before,
.service-box img {
filter: hue-rotate(410deg) saturate(33%); }
.table {
margin: 1.5rem 0 3rem;
}
.table th {
border-top: 0;
}

View file

@ -1,338 +0,0 @@
/*!
* Start Bootstrap - Creative v4.0.0-beta (http://startbootstrap.com/template-overviews/creative)
* Copyright 2013-2017 Start Bootstrap
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-creative/blob/master/LICENSE)
*/
:root {
--off-white: #f9fafb;
}
body,
html {
width: 100%;
/* background: #f9fafb; */
background: var(--off-white);
}
body {
font-family: 'Helvetica Neue', Arial, sans-serif;
background: var(--off-white);
}
hr {
max-width: 50px;
border-width: 3px;
border-color: #329F80;
}
hr.light {
border-color: white;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
p {
/*font-size: 16px;*/
line-height: 1.5;
margin-bottom: 20px;
}
section {
padding: 100px 0;
}
.section-heading {
margin-top: 0;
}
::-moz-selection {
color: white;
background: #222222;
text-shadow: none;
}
::selection {
color: white;
background: #222222;
text-shadow: none;
}
img::selection {
color: white;
background: transparent;
}
img::-moz-selection {
color: white;
background: transparent;
}
body {
-webkit-tap-highlight-color: #222222;
}
#mainNav {
border-color: rgba(34, 34, 34, 0.05);
background-color: #0F3723;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
#mainNav .navbar-brand {
font-weight: 700;
text-transform: uppercase;
color: #0F3B21;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: #0F3B21;
}
#mainNav .navbar-toggle {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
color: #222222;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus,
#mainNav .navbar-nav > li.nav-item > a.nav-link {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: white;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover {
color: white;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active,
#mainNav .navbar-nav > li.nav-item > a.nav-link.active {
color: white !important;
background-color: transparent;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover {
background-color: transparent;
}
@media (min-width: 992px) {
#mainNav {
border-color: rgba(255, 255, 255, 0.3);
background-color: transparent;
}
#mainNav .navbar-brand {
color: rgba(255, 255, 255, 0.7);
}
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
color: white;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
color: white;
}
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
color: white;
}
#mainNav.navbar-shrink {
border-color: rgba(34, 34, 34, 0.05);
background-color: #0F3723;
}
#mainNav.navbar-shrink .navbar-brand {
font-size: 16px;
color: #0F3B21;
}
#mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover {
color: #0F3B21;
}
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link,
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus {
color: white;
}
}
header.masthead {
position: relative;
width: 100%;
min-height: auto;
text-align: center;
background-image: url("../../img/bg.png");
background-position: center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
header.masthead .header-content {
position: relative;
width: 100%;
padding: 150px 15px 100px;
text-align: center;
}
header.masthead .header-content .header-content-inner h1 {
font-size: 30px;
font-weight: 700;
margin-top: 0;
margin-bottom: 0;
text-transform: uppercase;
}
header.masthead .header-content .header-content-inner hr {
margin: 30px auto;
}
header.masthead .header-content .header-content-inner p {
font-size: 16px;
font-weight: 300;
margin-bottom: 50px;
}
@media (min-width: 768px) {
header.masthead {
height: 70%;
min-height: 600px;
}
header.masthead .header-content {
position: absolute;
top: 50%;
padding: 0 50px;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
header.masthead .header-content .header-content-inner {
max-width: 1000px;
margin-right: auto;
margin-left: auto;
}
header.masthead .header-content .header-content-inner h1 {
font-size: 50px;
}
header.masthead .header-content .header-content-inner p {
font-size: 18px;
max-width: 80%;
margin-right: auto;
margin-left: auto;
}
}
.service-box {
max-width: 400px;
margin: 50px auto 0;
}
@media (min-width: 992px) {
.service-box {
margin: 20px auto 0;
}
}
.service-box p {
margin-bottom: 0;
}
.portfolio-box {
position: relative;
display: block;
max-width: 650px;
margin: 0 auto;
}
.portfolio-box .portfolio-box-caption {
position: absolute;
bottom: 0;
display: block;
width: 100%;
height: 100%;
text-align: center;
opacity: 0;
background: rgba(240, 95, 64, 0.9);
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
position: absolute;
top: 50%;
width: 100%;
transform: translateY(-50%);
text-align: center;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
padding: 0 15px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 18px;
}
.portfolio-box:hover .portfolio-box-caption {
opacity: 1;
}
.portfolio-box:focus {
outline: none;
}
@media (min-width: 768px) {
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 16px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 22px;
}
}
.call-to-action {
padding: 50px 0;
}
.call-to-action h2 {
margin: 0 auto 20px;
}
.no-gutter > [class*='col-'] {
padding-right: 0;
padding-left: 0;
}

View file

@ -1,4 +0,0 @@
$primary: #329f80;
$secondary: #2284A6;
$dark: #0f3b21;
$font-size-base: 0.9rem;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
The contents of this folder was generated by https://github.com/btcpayserver/trezor-webpack-wrapper

File diff suppressed because one or more lines are too long

View file

@ -146,10 +146,17 @@ The BTCPay Server Project is proudly supported by these entities through the [BT
<tr>
<td align="center" valign="middle">
<a href="https://twitter.com/sqcrypto" target="_blank">
<img src="BTCPayServer/wwwroot/img/squarecrypto.svg" alt="Sponsor Square Crypto" height=100>
<img src="BTCPayServer/wwwroot/img/squarecrypto.svg" alt="Square Crypto" height=100>
<br/>
<span>Square Crypto</span>
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.dglab.com/en/" target="_blank">
<img src="BTCPayServer/wwwroot/img/dglab.svg" alt="DG Lab" height=100>
<br/>
<span>DG Lab</span>
</a>
</td>
<td align="center" valign="middle">
<a href="https://acinq.co/" target="_blank">
@ -160,3 +167,6 @@ The BTCPay Server Project is proudly supported by these entities through the [BT
</td>
</tr>
</tbody>
</table>
If you'd like to support the project, please visit the [donation page](https://btcpayserver.org/donate/).