diff --git a/BTCPayServer.Abstractions/Custodians/Client/Exception/CustodianApiException.cs b/BTCPayServer.Abstractions/Custodians/Client/Exception/CustodianApiException.cs index a650918f0..be6792bcb 100644 --- a/BTCPayServer.Abstractions/Custodians/Client/Exception/CustodianApiException.cs +++ b/BTCPayServer.Abstractions/Custodians/Client/Exception/CustodianApiException.cs @@ -10,7 +10,7 @@ public class CustodianApiException : Exception HttpStatus = httpStatus; Code = code; } - + public CustodianApiException(int httpStatus, string code, string message) : this(httpStatus, code, message, null) { } diff --git a/BTCPayServer.Abstractions/Form/Field.cs b/BTCPayServer.Abstractions/Form/Field.cs index f9ee0573a..d9e0e1cfb 100644 --- a/BTCPayServer.Abstractions/Form/Field.cs +++ b/BTCPayServer.Abstractions/Form/Field.cs @@ -52,10 +52,10 @@ public class Field public string HelpText; [JsonExtensionData] public IDictionary AdditionalData { get; set; } - public List Fields { get; set; } = new (); + public List Fields { get; set; } = new(); // The field is considered "valid" if there are no validation errors - public List ValidationErrors = new (); + public List ValidationErrors = new(); public virtual bool IsValid() { diff --git a/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs b/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs index 72c69dcc4..49e0c6c45 100644 --- a/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs +++ b/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs @@ -23,12 +23,12 @@ public class SVGUse : UrlResolutionTagHelper2 { _fileVersionProvider = fileVersionProvider; } - + public override void Process(TagHelperContext context, TagHelperOutput output) { var attr = output.Attributes["href"].Value.ToString(); var symbolIndex = attr!.IndexOf("#", StringComparison.InvariantCulture); - var start = attr.IndexOf("~", StringComparison.InvariantCulture) + 1; + var start = attr.IndexOf("~", StringComparison.InvariantCulture) + 1; var length = (symbolIndex != -1 ? symbolIndex : attr.Length) - start; var filePath = attr.Substring(start, length); if (!string.IsNullOrEmpty(filePath)) diff --git a/BTCPayServer.Client/BTCPayServerClient.Apps.cs b/BTCPayServer.Client/BTCPayServerClient.Apps.cs index 8cf26ca5a..5dc704d2e 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Apps.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Apps.cs @@ -51,7 +51,7 @@ namespace BTCPayServer.Client method: HttpMethod.Get), token); return await HandleResponse(response); } - + public virtual async Task GetAllApps(string storeId, CancellationToken token = default) { if (storeId == null) diff --git a/BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs b/BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs index 5129bfc2f..95b3b572e 100644 --- a/BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs +++ b/BTCPayServer.Client/BTCPayServerClient.CustodianAccounts.cs @@ -80,13 +80,13 @@ namespace BTCPayServer.Client var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token); return await HandleResponse(response); } - - public virtual async Task CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default) + + public virtual async Task CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default) { var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals", bodyPayload: request, method: HttpMethod.Post), token); return await HandleResponse(response); } - + public virtual async Task SimulateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default) { var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/simulation", bodyPayload: request, method: HttpMethod.Post), token); diff --git a/BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs b/BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs index 7d777521e..36abdf8d4 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs @@ -113,7 +113,7 @@ namespace BTCPayServer.Client CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload), token); return await HandleResponse(response); } - + public virtual async Task GetLightningPayments(string cryptoCode, bool? includePending = null, long? offsetIndex = null, CancellationToken token = default) { diff --git a/BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs b/BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs index e2dc8bf6f..abe4c6c06 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs @@ -115,7 +115,7 @@ namespace BTCPayServer.Client CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload), token); return await HandleResponse(response); } - + public virtual async Task GetLightningPayments(string storeId, string cryptoCode, bool? includePending = null, long? offsetIndex = null, CancellationToken token = default) { diff --git a/BTCPayServer.Client/BTCPayServerClient.StoreRatesConfiguration.cs b/BTCPayServer.Client/BTCPayServerClient.StoreRatesConfiguration.cs index 80c1ec7d5..1701ef189 100644 --- a/BTCPayServer.Client/BTCPayServerClient.StoreRatesConfiguration.cs +++ b/BTCPayServer.Client/BTCPayServerClient.StoreRatesConfiguration.cs @@ -54,7 +54,7 @@ namespace BTCPayServer.Client CancellationToken token = default) { using var response = await _httpClient.SendAsync( - CreateHttpRequest($"api/v1/stores/{storeId}/rates", + CreateHttpRequest($"api/v1/stores/{storeId}/rates", queryPayload: new Dictionary() { { "currencyPair", currencyPair } }, method: HttpMethod.Get), token); diff --git a/BTCPayServer.Client/Models/LightningAddressData.cs b/BTCPayServer.Client/Models/LightningAddressData.cs index 8970c3d3e..44483db29 100644 --- a/BTCPayServer.Client/Models/LightningAddressData.cs +++ b/BTCPayServer.Client/Models/LightningAddressData.cs @@ -6,5 +6,5 @@ public class LightningAddressData public string CurrencyCode { get; set; } public decimal? Min { get; set; } public decimal? Max { get; set; } - + } diff --git a/BTCPayServer.Client/Models/LightningInvoiceData.cs b/BTCPayServer.Client/Models/LightningInvoiceData.cs index 814113f38..e7daa3c98 100644 --- a/BTCPayServer.Client/Models/LightningInvoiceData.cs +++ b/BTCPayServer.Client/Models/LightningInvoiceData.cs @@ -16,7 +16,7 @@ namespace BTCPayServer.Client.Models [JsonProperty("BOLT11")] public string BOLT11 { get; set; } - + public string PaymentHash { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] @@ -24,7 +24,7 @@ namespace BTCPayServer.Client.Models [JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))] public DateTimeOffset? PaidAt { get; set; } - + [JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))] public DateTimeOffset ExpiresAt { get; set; } diff --git a/BTCPayServer.Client/Models/WithdrawRequestData.cs b/BTCPayServer.Client/Models/WithdrawRequestData.cs index 1a4b45d0b..a0529f7f1 100644 --- a/BTCPayServer.Client/Models/WithdrawRequestData.cs +++ b/BTCPayServer.Client/Models/WithdrawRequestData.cs @@ -1,8 +1,8 @@ +using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System; -using Newtonsoft.Json; using System.Net.Http.Headers; +using Newtonsoft.Json; namespace BTCPayServer.Client.Models; @@ -14,9 +14,9 @@ public class WithdrawRequestData public WithdrawRequestData() { - + } - + public WithdrawRequestData(string paymentMethod, TradeQuantity qty) { PaymentMethod = paymentMethod; diff --git a/BTCPayServer.Client/Models/WithdrawalResponseData.cs b/BTCPayServer.Client/Models/WithdrawalResponseData.cs index 16207572d..14bc8aa4c 100644 --- a/BTCPayServer.Client/Models/WithdrawalResponseData.cs +++ b/BTCPayServer.Client/Models/WithdrawalResponseData.cs @@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models; public class WithdrawalResponseData : WithdrawalBaseResponseData { - + [JsonConverter(typeof(StringEnumConverter))] public WithdrawalStatus Status { get; } diff --git a/BTCPayServer.Data/ApplicationDbContext.cs b/BTCPayServer.Data/ApplicationDbContext.cs index 7f9e9a4f9..be29a7942 100644 --- a/BTCPayServer.Data/ApplicationDbContext.cs +++ b/BTCPayServer.Data/ApplicationDbContext.cs @@ -124,14 +124,14 @@ namespace BTCPayServer.Data #pragma warning disable CS0612 // Type or member is obsolete WalletTransactionData.OnModelCreating(builder); #pragma warning restore CS0612 // Type or member is obsolete - WebhookDeliveryData.OnModelCreating(builder, Database); - LightningAddressData.OnModelCreating(builder, Database); - PayoutProcessorData.OnModelCreating(builder, Database); - WebhookData.OnModelCreating(builder, Database); - FormData.OnModelCreating(builder, Database); + WebhookDeliveryData.OnModelCreating(builder, Database); + LightningAddressData.OnModelCreating(builder, Database); + PayoutProcessorData.OnModelCreating(builder, Database); + WebhookData.OnModelCreating(builder, Database); + FormData.OnModelCreating(builder, Database); - if (Database.IsSqlite() && !_designTime) + if (Database.IsSqlite() && !_designTime) { // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations diff --git a/BTCPayServer.Data/Data/FormData.cs b/BTCPayServer.Data/Data/FormData.cs index 6598e5ce6..7519f10bf 100644 --- a/BTCPayServer.Data/Data/FormData.cs +++ b/BTCPayServer.Data/Data/FormData.cs @@ -13,14 +13,14 @@ public class FormData public StoreData Store { get; set; } public string Config { get; set; } public bool Public { get; set; } - + internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) { builder.Entity() .HasOne(o => o.Store) .WithMany(o => o.Forms).OnDelete(DeleteBehavior.Cascade); builder.Entity().HasIndex(o => o.StoreId); - + if (databaseFacade.IsNpgsql()) { builder.Entity() diff --git a/BTCPayServer.Data/Data/LightingAddressData.cs b/BTCPayServer.Data/Data/LightingAddressData.cs index 400d64be5..f52cc6785 100644 --- a/BTCPayServer.Data/Data/LightingAddressData.cs +++ b/BTCPayServer.Data/Data/LightingAddressData.cs @@ -39,6 +39,6 @@ public class LightningAddressDataBlob public string CurrencyCode { get; set; } public decimal? Min { get; set; } public decimal? Max { get; set; } - + public JObject InvoiceMetadata { get; set; } } diff --git a/BTCPayServer.Data/Data/NotificationData.cs b/BTCPayServer.Data/Data/NotificationData.cs index d5b79ed2c..847ccd56f 100644 --- a/BTCPayServer.Data/Data/NotificationData.cs +++ b/BTCPayServer.Data/Data/NotificationData.cs @@ -24,8 +24,8 @@ namespace BTCPayServer.Data public string Blob2 { get; set; } - internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) - { + internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade) + { builder.Entity() .HasOne(o => o.ApplicationUser) .WithMany(n => n.Notifications) diff --git a/BTCPayServer.Data/Migrations/20230125085242_AddForms.cs b/BTCPayServer.Data/Migrations/20230125085242_AddForms.cs index 4adb5558e..168d532dd 100644 --- a/BTCPayServer.Data/Migrations/20230125085242_AddForms.cs +++ b/BTCPayServer.Data/Migrations/20230125085242_AddForms.cs @@ -1,4 +1,4 @@ -using System; +using System; using BTCPayServer.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/BTCPayServer.Rating/Providers/CoinGeckoRateProvider.cs b/BTCPayServer.Rating/Providers/CoinGeckoRateProvider.cs index 56f249684..3a6656023 100644 --- a/BTCPayServer.Rating/Providers/CoinGeckoRateProvider.cs +++ b/BTCPayServer.Rating/Providers/CoinGeckoRateProvider.cs @@ -14,7 +14,7 @@ namespace BTCPayServer.Services.Rates public const string CoinGeckoName = "coingecko"; // https://api.coingecko.com/api/v3/exchanges/list internal static readonly Dictionary SupportedExchanges = JArray.Parse("[{\"id\":\"1bch\",\"name\":\"1BCH\"},{\"id\":\"3xcalibur\",\"name\":\"3xcalibur\"},{\"id\":\"aave\",\"name\":\"Aave\"},{\"id\":\"aax\",\"name\":\"AAX\"},{\"id\":\"aax_futures\",\"name\":\"AAX Futures\"},{\"id\":\"abcc\",\"name\":\"ABCC\"},{\"id\":\"acala_swap\",\"name\":\"Acala Swap\"},{\"id\":\"acdx\",\"name\":\"ACDX\"},{\"id\":\"ace\",\"name\":\"Ace\"},{\"id\":\"acsi_finance\",\"name\":\"Acsi Finance\"},{\"id\":\"agora_swap\",\"name\":\"Agora Swap\"},{\"id\":\"alexgo\",\"name\":\"ALEX\"},{\"id\":\"algebra_finance\",\"name\":\"Algebra finance\"},{\"id\":\"alpha_five\",\"name\":\"Alpha5\"},{\"id\":\"altcointrader\",\"name\":\"AltcoinTrader\"},{\"id\":\"alterdice\",\"name\":\"AlterDice\"},{\"id\":\"altmarkets\",\"name\":\"Altmarkets\"},{\"id\":\"amaterasu\",\"name\":\"Amaterasu Finance\"},{\"id\":\"apeswap_bsc\",\"name\":\"ApeSwap\"},{\"id\":\"apeswap_polygon\",\"name\":\"ApeSwap (Polygon)\"},{\"id\":\"apeswap_telos\",\"name\":\"Apeswap (Telos)\"},{\"id\":\"apex_pro\",\"name\":\"ApeX Pro\"},{\"id\":\"aprobit\",\"name\":\"Aprobit\"},{\"id\":\"arthswap\",\"name\":\"ArthSwap\"},{\"id\":\"astroport\",\"name\":\"Astroport (Classic)\"},{\"id\":\"auroraswap\",\"name\":\"AuroraSwap\"},{\"id\":\"autoshark_finance\",\"name\":\"AutoShark Finance\"},{\"id\":\"azbit\",\"name\":\"Azbit\"},{\"id\":\"b2bx\",\"name\":\"B2BX\"},{\"id\":\"babydogeswap\",\"name\":\"BabyDogeSwap\"},{\"id\":\"babyswap\",\"name\":\"BabySwap\"},{\"id\":\"baguette\",\"name\":\"Baguette\"},{\"id\":\"bakeryswap\",\"name\":\"Bakeryswap\"},{\"id\":\"bakkt\",\"name\":\"Bakkt\"},{\"id\":\"balanced_network\",\"name\":\"Balanced Network\"},{\"id\":\"balancer\",\"name\":\"Balancer (v2)\"},{\"id\":\"balancer_arbitrum\",\"name\":\"Balancer (Arbitrum)\"},{\"id\":\"balancer_polygon\",\"name\":\"Balancer (Polygon)\"},{\"id\":\"balancer_v1\",\"name\":\"Balancer (v1)\"},{\"id\":\"bancor\",\"name\":\"Bancor (V2)\"},{\"id\":\"bancor_v3\",\"name\":\"Bancor (V3)\"},{\"id\":\"baryon_network\",\"name\":\"Baryon Network\"},{\"id\":\"basefex\",\"name\":\"BaseFEX\"},{\"id\":\"beamswap\",\"name\":\"Beamswap\"},{\"id\":\"beaxy\",\"name\":\"Beaxy\"},{\"id\":\"beethovenx\",\"name\":\"Beethoven X\"},{\"id\":\"benswap_smart_bitcoin_cash\",\"name\":\"Benswap\"},{\"id\":\"bgogo\",\"name\":\"Bgogo\"},{\"id\":\"bibox\",\"name\":\"Bibox\"},{\"id\":\"bibox_futures\",\"name\":\"Bibox (Futures)\"},{\"id\":\"biconomy\",\"name\":\"Biconomy\"},{\"id\":\"bigone\",\"name\":\"BigONE\"},{\"id\":\"bigone_futures\",\"name\":\"BigONE Futures\"},{\"id\":\"bilaxy\",\"name\":\"Bilaxy\"},{\"id\":\"binance\",\"name\":\"Binance\"},{\"id\":\"binance_dex\",\"name\":\"Binance DEX\"},{\"id\":\"binance_dex_mini\",\"name\":\"Binance DEX (Mini)\"},{\"id\":\"binance_futures\",\"name\":\"Binance (Futures)\"},{\"id\":\"binance_us\",\"name\":\"Binance US\"},{\"id\":\"bingx\",\"name\":\"BingX\"},{\"id\":\"bingx_futures\",\"name\":\"BingX (Futures)\"},{\"id\":\"bione\",\"name\":\"BiONE\"},{\"id\":\"birake\",\"name\":\"Birake\"},{\"id\":\"bisq\",\"name\":\"Bisq\"},{\"id\":\"biswap\",\"name\":\"Biswap\"},{\"id\":\"bit2c\",\"name\":\"Bit2c\"},{\"id\":\"bitazza\",\"name\":\"Bitazza\"},{\"id\":\"bitbank\",\"name\":\"Bitbank\"},{\"id\":\"bitbay\",\"name\":\"Zonda\"},{\"id\":\"bitbegin\",\"name\":\"Bitbegin\"},{\"id\":\"bitbns\",\"name\":\"BitBNS\"},{\"id\":\"bitbox\",\"name\":\"BITFRONT\"},{\"id\":\"bitbuy\",\"name\":\"Bitbuy\"},{\"id\":\"bitci\",\"name\":\"Bitci\"},{\"id\":\"bitcoin_com\",\"name\":\"FMFW.io\"},{\"id\":\"bit_com\",\"name\":\"BIT\"},{\"id\":\"bit_com_futures\",\"name\":\"BIT (Futures)\"},{\"id\":\"bitexbook\",\"name\":\"BITEXBOOK\"},{\"id\":\"bitexen\",\"name\":\"Bitexen\"},{\"id\":\"bitexlive\",\"name\":\"Bitexlive\"},{\"id\":\"bitfex\",\"name\":\"Bitfex\"},{\"id\":\"bitfinex\",\"name\":\"Bitfinex\"},{\"id\":\"bitfinex_futures\",\"name\":\"Bitfinex (Futures)\"},{\"id\":\"bitflyer\",\"name\":\"bitFlyer\"},{\"id\":\"bitflyer_futures\",\"name\":\"Bitflyer (Futures)\"},{\"id\":\"bitforex\",\"name\":\"Bitforex\"},{\"id\":\"bitforex_futures\",\"name\":\"Bitforex (Futures)\"},{\"id\":\"bitget\",\"name\":\"Bitget\"},{\"id\":\"bitget_futures\",\"name\":\"Bitget Futures\"},{\"id\":\"bithash\",\"name\":\"BitHash\"},{\"id\":\"bithumb\",\"name\":\"Bithumb\"},{\"id\":\"bithumb_futures\",\"name\":\"Bithumb (Futures)\"},{\"id\":\"bithumb_global\",\"name\":\"BitGlobal\"},{\"id\":\"bitinka\",\"name\":\"Bitinka.com\"},{\"id\":\"bitkonan\",\"name\":\"BitKonan\"},{\"id\":\"bitkub\",\"name\":\"Bitkub\"},{\"id\":\"bitlo\",\"name\":\"Bitlo\"},{\"id\":\"bitmart\",\"name\":\"BitMart\"},{\"id\":\"bitmart_futures\",\"name\":\"Bitmart Futures\"},{\"id\":\"bitmax\",\"name\":\"AscendEX (BitMax)\"},{\"id\":\"bitmax_futures\",\"name\":\"AscendEX (BitMax) (Futures)\"},{\"id\":\"bitmex\",\"name\":\"BitMEX (Derivative)\"},{\"id\":\"bitmex_spot\",\"name\":\"BitMEX\"},{\"id\":\"bitoffer\",\"name\":\"Bitoffer\"},{\"id\":\"bitonbay\",\"name\":\"BitOnBay\"},{\"id\":\"bitopro\",\"name\":\"BitoPro\"},{\"id\":\"bitpanda\",\"name\":\"Bitpanda Pro\"},{\"id\":\"bitrue\",\"name\":\"Bitrue\"},{\"id\":\"bitrue_futures\",\"name\":\"Bitrue (Futures)\"},{\"id\":\"bitso\",\"name\":\"Bitso\"},{\"id\":\"bitstamp\",\"name\":\"Bitstamp\"},{\"id\":\"bitsten\",\"name\":\"Bitsten\"},{\"id\":\"bitstorage\",\"name\":\"BitStorage\"},{\"id\":\"bittrex\",\"name\":\"Bittrex\"},{\"id\":\"bitubu\",\"name\":\"Bitubu Exchange\"},{\"id\":\"bitvavo\",\"name\":\"Bitvavo\"},{\"id\":\"bitz_futures\",\"name\":\"BitZ (Futures)\"},{\"id\":\"bkex\",\"name\":\"BKEX\"},{\"id\":\"blockchain_com\",\"name\":\"Blockchain.com\"},{\"id\":\"bossswap\",\"name\":\"BossSwap\"},{\"id\":\"btc_alpha\",\"name\":\"BTC-Alpha\"},{\"id\":\"btcbox\",\"name\":\"BTCBOX\"},{\"id\":\"btcc\",\"name\":\"BTCC\"},{\"id\":\"btcc_futures\",\"name\":\"BTCC Futures\"},{\"id\":\"btcex\",\"name\":\"BTCEX\"},{\"id\":\"btcex_futures\",\"name\":\"BTCEX (Futures)\"},{\"id\":\"btcmarkets\",\"name\":\"BTCMarkets\"},{\"id\":\"btcmex\",\"name\":\"BTCMEX\"},{\"id\":\"btcsquare\",\"name\":\"BTCSquare\"},{\"id\":\"btc_trade_ua\",\"name\":\"BTC Trade UA\"},{\"id\":\"btcturk\",\"name\":\"BtcTurk PRO\"},{\"id\":\"btse\",\"name\":\"BTSE\"},{\"id\":\"btse_futures\",\"name\":\"BTSE (Futures)\"},{\"id\":\"bullish_com\",\"name\":\"Bullish\"},{\"id\":\"buyucoin\",\"name\":\"BuyUcoin\"},{\"id\":\"bw\",\"name\":\"BW.com\"},{\"id\":\"bybit\",\"name\":\"Bybit (Futures)\"},{\"id\":\"bybit_spot\",\"name\":\"Bybit\"},{\"id\":\"camelot\",\"name\":\"Camelot\"},{\"id\":\"canto_dex\",\"name\":\"Canto Dex\"},{\"id\":\"capricorn\",\"name\":\"Capricorn\"},{\"id\":\"catex\",\"name\":\"Catex\"},{\"id\":\"cbx\",\"name\":\"CBX\"},{\"id\":\"ccex\",\"name\":\"C-CEX\"},{\"id\":\"cex\",\"name\":\"CEX.IO\"},{\"id\":\"chainex\",\"name\":\"ChainEX\"},{\"id\":\"changelly\",\"name\":\"Changelly PRO\"},{\"id\":\"cherryswap\",\"name\":\"CherrySwap\"},{\"id\":\"chiliz\",\"name\":\"ChilizX\"},{\"id\":\"citex\",\"name\":\"CITEX\"},{\"id\":\"claimswap\",\"name\":\"Claimswap\"},{\"id\":\"clipper_ethereum\",\"name\":\"Clipper (Ethereum)\"},{\"id\":\"clipper_moonbeam\",\"name\":\"Clipper (Moonbeam)\"},{\"id\":\"clipper_optimism\",\"name\":\"Clipper (Optimism)\"},{\"id\":\"clipper_polygon\",\"name\":\"Clipper (Polygon)\"},{\"id\":\"cme_futures\",\"name\":\"CME Group\"},{\"id\":\"coinbene\",\"name\":\"CoinBene\"},{\"id\":\"coincheck\",\"name\":\"Coincheck\"},{\"id\":\"coindcx\",\"name\":\"CoinDCX\"},{\"id\":\"coindeal\",\"name\":\"Coindeal\"},{\"id\":\"coin_egg\",\"name\":\"CoinEgg\"},{\"id\":\"coinex\",\"name\":\"CoinEx\"},{\"id\":\"coinex_futures\",\"name\":\"CoinEx (Futures)\"},{\"id\":\"coinfalcon\",\"name\":\"Coinfalcon\"},{\"id\":\"coinfield\",\"name\":\"Coinfield\"},{\"id\":\"coinflex\",\"name\":\"CoinFLEX\"},{\"id\":\"coinflex_futures\",\"name\":\"CoinFLEX (Futures)\"},{\"id\":\"coingi\",\"name\":\"Coingi\"},{\"id\":\"coinjar\",\"name\":\"CoinJar Exchange\"},{\"id\":\"coinlist\",\"name\":\"Coinlist\"},{\"id\":\"coinmargin\",\"name\":\"CoinMargin\"},{\"id\":\"coin_metro\",\"name\":\"Coinmetro\"},{\"id\":\"coinone\",\"name\":\"Coinone\"},{\"id\":\"coinsbit\",\"name\":\"Coinsbit\"},{\"id\":\"coinspro\",\"name\":\"Coins.ph\"},{\"id\":\"coinstore\",\"name\":\"Coinstore\"},{\"id\":\"cointiger\",\"name\":\"CoinTiger\"},{\"id\":\"cointiger_futures\",\"name\":\"CoinTiger (Futures)\"},{\"id\":\"cointr\",\"name\":\"CoinTR Pro\"},{\"id\":\"coinzix\",\"name\":\"Coinzix\"},{\"id\":\"coinzoom\",\"name\":\"Coinzoom\"},{\"id\":\"comethswap\",\"name\":\"ComethSwap\"},{\"id\":\"concave\",\"name\":\"Concave\"},{\"id\":\"c_patex\",\"name\":\"C-Patex\"},{\"id\":\"crema_finance\",\"name\":\"Crema Finance\"},{\"id\":\"crescent\",\"name\":\"Crescent\"},{\"id\":\"crex24\",\"name\":\"CREX24\"},{\"id\":\"crodex\",\"name\":\"Crodex\"},{\"id\":\"cronaswap\",\"name\":\"Cronaswap\"},{\"id\":\"cronus_finance\",\"name\":\"Cronus Finance\"},{\"id\":\"crypto_com\",\"name\":\"Crypto.com Exchange\"},{\"id\":\"crypto_com_futures\",\"name\":\"Crypto.com Exchange (Futures)\"},{\"id\":\"cryptology\",\"name\":\"Cryptology\"},{\"id\":\"c_trade\",\"name\":\"C-Trade\"},{\"id\":\"currency\",\"name\":\"Currency.com\"},{\"id\":\"curve_arbitrum\",\"name\":\"Curve (Arbitrum)\"},{\"id\":\"curve_avalanche\",\"name\":\"Curve (Avalanche)\"},{\"id\":\"curve_ethereum\",\"name\":\"Curve (Ethereum)\"},{\"id\":\"curve_fantom\",\"name\":\"Curve (Fantom)\"},{\"id\":\"curve_optimism\",\"name\":\"Curve (Optimism)\"},{\"id\":\"curve_polygon\",\"name\":\"Curve (Polygon)\"},{\"id\":\"curve_xdai\",\"name\":\"Curve (Xdai)\"},{\"id\":\"dao_swap\",\"name\":\"DAO Swap\"},{\"id\":\"darkknight\",\"name\":\"Dark KnightSwap\"},{\"id\":\"dcoin\",\"name\":\"Dcoin\"},{\"id\":\"decoin\",\"name\":\"Decoin\"},{\"id\":\"deepcoin\",\"name\":\"Deepcoin\"},{\"id\":\"deepcoin_derivatives\",\"name\":\"Deepcoin (Derivatives)\"},{\"id\":\"defichain\",\"name\":\"DeFiChain DEX\"},{\"id\":\"defi_kingdoms\",\"name\":\"Defi Kingdoms\"},{\"id\":\"defi_kingdoms_crystalvale\",\"name\":\"Defi Kingdoms (Crystalvale)\"},{\"id\":\"defi_plaza\",\"name\":\"DefiPlaza\"},{\"id\":\"defi_swap\",\"name\":\"DeFi Swap\"},{\"id\":\"delta_futures\",\"name\":\"Delta Exchange (Futures)\"},{\"id\":\"delta_spot\",\"name\":\"Delta Exchange\"},{\"id\":\"dem_exchange\",\"name\":\"Demex\"},{\"id\":\"deribit\",\"name\":\"Deribit\"},{\"id\":\"deversifi\",\"name\":\"Rhino.fi\"},{\"id\":\"dexalot\",\"name\":\"Dexalot\"},{\"id\":\"dextrade\",\"name\":\"Dex-Trade\"},{\"id\":\"dfx\",\"name\":\"DFX\"},{\"id\":\"dfx_polygon\",\"name\":\"DFX (Polygon)\"},{\"id\":\"dfyn\",\"name\":\"Dfyn\"},{\"id\":\"diffusion\",\"name\":\"Diffusion Finance\"},{\"id\":\"digifinex\",\"name\":\"DigiFinex\"},{\"id\":\"dodo\",\"name\":\"DODO\"},{\"id\":\"dodo_arbitrum\",\"name\":\"Dodo (Arbitrum)\"},{\"id\":\"dodo_bsc\",\"name\":\"Dodo (BSC)\"},{\"id\":\"dodo_polygon\",\"name\":\"Dodo (Polygon)\"},{\"id\":\"dogeshrek\",\"name\":\"Dogeshrek\"},{\"id\":\"dogeswap\",\"name\":\"DogeSwap\"},{\"id\":\"dooar_bsc\",\"name\":\"DOOAR (BSC)\"},{\"id\":\"dooar_ethereum\",\"name\":\"DOOAR (Ethereum)\"},{\"id\":\"dove_wallet\",\"name\":\"BTX\"},{\"id\":\"drift_protocol\",\"name\":\"Drift Protocol\"},{\"id\":\"duckydefi\",\"name\":\"DuckyDeFi\"},{\"id\":\"duedex\",\"name\":\"DueDEX\"},{\"id\":\"dydx\",\"name\":\"dYdX\"},{\"id\":\"dydx_perpetual\",\"name\":\"dYdX Perpetual\"},{\"id\":\"dystopia\",\"name\":\"Dystopia\"},{\"id\":\"elk_finance_avax\",\"name\":\"Elk Finance (Avalanche)\"},{\"id\":\"elk_finance_bsc\",\"name\":\"Elk Finance (BSC)\"},{\"id\":\"elk_finance_ethereum\",\"name\":\"Elk Finance (Ethereum)\"},{\"id\":\"elk_finance_polygon\",\"name\":\"Elk Finance (Polygon)\"},{\"id\":\"elk_finance_telos\",\"name\":\"Elk Finance (Telos)\"},{\"id\":\"emirex\",\"name\":\"Emirex\"},{\"id\":\"empiredex\",\"name\":\"EmpireDEX (Cronos)\"},{\"id\":\"empiredex_bsc\",\"name\":\"EmpireDEX (BSC)\"},{\"id\":\"energiswap\",\"name\":\"Energiswap\"},{\"id\":\"equalizer\",\"name\":\"Equalizer\"},{\"id\":\"equos\",\"name\":\"EQONEX\"},{\"id\":\"equos_perpetual\",\"name\":\"EQONEX (Perpetual)\"},{\"id\":\"evmoswap\",\"name\":\"EvmoSwap\"},{\"id\":\"excalibur\",\"name\":\"Excalibur\"},{\"id\":\"exmarkets\",\"name\":\"ExMarkets\"},{\"id\":\"exmo\",\"name\":\"EXMO\"},{\"id\":\"fairyswap\",\"name\":\"Fairyswap\"},{\"id\":\"fameex\",\"name\":\"Fameex\"},{\"id\":\"fatbtc\",\"name\":\"FatBTC\"},{\"id\":\"finexbox\",\"name\":\"FinexBox\"},{\"id\":\"firebird_finance_polygon\",\"name\":\"Firebird Finance (Polygon)\"},{\"id\":\"flatqube\",\"name\":\"FlatQube\"},{\"id\":\"flybit\",\"name\":\"Flybit\"},{\"id\":\"four_swap\",\"name\":\"4swap\"},{\"id\":\"foxbit\",\"name\":\"Foxbit\"},{\"id\":\"fraxswap_ethereum\",\"name\":\"Fraxswap (Ethereum)\"},{\"id\":\"freiexchange\",\"name\":\"Freiexchange\"},{\"id\":\"fubt\",\"name\":\"FUBT\"},{\"id\":\"fuzz_finance\",\"name\":\"FuzzSwap\"},{\"id\":\"fx_swap\",\"name\":\"Fx Swap\"},{\"id\":\"gate\",\"name\":\"Gate.io\"},{\"id\":\"gate_futures\",\"name\":\"Gate.io (Futures)\"},{\"id\":\"gdac\",\"name\":\"GDAC\"},{\"id\":\"gdax\",\"name\":\"Coinbase Exchange\"},{\"id\":\"gemini\",\"name\":\"Gemini\"},{\"id\":\"glide_finance\",\"name\":\"Glide Finance\"},{\"id\":\"globe_exchange\",\"name\":\"Globe\"},{\"id\":\"globe_exchange_derivatives\",\"name\":\"Globe (Derivatives)\"},{\"id\":\"gmo_japan\",\"name\":\"GMO Japan\"},{\"id\":\"gmo_japan_futures\",\"name\":\"GMO Japan (Futures)\"},{\"id\":\"goku\",\"name\":\"GokuMarket\"},{\"id\":\"gopax\",\"name\":\"GoPax\"},{\"id\":\"graviex\",\"name\":\"Graviex\"},{\"id\":\"gravity_finance\",\"name\":\"Gravity Finance\"},{\"id\":\"greenhouse_dex\",\"name\":\"Greenhouse\"},{\"id\":\"hakuswap\",\"name\":\"HakuSwap\"},{\"id\":\"hanbitco\",\"name\":\"Hanbitco\"},{\"id\":\"hbtc_futures\",\"name\":\"BHEX (Futures)\"},{\"id\":\"hebeswap\",\"name\":\"Hebeswap\"},{\"id\":\"hermes_protocol\",\"name\":\"Hermes Protocol\"},{\"id\":\"hitbtc\",\"name\":\"HitBTC\"},{\"id\":\"hitbtc_derivatives\",\"name\":\"HitBTC (Derivatives)\"},{\"id\":\"honeyswap\",\"name\":\"Honeyswap\"},{\"id\":\"honeyswap_polygon\",\"name\":\"Honeyswap (Polygon)\"},{\"id\":\"hoo\",\"name\":\"Hoo.com\"},{\"id\":\"hopex\",\"name\":\"Hopex\"},{\"id\":\"hotbit\",\"name\":\"Hotbit\"},{\"id\":\"huckleberry\",\"name\":\"Huckleberry\"},{\"id\":\"huobi\",\"name\":\"Huobi\"},{\"id\":\"huobi_dm\",\"name\":\"Huobi Futures\"},{\"id\":\"huobi_japan\",\"name\":\"Huobi Japan\"},{\"id\":\"huobi_korea\",\"name\":\"Huobi Korea\"},{\"id\":\"hydra\",\"name\":\"Hydra DEX\"},{\"id\":\"idex\",\"name\":\"Idex\"},{\"id\":\"impossible_finance\",\"name\":\"Impossible Finance\"},{\"id\":\"impossible_finance_v3\",\"name\":\"Impossible Finance (v3)\"},{\"id\":\"independent_reserve\",\"name\":\"Independent Reserve\"},{\"id\":\"indodax\",\"name\":\"Indodax\"},{\"id\":\"injective\",\"name\":\"Helix\"},{\"id\":\"injective_futures\",\"name\":\"Helix (Futures)\"},{\"id\":\"integral_size\",\"name\":\"Integral SIZE\"},{\"id\":\"itbit\",\"name\":\"itBit\"},{\"id\":\"iziswap\",\"name\":\"Iziswap\"},{\"id\":\"jetswap\",\"name\":\"JetSwap\"},{\"id\":\"jex_futures\",\"name\":\"Binance JEX (Futures)\"},{\"id\":\"jswap\",\"name\":\"Jswap\"},{\"id\":\"julswap\",\"name\":\"Julswap\"},{\"id\":\"junoswap\",\"name\":\"Junoswap\"},{\"id\":\"jupiter\",\"name\":\"Jupiter\"},{\"id\":\"kaidex\",\"name\":\"Kaidex\"},{\"id\":\"kaidex_v3\",\"name\":\"Kaidex V3\"},{\"id\":\"kanga\",\"name\":\"Kanga\"},{\"id\":\"karura_swap\",\"name\":\"Karura Swap\"},{\"id\":\"katana\",\"name\":\"Katana\"},{\"id\":\"kava\",\"name\":\"Kava Swap\"},{\"id\":\"kdswap\",\"name\":\"KDSwap\"},{\"id\":\"khaos_exchange\",\"name\":\"Khaos Exchange\"},{\"id\":\"kibbleswap\",\"name\":\"KibbleSwap\"},{\"id\":\"kickex\",\"name\":\"KickEX\"},{\"id\":\"klayswap\",\"name\":\"KLAYSwap\"},{\"id\":\"klever_exchange\",\"name\":\"Klever Exchange\"},{\"id\":\"klex\",\"name\":\"KLEX\"},{\"id\":\"knightswap\",\"name\":\"KnightSwap\"},{\"id\":\"koinbazar\",\"name\":\"Koinbazar\"},{\"id\":\"korbit\",\"name\":\"Korbit\"},{\"id\":\"kraken\",\"name\":\"Kraken\"},{\"id\":\"kraken_futures\",\"name\":\"Kraken (Futures)\"},{\"id\":\"kucoin\",\"name\":\"KuCoin\"},{\"id\":\"kujira\",\"name\":\"Kujira Fin\"},{\"id\":\"kumex\",\"name\":\"KuCoin Futures\"},{\"id\":\"kuna\",\"name\":\"Kuna Exchange\"},{\"id\":\"kuswap\",\"name\":\"Kuswap\"},{\"id\":\"kyberswap_classic_avalanche\",\"name\":\"KyberSwap Classic (Avalanche)\"},{\"id\":\"kyberswap_classic_bsc\",\"name\":\"KyberSwap Classic (BSC)\"},{\"id\":\"kyberswap_classic_bttc\",\"name\":\"Kyberswap Classic (Bittorent)\"},{\"id\":\"kyberswap_classic_ethereum\",\"name\":\"KyberSwap Classic (Ethereum)\"},{\"id\":\"kyberswap_classic_fantom\",\"name\":\"KyberSwap Classic (Fantom)\"},{\"id\":\"kyberswap_classic_polygon\",\"name\":\"KyberSwap Classic (Polygon)\"},{\"id\":\"kyberswap_elastic\",\"name\":\"KyberSwap Elastic (Ethereum)\"},{\"id\":\"kyberswap_elastic_arbitrum\",\"name\":\"Kyberswap Elastic (Arbitrum)\"},{\"id\":\"kyberswap_elastic_avalanche\",\"name\":\"Kyberswap Elastic (Avalanche)\"},{\"id\":\"kyberswap_elastic_bsc\",\"name\":\"Kyberswap Elastic (BSC)\"},{\"id\":\"kyberswap_elastic_fantom\",\"name\":\"Kyberswap Elastic (Fantom)\"},{\"id\":\"kyberswap_elastic_optimism\",\"name\":\"Kyberswap Elastic (Optimism)\"},{\"id\":\"kyberswap_elastic_polygon\",\"name\":\"Kyberswap Elastic (Polygon)\"},{\"id\":\"latoken\",\"name\":\"LATOKEN\"},{\"id\":\"lbank\",\"name\":\"LBank\"},{\"id\":\"lcx\",\"name\":\"LCX Exchange\"},{\"id\":\"leonicornswap\",\"name\":\"LeonicornSwap\"},{\"id\":\"levinswap_xdai\",\"name\":\"Levinswap (xDai)\"},{\"id\":\"lfgswap\",\"name\":\"LFGswap\"},{\"id\":\"lif3\",\"name\":\"LIF3 (Tombchain)\"},{\"id\":\"lif3-bsc\",\"name\":\"LIF3 (BSC)\"},{\"id\":\"lif3-polygon\",\"name\":\"LIF3 (Polygon)\"},{\"id\":\"liquid_derivatives\",\"name\":\"Liquid Perpetuals\"},{\"id\":\"localtrade\",\"name\":\"LocalTrade\"},{\"id\":\"loop\",\"name\":\"Loop Markets\"},{\"id\":\"loopring\",\"name\":\"Loopring\"},{\"id\":\"loopring_amm\",\"name\":\"Loopring AMM\"},{\"id\":\"luaswap\",\"name\":\"Luaswap\"},{\"id\":\"luno\",\"name\":\"Luno\"},{\"id\":\"lydia_finance\",\"name\":\"Lydia Finance\"},{\"id\":\"lykke\",\"name\":\"Lykke\"},{\"id\":\"maiar\",\"name\":\"xExchange\"},{\"id\":\"makiswap\",\"name\":\"Makiswap\"},{\"id\":\"mango_markets_derivatives\",\"name\":\"Mango Markets (Derivatives)\"},{\"id\":\"mango_markets_spot\",\"name\":\"Mango Markets\"},{\"id\":\"mars_ecosystem\",\"name\":\"Mars Ecosystem\"},{\"id\":\"max_maicoin\",\"name\":\"Max Maicoin\"},{\"id\":\"mcdex\",\"name\":\"MCDEX (Arbitrum)\"},{\"id\":\"mcdex_bsc\",\"name\":\"MCDEX (BSC)\"},{\"id\":\"mdex\",\"name\":\"Mdex\"},{\"id\":\"mdex_bsc\",\"name\":\"Mdex BSC\"},{\"id\":\"mercado_bitcoin\",\"name\":\"Mercado Bitcoin\"},{\"id\":\"mercatox\",\"name\":\"Mercatox\"},{\"id\":\"miaswap\",\"name\":\"MiaSwap\"},{\"id\":\"milkyswap-milkada\",\"name\":\"MilkySwap\"},{\"id\":\"mimo\",\"name\":\"Mimo\"},{\"id\":\"minswap\",\"name\":\"Minswap\"},{\"id\":\"mistswap_smart_bitcoin_cash\",\"name\":\"Mistswap\"},{\"id\":\"mm_finance\",\"name\":\"MMFinance (Cronos)\"},{\"id\":\"mmfinance_polygon\",\"name\":\"MMFinance (Polygon)\"},{\"id\":\"mojitoswap\",\"name\":\"MojitoSwap\"},{\"id\":\"morpheus_swap\",\"name\":\"Morpheus Swap\"},{\"id\":\"muesliswap\",\"name\":\"Muesliswap\"},{\"id\":\"muesliswap-milkada\",\"name\":\"Muesliswap (Milkada)\"},{\"id\":\"mxc\",\"name\":\"MEXC Global\"},{\"id\":\"mxc_futures\",\"name\":\"MEXC Global (Futures)\"},{\"id\":\"mycoinstory\",\"name\":\"MCS\"},{\"id\":\"nachoswap\",\"name\":\"NachoSwap\"},{\"id\":\"namebase\",\"name\":\"Namebase\"},{\"id\":\"nami_exchange\",\"name\":\"Nami.Exchange\"},{\"id\":\"narkasa\",\"name\":\"Narkasa\"},{\"id\":\"nash\",\"name\":\"Nash\"},{\"id\":\"nearpad\",\"name\":\"NearPAD\"},{\"id\":\"negociecoins\",\"name\":\"Negociecoins\"},{\"id\":\"netswap\",\"name\":\"Netswap\"},{\"id\":\"newdex\",\"name\":\"Newdex\"},{\"id\":\"nexus_mutual\",\"name\":\"Nexus Mutual\"},{\"id\":\"nice_hash\",\"name\":\"NiceHash\"},{\"id\":\"nominex\",\"name\":\"Nominex\"},{\"id\":\"nomiswap\",\"name\":\"Nomiswap\"},{\"id\":\"nomiswap_stable\",\"name\":\"Nomiswap (Stable)\"},{\"id\":\"novadax\",\"name\":\"NovaDAX\"},{\"id\":\"oasis_trade\",\"name\":\"OasisDEX\"},{\"id\":\"occamx\",\"name\":\"OccamX\"},{\"id\":\"oceanex\",\"name\":\"Oceanex\"},{\"id\":\"okcoin\",\"name\":\"Okcoin\"},{\"id\":\"okex\",\"name\":\"OKX\"},{\"id\":\"okex_swap\",\"name\":\"OKX (Futures)\"},{\"id\":\"omgfin\",\"name\":\"Omgfin\"},{\"id\":\"omnidex\",\"name\":\"OmniDex\"},{\"id\":\"one_inch_liquidity_protocol\",\"name\":\"1inch Liquidity Protocol\"},{\"id\":\"one_inch_liquidity_protocol_bsc\",\"name\":\"1inch Liquidity Protocol (BSC)\"},{\"id\":\"oolongswap\",\"name\":\"Oolongswap\"},{\"id\":\"openleverage\",\"name\":\"OpenLeverage\"},{\"id\":\"openocean_finance\",\"name\":\"OpenOcean\"},{\"id\":\"openswap\",\"name\":\"OpenSwap\"},{\"id\":\"oraidex\",\"name\":\"OraiDEX\"},{\"id\":\"orca\",\"name\":\"Orca\"},{\"id\":\"orderbook\",\"name\":\"Orderbook.io\"},{\"id\":\"orderly_network\",\"name\":\"Orderly Network\"},{\"id\":\"osmosis\",\"name\":\"Osmosis\"},{\"id\":\"ovex\",\"name\":\"Ovex\"},{\"id\":\"p2pb2b\",\"name\":\"P2B\"},{\"id\":\"paintswap\",\"name\":\"Paintswap\"},{\"id\":\"pancakeswap_ethereum\",\"name\":\"PancakeSwap (Ethereum)\"},{\"id\":\"pancakeswap_new\",\"name\":\"PancakeSwap (v2)\"},{\"id\":\"pangolin\",\"name\":\"Pangolin\"},{\"id\":\"pangolin-flare\",\"name\":\"Pangolin (Flare)\"},{\"id\":\"pangolin-songbird\",\"name\":\"Pangolin (Songbird)\"},{\"id\":\"paribu\",\"name\":\"Paribu\"},{\"id\":\"paritex\",\"name\":\"Paritex\"},{\"id\":\"paymium\",\"name\":\"Paymium\"},{\"id\":\"pegasys\",\"name\":\"Pegasys\"},{\"id\":\"perpetual_protocol\",\"name\":\"Perpetual Protocol\"},{\"id\":\"phemex\",\"name\":\"Phemex\"},{\"id\":\"phemex_futures\",\"name\":\"Phemex (Futures)\"},{\"id\":\"photonswap\",\"name\":\"PhotonSwap (Cronos)\"},{\"id\":\"photonswap_kava\",\"name\":\"PhotonSwap (Kava)\"},{\"id\":\"pinkswap\",\"name\":\"PinkSwap\"},{\"id\":\"pionex\",\"name\":\"Pionex\"},{\"id\":\"planet_finance\",\"name\":\"Planet Finance\"},{\"id\":\"platypus_finance\",\"name\":\"Platypus Finance\"},{\"id\":\"polkaex_shiden\",\"name\":\"PolkaEx (Shiden)\"},{\"id\":\"polkaswap\",\"name\":\"Polkaswap\"},{\"id\":\"poloniex\",\"name\":\"Poloniex\"},{\"id\":\"poloniex_futures\",\"name\":\"Poloniex Futures\"},{\"id\":\"polycat_finance\",\"name\":\"Polycat Finance\"},{\"id\":\"polydex\",\"name\":\"PolyDEX\"},{\"id\":\"polyzap\",\"name\":\"PolyZap\"},{\"id\":\"pomswap\",\"name\":\"POMSwap\"},{\"id\":\"powertrade\",\"name\":\"Powertrade\"},{\"id\":\"powswap\",\"name\":\"Powswap\"},{\"id\":\"prime_xbt\",\"name\":\"Prime XBT\"},{\"id\":\"prism\",\"name\":\"Prism Protocol\"},{\"id\":\"probit\",\"name\":\"ProBit Global\"},{\"id\":\"probit_kr\",\"name\":\"Probit (Korea)\"},{\"id\":\"protofi\",\"name\":\"ProtoFi\"},{\"id\":\"puddingswap\",\"name\":\"PuddingSwap\"},{\"id\":\"purcow\",\"name\":\"Purcow\"},{\"id\":\"qtrade\",\"name\":\"qTrade\"},{\"id\":\"quickswap\",\"name\":\"Quickswap\"},{\"id\":\"quickswap_dogechain\",\"name\":\"Quickswap (Dogechain)\"},{\"id\":\"quickswap_v3\",\"name\":\"Quickswap (v3)\"},{\"id\":\"quipuswap\",\"name\":\"Quipuswap\"},{\"id\":\"quoine\",\"name\":\"Liquid\"},{\"id\":\"radioshack_avalanche\",\"name\":\"RadioShack (Avalanche)\"},{\"id\":\"radioshack_bsc\",\"name\":\"RadioShack (BSC)\"},{\"id\":\"radioshack_ethereum\",\"name\":\"RadioShack (Ethereum)\"},{\"id\":\"radioshack_polygon_pos\",\"name\":\"RadioShack (Polygon)\"},{\"id\":\"raydium2\",\"name\":\"Raydium\"},{\"id\":\"rcpswap\",\"name\":\"RCP Swap\"},{\"id\":\"ref_finance\",\"name\":\"Ref Finance\"},{\"id\":\"resfinex\",\"name\":\"Resfinex\"},{\"id\":\"ruby_exchange\",\"name\":\"Ruby Exchange\"},{\"id\":\"saber\",\"name\":\"Saber\"},{\"id\":\"safe_trade\",\"name\":\"SafeTrade\"},{\"id\":\"sakeswap\",\"name\":\"SakeSwap\"},{\"id\":\"saros\",\"name\":\"Saros Finance\"},{\"id\":\"saucerswap_dex\",\"name\":\"Saucerswap\"},{\"id\":\"secondbtc\",\"name\":\"SecondBTC\"},{\"id\":\"secretswap\",\"name\":\"SecretSwap\"},{\"id\":\"serum_dex\",\"name\":\"Serum DEX\"},{\"id\":\"sharkswap\",\"name\":\"SharkSwap\"},{\"id\":\"shibaswap\",\"name\":\"Shibaswap\"},{\"id\":\"shibswap\",\"name\":\"ShibSwap\"},{\"id\":\"siennaswap\",\"name\":\"Siennaswap\"},{\"id\":\"sifchain\",\"name\":\"Sifchain\"},{\"id\":\"sinegy\",\"name\":\"SINEGY\"},{\"id\":\"solarbeam\",\"name\":\"Solarbeam\"},{\"id\":\"solarflare\",\"name\":\"Solarflare\"},{\"id\":\"solidly\",\"name\":\"Solidly\"},{\"id\":\"solidlydex\",\"name\":\"Solidly (Ethereum)\"},{\"id\":\"soulswap\",\"name\":\"Soulswap\"},{\"id\":\"south_xchange\",\"name\":\"SouthXchange\"},{\"id\":\"sovryn\",\"name\":\"Sovryn DEX\"},{\"id\":\"spartan_protocol\",\"name\":\"Spartan Protocol\"},{\"id\":\"sphynx_brise\",\"name\":\"Sphynx (Brise)\"},{\"id\":\"sphynx_swap\",\"name\":\"Sphynx Swap (BSC)\"},{\"id\":\"spice_trade_avalanche\",\"name\":\"Spice Trade (Avalanche)\"},{\"id\":\"spicyswap\",\"name\":\"Spicyswap\"},{\"id\":\"spiritswap\",\"name\":\"SpiritSwap\"},{\"id\":\"spiritswap_v2\",\"name\":\"SpiritSwap (V2)\"},{\"id\":\"spookyswap\",\"name\":\"SpookySwap\"},{\"id\":\"stake_cube\",\"name\":\"StakeCube Exchange\"},{\"id\":\"stellar_term\",\"name\":\"StellarTerm\"},{\"id\":\"stellaswap\",\"name\":\"StellaSwap\"},{\"id\":\"step-exchange\",\"name\":\"Step Exchange\"},{\"id\":\"step_finance\",\"name\":\"Step Finance\"},{\"id\":\"stocks_exchange\",\"name\":\"STEX\"},{\"id\":\"stormgain\",\"name\":\"Stormgain\"},{\"id\":\"stormgain_futures\",\"name\":\"Stormgain Futures\"},{\"id\":\"sundaeswap\",\"name\":\"Sundaeswap\"},{\"id\":\"sunswap_v1\",\"name\":\"SUN.io\"},{\"id\":\"surfswap\",\"name\":\"Surfswap\"},{\"id\":\"sushiswap\",\"name\":\"Sushiswap\"},{\"id\":\"sushiswap_arbitrum\",\"name\":\"Sushiswap (Arbitrum One)\"},{\"id\":\"sushiswap_arbitrum_nova\",\"name\":\"Sushiswap (Arbitrum Nova)\"},{\"id\":\"sushiswap_avalanche\",\"name\":\"Sushiswap (Avalanche)\"},{\"id\":\"sushiswap_bsc\",\"name\":\"Sushiswap (BSC)\"},{\"id\":\"sushiswap_celo\",\"name\":\"Sushiswap Celo\"},{\"id\":\"sushiswap_fantom\",\"name\":\"Sushiswap (Fantom)\"},{\"id\":\"sushiswap_harmony\",\"name\":\"Sushiswap (Harmony)\"},{\"id\":\"sushiswap_polygon_pos\",\"name\":\"Sushiswap (Polygon POS)\"},{\"id\":\"sushiswap_xdai\",\"name\":\"Sushiswap (xDai)\"},{\"id\":\"swapfish\",\"name\":\"SwapFish\"},{\"id\":\"swappi\",\"name\":\"Swappi\"},{\"id\":\"swapr_arbitrum\",\"name\":\"Swapr (Arbitrum)\"},{\"id\":\"swapr_ethereum\",\"name\":\"Swapr (Ethereum)\"},{\"id\":\"swapr_xdai\",\"name\":\"Swapr (Xdai)\"},{\"id\":\"swop_fi\",\"name\":\"Swop.Fi\"},{\"id\":\"swych\",\"name\":\"SWYCH\"},{\"id\":\"synfutures\",\"name\":\"SynFutures\"},{\"id\":\"synthetix\",\"name\":\"Kwenta\"},{\"id\":\"tangoswap\",\"name\":\"TangoSwap\"},{\"id\":\"tdax\",\"name\":\"Satang Pro\"},{\"id\":\"tealswap\",\"name\":\"Tealswap\"},{\"id\":\"templedao\",\"name\":\"TempleDAO\"},{\"id\":\"tenderswap\",\"name\":\"Tenderswap\"},{\"id\":\"terraswap\",\"name\":\"Terraswap Classic\"},{\"id\":\"tethys\",\"name\":\"Tethys Finance\"},{\"id\":\"tetuswap\",\"name\":\"Tetuswap\"},{\"id\":\"tfm\",\"name\":\"Terraformer\"},{\"id\":\"therocktrading\",\"name\":\"TheRockTrading\"},{\"id\":\"thorswap\",\"name\":\"THORSwap\"},{\"id\":\"thorus\",\"name\":\"Thorus\"},{\"id\":\"thorwallet\",\"name\":\"THORWallet DEX\"},{\"id\":\"tidex\",\"name\":\"Tidex\"},{\"id\":\"tinyman\",\"name\":\"Tinyman\"},{\"id\":\"tokenize\",\"name\":\"Tokenize\"},{\"id\":\"tokenlon\",\"name\":\"Tokenlon\"},{\"id\":\"tokenomy\",\"name\":\"Tokenomy\"},{\"id\":\"token_sets\",\"name\":\"TokenSets\"},{\"id\":\"toko_crypto\",\"name\":\"TokoCrypto\"},{\"id\":\"tokok\",\"name\":\"TOKOK\"},{\"id\":\"tokpie\",\"name\":\"Tokpie\"},{\"id\":\"tomb_swap_fantom\",\"name\":\"Tomb Swap (Fantom)\"},{\"id\":\"trade_ogre\",\"name\":\"TradeOgre\"},{\"id\":\"traderjoe\",\"name\":\"Trader Joe\"},{\"id\":\"traderjoe-v2-arbitrum\",\"name\":\"Trader Joe v2 (Arbitrum)\"},{\"id\":\"traderjoe-v2-avalanche\",\"name\":\"Trader Joe v2\"},{\"id\":\"tranquil_finance\",\"name\":\"Tranquil Finance\"},{\"id\":\"trisolaris\",\"name\":\"Trisolaris\"},{\"id\":\"tropical_finance\",\"name\":\"Tropical Finance\"},{\"id\":\"txbit\",\"name\":\"Txbit\"},{\"id\":\"ubeswap\",\"name\":\"Ubeswap\"},{\"id\":\"unicly\",\"name\":\"Unicly\"},{\"id\":\"uniswap_v2\",\"name\":\"Uniswap (v2)\"},{\"id\":\"uniswap_v3\",\"name\":\"Uniswap (v3)\"},{\"id\":\"uniswap_v3_arbitrum\",\"name\":\"Uniswap (Arbitrum One)\"},{\"id\":\"uniswap_v3_optimism\",\"name\":\"Uniswap (Optimism)\"},{\"id\":\"uniswap_v3_polygon_pos\",\"name\":\"Uniswap (Polygon)\"},{\"id\":\"uniwswap\",\"name\":\"UniWswap\"},{\"id\":\"unnamed\",\"name\":\"Unnamed\"},{\"id\":\"upbit\",\"name\":\"Upbit\"},{\"id\":\"upbit_indonesia\",\"name\":\"Upbit Indonesia \"},{\"id\":\"value_liquid_bsc\",\"name\":\"vSwap BSC\"},{\"id\":\"velic\",\"name\":\"Velic\"},{\"id\":\"velodrome\",\"name\":\"Velodrome Finance\"},{\"id\":\"verse\",\"name\":\"Verse\"},{\"id\":\"vindax\",\"name\":\"Vindax\"},{\"id\":\"viperswap\",\"name\":\"ViperSwap\"},{\"id\":\"vitex\",\"name\":\"ViteX\"},{\"id\":\"voltage_finance\",\"name\":\"Voltage Finance\"},{\"id\":\"voltswap_meter\",\"name\":\"Voltswap (Meter)\"},{\"id\":\"voltswap_theta\",\"name\":\"Voltswap (Theta)\"},{\"id\":\"vvs\",\"name\":\"VVS Finance\"},{\"id\":\"wagyuswap\",\"name\":\"WagyuSwap\"},{\"id\":\"wannaswap\",\"name\":\"Wannaswap\"},{\"id\":\"wanswap\",\"name\":\"WanSwap\"},{\"id\":\"waultswap_polygon\",\"name\":\"WaultSwap Polygon\"},{\"id\":\"wavelength\",\"name\":\"Wavelength\"},{\"id\":\"waves\",\"name\":\"Wx.network\"},{\"id\":\"wazirx\",\"name\":\"WazirX\"},{\"id\":\"wemix_fi\",\"name\":\"WEMIX.Fi\"},{\"id\":\"whitebit\",\"name\":\"WhiteBIT\"},{\"id\":\"wigoswap\",\"name\":\"Wigoswap\"},{\"id\":\"wombat\",\"name\":\"Wombat\"},{\"id\":\"woofi\",\"name\":\"WOOFi\"},{\"id\":\"woo_network_futures\",\"name\":\"WOO Network (Futures)\"},{\"id\":\"wootrade\",\"name\":\"WOO Network\"},{\"id\":\"xave\",\"name\":\"Xave Finance\"},{\"id\":\"xcad\",\"name\":\"XCAD DEX\"},{\"id\":\"xswap\",\"name\":\"XSwap\"},{\"id\":\"xt\",\"name\":\"XT.COM\"},{\"id\":\"xt_derivatives\",\"name\":\"XT.COM (Derivatives)\"},{\"id\":\"yobit\",\"name\":\"YoBit\"},{\"id\":\"yodeswap\",\"name\":\"Yodeswap\"},{\"id\":\"yokaiswap\",\"name\":\"Yokaiswap\"},{\"id\":\"yoshi_exchange_bsc\",\"name\":\"Yoshi.exchange (BSC)\"},{\"id\":\"yoshi_exchange_ftm\",\"name\":\"Yoshi.exchange (Fantom)\"},{\"id\":\"yunex\",\"name\":\"Yunex.io\"},{\"id\":\"zaif\",\"name\":\"Zaif\"},{\"id\":\"zappy\",\"name\":\"Zappy\"},{\"id\":\"zbg\",\"name\":\"ZBG\"},{\"id\":\"zbg_futures\",\"name\":\"ZBG Futures\"},{\"id\":\"zbx\",\"name\":\"ZBX\"},{\"id\":\"zebitex\",\"name\":\"Zebitex\"},{\"id\":\"zebpay\",\"name\":\"ZebPay\"},{\"id\":\"zenlink_astar\",\"name\":\"Zenlink (Astar)\"},{\"id\":\"zenlink_moonbeam\",\"name\":\"Zenlink (Moonbeam)\"},{\"id\":\"zenlink_moonriver\",\"name\":\"Zenlink (Moonriver)\"},{\"id\":\"zero_ex\",\"name\":\"0x Protocol\"},{\"id\":\"zigzag\",\"name\":\"ZigZag (zkSync v1)\"},{\"id\":\"zigzag_arbitrum\",\"name\":\"ZigZag (Arbitrum)\"},{\"id\":\"zilswap\",\"name\":\"ZilSwap\"},{\"id\":\"zipmex\",\"name\":\"Zipmex\"},{\"id\":\"zipswap\",\"name\":\"ZipSwap\"},{\"id\":\"zircon\",\"name\":\"Zircon\"}]") - .ToDictionary(c => + .ToDictionary(c => c["id"].Value(), c => new RateSourceInfo(c["id"].ToString().ToLowerInvariant(), c["name"].ToString(), $"https://api.coingecko.com/api/v3/exchanges/{c["id"]}/tickers")); @@ -47,7 +47,7 @@ namespace BTCPayServer.Services.Rates UnderlyingExchange = null; Client = httpClientFactory.CreateClient(); Client.BaseAddress = new Uri("https://api.coingecko.com/api/v3/"); - Client.DefaultRequestHeaders.Add("Accept", "application/json"); + Client.DefaultRequestHeaders.Add("Accept", "application/json"); } public virtual Task GetRatesAsync(CancellationToken cancellationToken) diff --git a/BTCPayServer.Rating/Providers/NullRateProvider.cs b/BTCPayServer.Rating/Providers/NullRateProvider.cs index 3aa7cdf41..3cbd1c1f1 100644 --- a/BTCPayServer.Rating/Providers/NullRateProvider.cs +++ b/BTCPayServer.Rating/Providers/NullRateProvider.cs @@ -20,7 +20,7 @@ namespace BTCPayServer.Services.Rates } } - public RateSourceInfo RateSourceInfo => new RateSourceInfo("NULL","NULL", "https://NULL.NULL"); + public RateSourceInfo RateSourceInfo => new RateSourceInfo("NULL", "NULL", "https://NULL.NULL"); public Task GetRatesAsync(CancellationToken cancellationToken) { diff --git a/BTCPayServer.Rating/Services/RateProviderFactory.cs b/BTCPayServer.Rating/Services/RateProviderFactory.cs index 2f019d1e1..b5b233f63 100644 --- a/BTCPayServer.Rating/Services/RateProviderFactory.cs +++ b/BTCPayServer.Rating/Services/RateProviderFactory.cs @@ -89,7 +89,7 @@ namespace BTCPayServer.Services.Rates AvailableRateProviders.Add(new(rsi.Id, rsi.DisplayName, rsi.Url, RateSource.Coingecko)); } } - AvailableRateProviders.Sort((a,b) => StringComparer.Ordinal.Compare(a.DisplayName, b.DisplayName)); + AvailableRateProviders.Sort((a, b) => StringComparer.Ordinal.Compare(a.DisplayName, b.DisplayName)); } public List AvailableRateProviders { get; } = new List(); diff --git a/BTCPayServer.Tests/Checkoutv2Tests.cs b/BTCPayServer.Tests/Checkoutv2Tests.cs index 4836c1123..126f33d2e 100644 --- a/BTCPayServer.Tests/Checkoutv2Tests.cs +++ b/BTCPayServer.Tests/Checkoutv2Tests.cs @@ -44,7 +44,7 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.Id("StoreWebsite")).SendKeys(storeUrl); s.Driver.FindElement(By.Id("Save")).Click(); Assert.Contains("Store successfully updated", s.FindAlertMessage().Text); - + // Enable LNURL, which we will need for (non-)presence checks throughout this test s.GoToHome(); s.GoToLightningSettings(); @@ -79,7 +79,7 @@ namespace BTCPayServer.Tests Assert.Equal(address, copyAddress); Assert.Equal($"bitcoin:{address.ToUpperInvariant()}", qrValue); s.Driver.ElementDoesNotExist(By.Id("Lightning_BTC")); - + // Details should show exchange rate s.Driver.ToggleCollapse("PaymentDetails"); s.Driver.ElementDoesNotExist(By.Id("PaymentDetails-TotalPrice")); @@ -87,7 +87,7 @@ namespace BTCPayServer.Tests s.Driver.ElementDoesNotExist(By.Id("PaymentDetails-AmountDue")); Assert.Contains("$", s.Driver.FindElement(By.Id("PaymentDetails-ExchangeRate")).Text); Assert.Contains("sat/byte", s.Driver.FindElement(By.Id("PaymentDetails-RecommendedFee")).Text); - + // Switch to LNURL s.Driver.FindElement(By.CssSelector(".payment-method:nth-child(2)")).Click(); TestUtils.Eventually(() => @@ -125,7 +125,7 @@ namespace BTCPayServer.Tests s.GoToInvoiceCheckout(invoiceId); s.Driver.WaitUntilAvailable(By.Id("Checkout-v2")); Assert.Contains("sats", s.Driver.FindElement(By.Id("AmountDue")).Text); - + // Details should not show exchange rate s.Driver.ToggleCollapse("PaymentDetails"); s.Driver.ElementDoesNotExist(By.Id("PaymentDetails-ExchangeRate")); @@ -206,7 +206,7 @@ namespace BTCPayServer.Tests Assert.Contains("Mined 1 block", s.Driver.WaitForElement(By.Id("CheatSuccessMessage")).Text); }); - + // Settled TestUtils.Eventually(() => { @@ -244,7 +244,7 @@ namespace BTCPayServer.Tests Assert.StartsWith("lnbcrt", copyAddressLightning); Assert.StartsWith($"bitcoin:{address.ToUpperInvariant()}?amount=", qrValue); Assert.Contains("&lightning=LNBCRT", qrValue); - + // Check details s.Driver.ToggleCollapse("PaymentDetails"); Assert.Contains("1 BTC = ", s.Driver.FindElement(By.Id("PaymentDetails-ExchangeRate")).Text); @@ -252,7 +252,7 @@ namespace BTCPayServer.Tests Assert.Contains("$", s.Driver.FindElement(By.Id("PaymentDetails-TotalFiat")).Text); Assert.Contains("BTC", s.Driver.FindElement(By.Id("PaymentDetails-AmountDue")).Text); Assert.Contains("BTC", s.Driver.FindElement(By.Id("PaymentDetails-TotalPrice")).Text); - + // Switch to amount displayed in sats s.GoToHome(); s.GoToStore(StoreNavPages.CheckoutAppearance); @@ -262,7 +262,7 @@ namespace BTCPayServer.Tests s.GoToInvoiceCheckout(invoiceId); s.Driver.WaitUntilAvailable(By.Id("Checkout-v2")); Assert.Contains("sats", s.Driver.FindElement(By.Id("AmountDue")).Text); - + // Check details s.Driver.ToggleCollapse("PaymentDetails"); Assert.Contains("1 sat = ", s.Driver.FindElement(By.Id("PaymentDetails-ExchangeRate")).Text); @@ -270,7 +270,7 @@ namespace BTCPayServer.Tests Assert.Contains("$", s.Driver.FindElement(By.Id("PaymentDetails-TotalFiat")).Text); Assert.Contains("sats", s.Driver.FindElement(By.Id("PaymentDetails-AmountDue")).Text); Assert.Contains("sats", s.Driver.FindElement(By.Id("PaymentDetails-TotalPrice")).Text); - + // BIP21 with LN as default payment method s.GoToHome(); invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike"); @@ -280,7 +280,7 @@ namespace BTCPayServer.Tests payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href"); Assert.StartsWith("bitcoin:", payUrl); Assert.Contains("&lightning=lnbcrt", payUrl); - + // Check details s.Driver.ToggleCollapse("PaymentDetails"); Assert.Contains("1 sat = ", s.Driver.FindElement(By.Id("PaymentDetails-ExchangeRate")).Text); @@ -294,7 +294,7 @@ namespace BTCPayServer.Tests s.GoToLightningSettings(); Assert.True(s.Driver.FindElement(By.Id("LNURLEnabled")).Selected); Assert.True(s.Driver.FindElement(By.Id("LNURLStandardInvoiceEnabled")).Selected); - + // BIP21 with top-up invoice invoiceId = s.CreateInvoice(amount: null); s.GoToInvoiceCheckout(invoiceId); @@ -312,7 +312,7 @@ namespace BTCPayServer.Tests Assert.Equal(address, copyAddressOnchain); Assert.StartsWith("lnurl", copyAddressLightning); Assert.StartsWith($"bitcoin:{address.ToUpperInvariant()}?lightning=LNURL", qrValue); - + // Check details s.Driver.ToggleCollapse("PaymentDetails"); Assert.Contains("1 sat = ", s.Driver.FindElement(By.Id("PaymentDetails-ExchangeRate")).Text); @@ -331,7 +331,7 @@ namespace BTCPayServer.Tests Assert.Contains("This invoice will expire in", paymentInfo.Text); Assert.Contains("00:0", paymentInfo.Text); Assert.DoesNotContain("Please send", paymentInfo.Text); - + // Configure countdown timer s.GoToHome(); invoiceId = s.CreateInvoice(); @@ -343,13 +343,13 @@ namespace BTCPayServer.Tests displayExpirationTimer.SendKeys("10"); s.Driver.FindElement(By.Id("Save")).Click(); Assert.Contains("Store successfully updated", s.FindAlertMessage().Text); - + s.GoToInvoiceCheckout(invoiceId); s.Driver.WaitUntilAvailable(By.Id("Checkout-v2")); paymentInfo = s.Driver.FindElement(By.Id("PaymentInfo")); Assert.False(paymentInfo.Displayed); Assert.DoesNotContain("This invoice will expire in", paymentInfo.Text); - + expirySeconds = s.Driver.FindElement(By.Id("ExpirySeconds")); expirySeconds.Clear(); expirySeconds.SendKeys("599"); @@ -359,7 +359,7 @@ namespace BTCPayServer.Tests Assert.True(paymentInfo.Displayed); Assert.Contains("This invoice will expire in", paymentInfo.Text); Assert.Contains("09:5", paymentInfo.Text); - + // Disable LNURL again s.GoToHome(); s.GoToLightningSettings(); @@ -378,7 +378,7 @@ namespace BTCPayServer.Tests payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href"); Assert.StartsWith("bitcoin:", payUrl); Assert.Contains("&lightning=lnbcrt", payUrl); - + // Language Switch var languageSelect = new SelectElement(s.Driver.FindElement(By.Id("DefaultLang"))); Assert.Equal("English", languageSelect.SelectedOption.Text); @@ -387,7 +387,7 @@ namespace BTCPayServer.Tests languageSelect.SelectByText("Deutsch"); Assert.Equal("Details anzeigen", s.Driver.FindElement(By.Id("DetailsToggle")).Text); Assert.Contains("lang=de", s.Driver.Url); - + s.Driver.Navigate().Refresh(); languageSelect = new SelectElement(s.Driver.FindElement(By.Id("DefaultLang"))); Assert.Equal("Deutsch", languageSelect.SelectedOption.Text); diff --git a/BTCPayServer.Tests/FastTests.cs b/BTCPayServer.Tests/FastTests.cs index 0af888fb0..bd63c267c 100644 --- a/BTCPayServer.Tests/FastTests.cs +++ b/BTCPayServer.Tests/FastTests.cs @@ -626,7 +626,7 @@ namespace BTCPayServer.Tests [Fact] public void RoundupCurrenciesCorrectly() { - DisplayFormatter displayFormatter = new (CurrencyNameTable.Instance); + DisplayFormatter displayFormatter = new(CurrencyNameTable.Instance); foreach (var test in new[] { (0.0005m, "0.0005 USD", "USD"), (0.001m, "0.001 USD", "USD"), (0.01m, "0.01 USD", "USD"), @@ -766,7 +766,7 @@ namespace BTCPayServer.Tests var root = new Mnemonic( "usage fever hen zero slide mammal silent heavy donate budget pulse say brain thank sausage brand craft about save attract muffin advance illegal cabbage") .DeriveExtKey(); - + // xpub var tpub = "tpubD6NzVbkrYhZ4YHNiuTdTmHRmbcPRLfqgyneZFCL1mkzkUBjXriQShxTh9HL34FK2mhieasJVk9EzJrUfkFqRNQBjiXgx3n5BhPkxKBoFmaS"; Assert.True(DerivationSchemeSettings.TryParseFromWalletFile(tpub, testnet, out var settings, out var error)); diff --git a/BTCPayServer.Tests/FormTests.cs b/BTCPayServer.Tests/FormTests.cs index dfd6d1178..59669ed84 100644 --- a/BTCPayServer.Tests/FormTests.cs +++ b/BTCPayServer.Tests/FormTests.cs @@ -116,7 +116,7 @@ public class FormTests : UnitTestBase break; } } - + form = new Form() { Fields = new List @@ -143,7 +143,7 @@ public class FormTests : UnitTestBase {"invoice_item3", new StringValues("updated")}, {"invoice_test", new StringValues("updated")} })); - + foreach (var f in form.GetAllFields()) { var field = f.Field; @@ -185,7 +185,7 @@ public class FormTests : UnitTestBase form.SetValues(obj); obj = service.GetValues(form); Assert.Null(obj["test"].Value()); - form.SetValues(new JObject{ ["test"] = "hello" }); + form.SetValues(new JObject { ["test"] = "hello" }); obj = service.GetValues(form); Assert.Equal("hello", obj["test"].Value()); } diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index b230bf407..4d139de48 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -302,7 +302,8 @@ namespace BTCPayServer.Tests { await client.GetApp("some random ID lol"); }); - await AssertHttpError(404, async () => { + await AssertHttpError(404, async () => + { await client.GetPosApp("some random ID lol"); }); @@ -451,7 +452,7 @@ namespace BTCPayServer.Tests // Test creating a crowdfund app var app = await client.CreateCrowdfundApp( user.StoreId, - new CreateCrowdfundAppRequest() + new CreateCrowdfundAppRequest() { AppName = "test app from API", Title = "test app title" @@ -462,10 +463,12 @@ namespace BTCPayServer.Tests Assert.Equal("Crowdfund", app.AppType); // Make sure we return a 404 if we try to get an app that doesn't exist - await AssertHttpError(404, async () => { + await AssertHttpError(404, async () => + { await client.GetApp("some random ID lol"); }); - await AssertHttpError(404, async () => { + await AssertHttpError(404, async () => + { await client.GetCrowdfundApp("some random ID lol"); }); @@ -488,7 +491,8 @@ namespace BTCPayServer.Tests // Test deleting the newly created app await client.DeleteApp(retrievedApp.Id); - await AssertHttpError(404, async () => { + await AssertHttpError(404, async () => + { await client.GetApp(retrievedApp.Id); }); } @@ -512,8 +516,8 @@ namespace BTCPayServer.Tests } ); var crowdfundApp = await client.CreateCrowdfundApp(user.StoreId, new CreateCrowdfundAppRequest() { AppName = "test app from API" }); - - // Create another store and one app on it so we can get all apps from all stores for the user below + + // Create another store and one app on it so we can get all apps from all stores for the user below var newStore = await client.CreateStore(new CreateStoreRequest() { Name = "A" }); var newApp = await client.CreateCrowdfundApp(newStore.Id, new CreateCrowdfundAppRequest() { AppName = "new app" }); @@ -544,7 +548,7 @@ namespace BTCPayServer.Tests Assert.Equal(crowdfundApp.Name, apps[1].Name); Assert.Equal(crowdfundApp.StoreId, apps[1].StoreId); Assert.Equal(crowdfundApp.AppType, apps[1].AppType); - + Assert.Equal(newApp.Name, apps[2].Name); Assert.Equal(newApp.StoreId, apps[2].StoreId); Assert.Equal(newApp.AppType, apps[2].AppType); @@ -1066,7 +1070,7 @@ namespace BTCPayServer.Tests var lnrURLs = await unauthenticated.GetPullPaymentLNURL(test4.Id); Assert.IsType(lnrURLs.LNURLBech32); Assert.IsType(lnrURLs.LNURLUri); - + //permission test around auto approved pps and payouts var nonApproved = await acc.CreateClient(Policies.CanCreateNonApprovedPullPayments); var approved = await acc.CreateClient(Policies.CanCreatePullPayments); @@ -1091,7 +1095,7 @@ namespace BTCPayServer.Tests Destination = new Key().GetAddress(ScriptPubKeyType.TaprootBIP86, Network.RegTest).ToString() }); }); - + var pullPayment = await approved.CreatePullPayment(acc.StoreId, new CreatePullPaymentRequest() { Amount = 100, @@ -1100,7 +1104,7 @@ namespace BTCPayServer.Tests PaymentMethods = new[] { "BTC" }, AutoApproveClaims = true }); - + var p = await approved.CreatePayout(acc.StoreId, new CreatePayoutThroughStoreRequest() { Amount = 100, @@ -1256,7 +1260,10 @@ namespace BTCPayServer.Tests //update store Assert.Empty(newStore.PaymentMethodCriteria); await client.GenerateOnChainWallet(newStore.Id, "BTC", new GenerateOnChainWalletRequest()); - var updatedStore = await client.UpdateStore(newStore.Id, new UpdateStoreRequest() { Name = "B", PaymentMethodCriteria = new List() + var updatedStore = await client.UpdateStore(newStore.Id, new UpdateStoreRequest() + { + Name = "B", + PaymentMethodCriteria = new List() { new() { @@ -1265,7 +1272,8 @@ namespace BTCPayServer.Tests PaymentMethod = "BTC", CurrencyCode = "USD" } - }}); + } + }); Assert.Equal("B", updatedStore.Name); var s = (await client.GetStore(newStore.Id)); Assert.Equal("B", s.Name); @@ -1275,9 +1283,9 @@ namespace BTCPayServer.Tests Assert.True(pmc.Above); Assert.Equal("BTC", pmc.PaymentMethod); Assert.Equal("USD", pmc.CurrencyCode); - updatedStore = await client.UpdateStore(newStore.Id, new UpdateStoreRequest() { Name = "B"}); + updatedStore = await client.UpdateStore(newStore.Id, new UpdateStoreRequest() { Name = "B" }); Assert.Empty(newStore.PaymentMethodCriteria); - + //list stores var stores = await client.GetStores(); var storeIds = stores.Select(data => data.Id); @@ -2331,10 +2339,10 @@ namespace BTCPayServer.Tests Assert.NotNull(merchantInvoice.Id); Assert.NotNull(merchantInvoice.PaymentHash); Assert.Equal(merchantInvoice.Id, merchantInvoice.PaymentHash); - + // The default client is using charge, so we should not be able to query channels var chargeClient = await user.CreateClient(Policies.CanUseInternalLightningNode); - + var info = await chargeClient.GetLightningNodeInfo("BTC"); Assert.Single(info.NodeURIs); Assert.NotEqual(0, info.BlockHeight); @@ -2403,7 +2411,7 @@ namespace BTCPayServer.Tests Assert.NotNull(payResponse.FeeAmount); Assert.NotNull(payResponse.TotalAmount); Assert.NotNull(payResponse.PaymentHash); - + // check the get invoice response var merchInvoice = await merchantClient.GetLightningInvoice(merchant.StoreId, "BTC", merchantInvoice.Id); Assert.NotNull(merchInvoice); @@ -2442,7 +2450,7 @@ namespace BTCPayServer.Tests // Amount received might be bigger because of internal implementation shit from lightning Assert.True(LightMoney.Satoshis(1000) <= invoice.AmountReceived); - + // check payments list for store node var payments = await client.GetLightningPayments(user.StoreId, "BTC"); Assert.NotEmpty(payments); @@ -2488,7 +2496,7 @@ namespace BTCPayServer.Tests var user = tester.NewAccount(); await user.GrantAccessAsync(true); user.RegisterLightningNode("BTC", LightningConnectionType.CLightning); - + var client = await user.CreateClient(Policies.Unrestricted); var invoice = await client.CreateInvoice(user.StoreId, new CreateInvoiceRequest @@ -2503,12 +2511,12 @@ namespace BTCPayServer.Tests }); var pm = Assert.Single(await client.GetInvoicePaymentMethods(user.StoreId, invoice.Id)); Assert.False(pm.AdditionalData.HasValues); - + var resp = await tester.CustomerLightningD.Pay(pm.Destination); Assert.Equal(PayResult.Ok, resp.Result); Assert.NotNull(resp.Details.PaymentHash); Assert.NotNull(resp.Details.Preimage); - + pm = Assert.Single(await client.GetInvoicePaymentMethods(user.StoreId, invoice.Id)); Assert.True(pm.AdditionalData.HasValues); Assert.Equal(resp.Details.PaymentHash.ToString(), pm.AdditionalData.GetValue("paymentHash")); @@ -3193,7 +3201,7 @@ namespace BTCPayServer.Tests } - [Fact(Timeout =TestTimeout)] + [Fact(Timeout = TestTimeout)] [Trait("Integration", "Integration")] public async Task StoreLightningAddressesAPITests() { @@ -3205,14 +3213,14 @@ namespace BTCPayServer.Tests var store = await adminClient.GetStore(admin.StoreId); Assert.Empty(await adminClient.GetStorePaymentMethods(store.Id)); - var store2 = (await adminClient.CreateStore(new CreateStoreRequest() {Name = "test2"})).Id; + var store2 = (await adminClient.CreateStore(new CreateStoreRequest() { Name = "test2" })).Id; var address1 = Guid.NewGuid().ToString("n").Substring(0, 8); var address2 = Guid.NewGuid().ToString("n").Substring(0, 8); - - Assert.Empty(await adminClient.GetStoreLightningAddresses(store.Id)); - Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); + + Assert.Empty(await adminClient.GetStoreLightningAddresses(store.Id)); + Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); await adminClient.AddOrUpdateStoreLightningAddress(store.Id, address1, new LightningAddressData()); - + await adminClient.AddOrUpdateStoreLightningAddress(store.Id, address1, new LightningAddressData() { Max = 1 @@ -3221,8 +3229,8 @@ namespace BTCPayServer.Tests { await adminClient.AddOrUpdateStoreLightningAddress(store2, address1, new LightningAddressData()); }); - Assert.Equal(1,Assert.Single(await adminClient.GetStoreLightningAddresses(store.Id)).Max); - Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); + Assert.Equal(1, Assert.Single(await adminClient.GetStoreLightningAddresses(store.Id)).Max); + Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); await adminClient.AddOrUpdateStoreLightningAddress(store2, address2, new LightningAddressData()); @@ -3233,8 +3241,8 @@ namespace BTCPayServer.Tests await adminClient.RemoveStoreLightningAddress(store2, address1); }); await adminClient.RemoveStoreLightningAddress(store2, address2); - - Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); + + Assert.Empty(await adminClient.GetStoreLightningAddresses(store2)); } [Fact(Timeout = 60 * 2 * 1000)] @@ -3706,7 +3714,7 @@ namespace BTCPayServer.Tests Assert.Equal(0.9m, Assert.Single(await clientBasic.GetStoreRates(user.StoreId, new[] { "BTC_XYZ" })).Rate); - + config = await clientBasic.GetStoreRateConfiguration(user.StoreId); Assert.NotNull(config); Assert.NotNull(config.EffectiveScript); @@ -3940,7 +3948,7 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi var withdrawalClient = await admin.CreateClient(Policies.CanWithdrawFromCustodianAccounts); var depositClient = await admin.CreateClient(Policies.CanDepositToCustodianAccounts); var tradeClient = await admin.CreateClient(Policies.CanTradeCustodianAccount); - + var store = await adminClient.GetStore(admin.StoreId); var storeId = store.Id; @@ -3981,19 +3989,19 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi // Test: GetDepositAddress, unauth await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountDepositAddress(storeId, accountId, MockCustodian.DepositPaymentMethod)); - + // Test: GetDepositAddress, auth, but wrong permission await AssertHttpError(403, async () => await managerClient.GetCustodianAccountDepositAddress(storeId, accountId, MockCustodian.DepositPaymentMethod)); - + // Test: GetDepositAddress, wrong payment method - await AssertApiError( 400, "unsupported-payment-method", async () => await depositClient.GetCustodianAccountDepositAddress(storeId, accountId, "WRONG-PaymentMethod")); - + await AssertApiError(400, "unsupported-payment-method", async () => await depositClient.GetCustodianAccountDepositAddress(storeId, accountId, "WRONG-PaymentMethod")); + // Test: GetDepositAddress, wrong store ID await AssertHttpError(403, async () => await depositClient.GetCustodianAccountDepositAddress("WRONG-STORE", accountId, MockCustodian.DepositPaymentMethod)); - + // Test: GetDepositAddress, wrong account ID await AssertHttpError(404, async () => await depositClient.GetCustodianAccountDepositAddress(storeId, "WRONG-ACCOUNT-ID", MockCustodian.DepositPaymentMethod)); - + // Test: GetDepositAddress, correct payment method var depositAddress = await depositClient.GetCustodianAccountDepositAddress(storeId, accountId, MockCustodian.DepositPaymentMethod); Assert.NotNull(depositAddress); @@ -4001,7 +4009,7 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi // Test: Trade, unauth - var tradeRequest = new TradeRequestData { FromAsset = MockCustodian.TradeFromAsset, ToAsset = MockCustodian.TradeToAsset, Qty = new TradeQuantity(MockCustodian.TradeQtyBought, TradeQuantity.ValueType.Exact)}; + var tradeRequest = new TradeRequestData { FromAsset = MockCustodian.TradeFromAsset, ToAsset = MockCustodian.TradeToAsset, Qty = new TradeQuantity(MockCustodian.TradeQtyBought, TradeQuantity.ValueType.Exact) }; await AssertHttpError(401, async () => await unauthClient.MarketTradeCustodianAccountAsset(storeId, accountId, tradeRequest)); // Test: Trade, auth, but wrong permission @@ -4049,11 +4057,11 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi // Test: GetTradeQuote, unauth - await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); - + await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); + // Test: GetTradeQuote, auth, but wrong permission - await AssertHttpError(403, async () => await managerClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); - + await AssertHttpError(403, async () => await managerClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); + // Test: GetTradeQuote, auth, correct permission var tradeQuote = await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset); Assert.NotNull(tradeQuote); @@ -4063,28 +4071,28 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi Assert.Equal(MockCustodian.BtcPriceInEuro, tradeQuote.Ask); // Test: GetTradeQuote, SATS - await AssertApiError(400, "use-asset-synonym", async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, "SATS")); - + await AssertApiError(400, "use-asset-synonym", async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, "SATS")); + // Test: GetTradeQuote, wrong asset - await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, "WRONG-ASSET", MockCustodian.TradeToAsset)); - await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset , "WRONG-ASSET")); + await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, "WRONG-ASSET", MockCustodian.TradeToAsset)); + await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, accountId, MockCustodian.TradeFromAsset, "WRONG-ASSET")); // Test: wrong account ID - await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, "WRONG-ACCOUNT-ID", MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); - + await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeQuote(storeId, "WRONG-ACCOUNT-ID", MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); + // Test: wrong store ID - await AssertHttpError(403, async () => await tradeClient.GetCustodianAccountTradeQuote("WRONG-STORE-ID", accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); + await AssertHttpError(403, async () => await tradeClient.GetCustodianAccountTradeQuote("WRONG-STORE-ID", accountId, MockCustodian.TradeFromAsset, MockCustodian.TradeToAsset)); // Test: GetTradeInfo, unauth - await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountTradeInfo(storeId, accountId, MockCustodian.TradeId)); - + await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountTradeInfo(storeId, accountId, MockCustodian.TradeId)); + // Test: GetTradeInfo, auth, but wrong permission - await AssertHttpError(403, async () => await managerClient.GetCustodianAccountTradeInfo(storeId, accountId, MockCustodian.TradeId)); - + await AssertHttpError(403, async () => await managerClient.GetCustodianAccountTradeInfo(storeId, accountId, MockCustodian.TradeId)); + // Test: GetTradeInfo, auth, correct permission var tradeResult = await tradeClient.GetCustodianAccountTradeInfo(storeId, accountId, MockCustodian.TradeId); Assert.NotNull(tradeResult); @@ -4107,36 +4115,36 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi // Test: GetTradeInfo, wrong trade ID await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeInfo(storeId, accountId, "WRONG-TRADE-ID")); - + // Test: wrong account ID await AssertHttpError(404, async () => await tradeClient.GetCustodianAccountTradeInfo(storeId, "WRONG-ACCOUNT-ID", MockCustodian.TradeId)); - + // Test: wrong store ID await AssertHttpError(403, async () => await tradeClient.GetCustodianAccountTradeInfo("WRONG-STORE-ID", accountId, MockCustodian.TradeId)); var qty = new TradeQuantity(MockCustodian.WithdrawalAmount, TradeQuantity.ValueType.Exact); - // Test: SimulateWithdrawal, unauth + // Test: SimulateWithdrawal, unauth var simulateWithdrawalRequest = new WithdrawRequestData(MockCustodian.WithdrawalPaymentMethod, qty); await AssertHttpError(401, async () => await unauthClient.SimulateCustodianAccountWithdrawal(storeId, accountId, simulateWithdrawalRequest)); - + // Test: SimulateWithdrawal, auth, but wrong permission await AssertHttpError(403, async () => await managerClient.SimulateCustodianAccountWithdrawal(storeId, accountId, simulateWithdrawalRequest)); - + // Test: SimulateWithdrawal, correct payment method, correct amount var simulateWithdrawResponse = await withdrawalClient.SimulateCustodianAccountWithdrawal(storeId, accountId, simulateWithdrawalRequest); AssertMockWithdrawal(simulateWithdrawResponse, custodianAccountData); - + // Test: SimulateWithdrawal, wrong payment method var wrongPaymentMethodSimulateWithdrawalRequest = new WithdrawRequestData("WRONG-PAYMENT-METHOD", qty); - await AssertApiError( 400, "unsupported-payment-method", async () => await withdrawalClient.SimulateCustodianAccountWithdrawal(storeId, accountId, wrongPaymentMethodSimulateWithdrawalRequest)); - + await AssertApiError(400, "unsupported-payment-method", async () => await withdrawalClient.SimulateCustodianAccountWithdrawal(storeId, accountId, wrongPaymentMethodSimulateWithdrawalRequest)); + // Test: SimulateWithdrawal, wrong account ID await AssertHttpError(404, async () => await withdrawalClient.SimulateCustodianAccountWithdrawal(storeId, "WRONG-ACCOUNT-ID", simulateWithdrawalRequest)); - + // Test: SimulateWithdrawal, wrong store ID // TODO it is wierd that 403 is considered normal, but it is like this for all calls where the store is wrong... I'd have preferred a 404 error, because the store cannot be found. - await AssertHttpError(403, async () => await withdrawalClient.SimulateCustodianAccountWithdrawal( "WRONG-STORE-ID",accountId, simulateWithdrawalRequest)); - + await AssertHttpError(403, async () => await withdrawalClient.SimulateCustodianAccountWithdrawal("WRONG-STORE-ID", accountId, simulateWithdrawalRequest)); + // Test: SimulateWithdrawal, correct payment method, wrong amount var wrongAmountSimulateWithdrawalRequest = new WithdrawRequestData(MockCustodian.WithdrawalPaymentMethod, TradeQuantity.Parse("0.666")); await AssertHttpError(400, async () => await withdrawalClient.SimulateCustodianAccountWithdrawal(storeId, accountId, wrongAmountSimulateWithdrawalRequest)); @@ -4145,53 +4153,53 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi var createWithdrawalRequest = new WithdrawRequestData(MockCustodian.WithdrawalPaymentMethod, qty); var createWithdrawalRequestPercentage = new WithdrawRequestData(MockCustodian.WithdrawalPaymentMethod, qty); await AssertHttpError(401, async () => await unauthClient.CreateCustodianAccountWithdrawal(storeId, accountId, createWithdrawalRequest)); - + // Test: CreateWithdrawal, auth, but wrong permission await AssertHttpError(403, async () => await managerClient.CreateCustodianAccountWithdrawal(storeId, accountId, createWithdrawalRequest)); - + // Test: CreateWithdrawal, correct payment method, correct amount var withdrawResponse = await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, accountId, createWithdrawalRequest); AssertMockWithdrawal(withdrawResponse, custodianAccountData); - + // Test: CreateWithdrawal, correct payment method, correct amount, but as a percentage var withdrawWithPercentageResponse = await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, accountId, createWithdrawalRequestPercentage); AssertMockWithdrawal(withdrawWithPercentageResponse, custodianAccountData); - + // Test: CreateWithdrawal, wrong payment method var wrongPaymentMethodCreateWithdrawalRequest = new WithdrawRequestData("WRONG-PAYMENT-METHOD", qty); - await AssertApiError( 400, "unsupported-payment-method", async () => await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, accountId, wrongPaymentMethodCreateWithdrawalRequest)); - + await AssertApiError(400, "unsupported-payment-method", async () => await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, accountId, wrongPaymentMethodCreateWithdrawalRequest)); + // Test: CreateWithdrawal, wrong account ID await AssertHttpError(404, async () => await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, "WRONG-ACCOUNT-ID", createWithdrawalRequest)); - + // Test: CreateWithdrawal, wrong store ID // TODO it is wierd that 403 is considered normal, but it is like this for all calls where the store is wrong... I'd have preferred a 404 error, because the store cannot be found. - await AssertHttpError(403, async () => await withdrawalClient.CreateCustodianAccountWithdrawal( "WRONG-STORE-ID",accountId, createWithdrawalRequest)); - + await AssertHttpError(403, async () => await withdrawalClient.CreateCustodianAccountWithdrawal("WRONG-STORE-ID", accountId, createWithdrawalRequest)); + // Test: CreateWithdrawal, correct payment method, wrong amount var wrongAmountCreateWithdrawalRequest = new WithdrawRequestData(MockCustodian.WithdrawalPaymentMethod, TradeQuantity.Parse("0.666")); await AssertHttpError(400, async () => await withdrawalClient.CreateCustodianAccountWithdrawal(storeId, accountId, wrongAmountCreateWithdrawalRequest)); // Test: GetWithdrawalInfo, unauth await AssertHttpError(401, async () => await unauthClient.GetCustodianAccountWithdrawalInfo(storeId, accountId, MockCustodian.WithdrawalPaymentMethod, MockCustodian.WithdrawalId)); - + // Test: GetWithdrawalInfo, auth, but wrong permission await AssertHttpError(403, async () => await managerClient.GetCustodianAccountWithdrawalInfo(storeId, accountId, MockCustodian.WithdrawalPaymentMethod, MockCustodian.WithdrawalId)); - + // Test: GetWithdrawalInfo, auth, correct permission var withdrawalInfo = await withdrawalClient.GetCustodianAccountWithdrawalInfo(storeId, accountId, MockCustodian.WithdrawalPaymentMethod, MockCustodian.WithdrawalId); AssertMockWithdrawal(withdrawalInfo, custodianAccountData); // Test: GetWithdrawalInfo, wrong withdrawal ID await AssertHttpError(404, async () => await withdrawalClient.GetCustodianAccountWithdrawalInfo(storeId, accountId, MockCustodian.WithdrawalPaymentMethod, "WRONG-WITHDRAWAL-ID")); - + // Test: wrong account ID await AssertHttpError(404, async () => await withdrawalClient.GetCustodianAccountWithdrawalInfo(storeId, "WRONG-ACCOUNT-ID", MockCustodian.WithdrawalPaymentMethod, MockCustodian.WithdrawalId)); - + // Test: wrong store ID // TODO shouldn't this be 404? I cannot change this without bigger impact, as it would affect all API endpoints that are store centered await AssertHttpError(403, async () => await withdrawalClient.GetCustodianAccountWithdrawalInfo("WRONG-STORE-ID", accountId, MockCustodian.WithdrawalPaymentMethod, MockCustodian.WithdrawalId)); - + // TODO assert API error codes, not just status codes by using AssertCustodianApiError() // TODO also test withdrawals for the various "Status" (Queued, Complete, Failed) // TODO create a mock custodian with only ICustodian diff --git a/BTCPayServer.Tests/MockCustodian/MockCustodian.cs b/BTCPayServer.Tests/MockCustodian/MockCustodian.cs index 474e7c453..c009744ed 100644 --- a/BTCPayServer.Tests/MockCustodian/MockCustodian.cs +++ b/BTCPayServer.Tests/MockCustodian/MockCustodian.cs @@ -139,7 +139,7 @@ public class MockCustodian : ICustodian, ICanDeposit, ICanTrade, ICanWithdraw var r = new WithdrawResult(WithdrawalPaymentMethod, WithdrawalAsset, ledgerEntries, WithdrawalId, WithdrawalStatus, createdTime, WithdrawalTargetAddress, WithdrawalTransactionId); return r; } - + private SimulateWithdrawalResult CreateWithdrawSimulationResult() { var ledgerEntries = new List(); @@ -153,7 +153,7 @@ public class MockCustodian : ICustodian, ICanDeposit, ICanTrade, ICanWithdraw { if (paymentMethod == WithdrawalPaymentMethod) { - if (amount.ToString(CultureInfo.InvariantCulture).Equals(""+WithdrawalAmount, StringComparison.InvariantCulture) || WithdrawalAmountPercentage.Equals(amount)) + if (amount.ToString(CultureInfo.InvariantCulture).Equals("" + WithdrawalAmount, StringComparison.InvariantCulture) || WithdrawalAmountPercentage.Equals(amount)) { return Task.FromResult(CreateWithdrawResult()); } diff --git a/BTCPayServer.Tests/SeleniumTester.cs b/BTCPayServer.Tests/SeleniumTester.cs index f9f4b1c57..84b7f47f3 100644 --- a/BTCPayServer.Tests/SeleniumTester.cs +++ b/BTCPayServer.Tests/SeleniumTester.cs @@ -87,7 +87,7 @@ namespace BTCPayServer.Tests Driver.AssertNoError(); } - public void PayInvoice(bool mine = false, decimal? amount= null) + public void PayInvoice(bool mine = false, decimal? amount = null) { if (amount is not null) diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 51f41c996..733367c72 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -148,7 +148,7 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.LinkText("Remove")).Click(); s.Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("DELETE"); s.Driver.FindElement(By.Id("ConfirmContinue")).Click(); - + Assert.DoesNotContain("Custom Form 1", s.Driver.PageSource); s.Driver.FindElement(By.Id("CreateForm")).Click(); s.Driver.FindElement(By.Name("Name")).SendKeys("Custom Form 2"); @@ -163,23 +163,23 @@ namespace BTCPayServer.Tests formurl = s.Driver.Url; result = await s.Server.PayTester.HttpClient.GetAsync(formurl); Assert.NotEqual(HttpStatusCode.NotFound, result.StatusCode); - + s.GoToHome(); s.GoToStore(StoreNavPages.Forms); Assert.Contains("Custom Form 2", s.Driver.PageSource); - + s.Driver.FindElement(By.LinkText("Custom Form 2")).Click(); - + s.Driver.FindElement(By.Name("Name")).Clear(); s.Driver.FindElement(By.Name("Name")).SendKeys("Custom Form 3"); s.Driver.FindElement(By.Id("SaveButton")).Click(); s.GoToStore(StoreNavPages.Forms); Assert.Contains("Custom Form 3", s.Driver.PageSource); - + s.Driver.FindElement(By.Id("StoreNav-PaymentRequests")).Click(); s.Driver.FindElement(By.Id("CreatePaymentRequest")).Click(); - Assert.Equal(4, new SelectElement(s.Driver.FindElement(By.Id("FormId"))).Options.Count); - + Assert.Equal(4, new SelectElement(s.Driver.FindElement(By.Id("FormId"))).Options.Count); + } [Fact(Timeout = TestTimeout)] @@ -1377,9 +1377,9 @@ namespace BTCPayServer.Tests await Task.Delay(500); s.Driver.WaitForElement(By.CssSelector("div.label-manager input")).SendKeys("label2" + Keys.Enter); }); - + TestUtils.Eventually(() => - { + { s.Driver.Navigate().Refresh(); Assert.NotNull(s.Driver.FindElement(By.CssSelector("[data-value='test-label']"))); }); @@ -1401,10 +1401,10 @@ namespace BTCPayServer.Tests s.Driver.WaitForElement(By.CssSelector("[data-value='test-label']")).Click(); await Task.Delay(500); s.Driver.ExecuteJavaScript("document.querySelector('[data-value=\"test-label\"]').nextSibling.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Delete', keyCode: 46}));"); - + }); TestUtils.Eventually(() => - { + { s.Driver.Navigate().Refresh(); Assert.DoesNotContain("test-label", s.Driver.PageSource); }); diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 7ebfabf66..e4d550585 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -1609,7 +1609,7 @@ namespace BTCPayServer.Tests // Check correct casing: Addresses in payment URI need to be … // - lowercase in link version // - uppercase in QR version - + // Standard for all uppercase characters in QR codes is still not implemented in all wallets // But we're proceeding with BECH32 being uppercase Assert.Equal($"bitcoin:{paymentMethodUnified.BtcAddress}", paymentMethodUnified.InvoiceBitcoinUrl.Split('?')[0]); diff --git a/BTCPayServer.Tests/UtilitiesTests.cs b/BTCPayServer.Tests/UtilitiesTests.cs index 1ba8bf8dc..13f74760e 100644 --- a/BTCPayServer.Tests/UtilitiesTests.cs +++ b/BTCPayServer.Tests/UtilitiesTests.cs @@ -61,34 +61,34 @@ namespace BTCPayServer.Tests return description; } -// /// -// /// This will take the translations from v1 or v2 -// /// and upload them to transifex if not found -// /// -// [FactWithSecret("TransifexAPIToken")] -// [Trait("Utilities", "Utilities")] -//#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously -// public async Task UpdateTransifex() -// { -// // DO NOT RUN IT, THIS WILL ERASE THE CURRENT TRANSIFEX TRANSLATIONS + // /// + // /// This will take the translations from v1 or v2 + // /// and upload them to transifex if not found + // /// + // [FactWithSecret("TransifexAPIToken")] + // [Trait("Utilities", "Utilities")] + //#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + // public async Task UpdateTransifex() + // { + // // DO NOT RUN IT, THIS WILL ERASE THE CURRENT TRANSIFEX TRANSLATIONS -// var client = GetTransifexClient(); -// var translations = JsonTranslation.GetTranslations(TranslationFolder.CheckoutV2); -// var enTranslations = translations["en"]; -// translations.Remove("en"); + // var client = GetTransifexClient(); + // var translations = JsonTranslation.GetTranslations(TranslationFolder.CheckoutV2); + // var enTranslations = translations["en"]; + // translations.Remove("en"); -// foreach (var t in translations) -// { -// foreach (var w in t.Value.Words.ToArray()) -// { -// if (t.Value.Words[w.Key] == null) -// t.Value.Words[w.Key] = enTranslations.Words[w.Key]; -// } -// t.Value.Words.Remove("code"); -// t.Value.Words.Remove("NOTICE_WARN"); -// } -// await client.UpdateTranslations(translations); -// } + // foreach (var t in translations) + // { + // foreach (var w in t.Value.Words.ToArray()) + // { + // if (t.Value.Words[w.Key] == null) + // t.Value.Words[w.Key] = enTranslations.Words[w.Key]; + // } + // t.Value.Words.Remove("code"); + // t.Value.Words.Remove("NOTICE_WARN"); + // } + // await client.UpdateTranslations(translations); + // } //#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously @@ -147,7 +147,7 @@ namespace BTCPayServer.Tests public async Task AutoTranslateChatGPT() { var file = TranslationFolder.CheckoutV2; - + using var driver = new ChromeDriver(new ChromeOptions() { DebuggerAddress = "127.0.0.1:9222" @@ -547,7 +547,7 @@ retry: public string FullPath { get; set; } - public string TransifexProject { get; set; } + public string TransifexProject { get; set; } public string TransifexResource { get; private set; } public void Save() @@ -577,7 +577,7 @@ retry: } } - public void Translate(Dictionary sourceTranslations) + public void Translate(Dictionary sourceTranslations) { foreach (var o in sourceTranslations) if (o.Value != null) diff --git a/BTCPayServer/BufferizedFormFile.cs b/BTCPayServer/BufferizedFormFile.cs index a6848993a..f949ac107 100644 --- a/BTCPayServer/BufferizedFormFile.cs +++ b/BTCPayServer/BufferizedFormFile.cs @@ -1,7 +1,7 @@ -using Microsoft.AspNetCore.Http; using System.IO; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; namespace BTCPayServer { diff --git a/BTCPayServer/ColorPalette.cs b/BTCPayServer/ColorPalette.cs index 2b15d35b8..f057aa8a1 100644 --- a/BTCPayServer/ColorPalette.cs +++ b/BTCPayServer/ColorPalette.cs @@ -59,7 +59,7 @@ namespace BTCPayServer return Labels[num % Labels.Length]; } } - + /// https://gist.github.com/zihotki/09fc41d52981fb6f93a81ebf20b35cd5 /// /// Creates color with corrected brightness. @@ -92,7 +92,7 @@ namespace BTCPayServer return Color.FromArgb(color.A, (int)red, (int)green, (int)blue); } - + public string AdjustBrightness(string html, float correctionFactor) { var color = AdjustBrightness(ColorTranslator.FromHtml(html), correctionFactor); diff --git a/BTCPayServer/Components/AppSales/AppSales.cs b/BTCPayServer/Components/AppSales/AppSales.cs index f7f9427e5..bfc8a9706 100644 --- a/BTCPayServer/Components/AppSales/AppSales.cs +++ b/BTCPayServer/Components/AppSales/AppSales.cs @@ -41,7 +41,7 @@ public class AppSales : ViewComponent }; if (vm.InitialRendering) return View(vm); - + var app = HttpContext.GetAppData(); var stats = await _appService.GetSalesStats(app); vm.SalesCount = stats.SalesCount; diff --git a/BTCPayServer/Components/LabelManager/LabelManager.cs b/BTCPayServer/Components/LabelManager/LabelManager.cs index fb6ad26d8..e64ff3293 100644 --- a/BTCPayServer/Components/LabelManager/LabelManager.cs +++ b/BTCPayServer/Components/LabelManager/LabelManager.cs @@ -13,7 +13,7 @@ namespace BTCPayServer.Components.LabelManager { ExcludeTypes = excludeTypes, WalletObjectId = walletObjectId, - SelectedLabels = selectedLabels?? Array.Empty(), + SelectedLabels = selectedLabels ?? Array.Empty(), DisplayInline = displayInline, RichLabelInfo = richLabelInfo, AutoUpdate = autoUpdate, @@ -25,7 +25,7 @@ namespace BTCPayServer.Components.LabelManager public class RichLabelInfo { - public string Link { get; set; } - public string Tooltip { get; set; } + public string Link { get; set; } + public string Tooltip { get; set; } } } diff --git a/BTCPayServer/Components/QRCode/QRCode.cs b/BTCPayServer/Components/QRCode/QRCode.cs index 472c37978..974cded8e 100644 --- a/BTCPayServer/Components/QRCode/QRCode.cs +++ b/BTCPayServer/Components/QRCode/QRCode.cs @@ -9,8 +9,8 @@ namespace BTCPayServer.Components.QRCode { public class QRCode : ViewComponent { - private static QRCodeGenerator _qrGenerator = new (); - + private static QRCodeGenerator _qrGenerator = new(); + public IViewComponentResult Invoke(string data) { var qrCodeData = _qrGenerator.CreateQrCode(data, QRCodeGenerator.ECCLevel.Q); diff --git a/BTCPayServer/Components/StoreRecentTransactions/StoreRecentTransactions.cs b/BTCPayServer/Components/StoreRecentTransactions/StoreRecentTransactions.cs index 570d586e7..16a38e651 100644 --- a/BTCPayServer/Components/StoreRecentTransactions/StoreRecentTransactions.cs +++ b/BTCPayServer/Components/StoreRecentTransactions/StoreRecentTransactions.cs @@ -59,7 +59,7 @@ public class StoreRecentTransactions : ViewComponent var network = derivationSettings.Network; var wallet = _walletProvider.GetWallet(network); var allTransactions = await wallet.FetchTransactionHistory(derivationSettings.AccountDerivation, 0, 5, TimeSpan.FromDays(31.0)); - var walletTransactionsInfo = await _walletRepository.GetWalletTransactionsInfo( vm.WalletId , allTransactions.Select(t => t.TransactionId.ToString()).ToArray()); + var walletTransactionsInfo = await _walletRepository.GetWalletTransactionsInfo(vm.WalletId, allTransactions.Select(t => t.TransactionId.ToString()).ToArray()); transactions = allTransactions .Select(tx => diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index d16c78f59..e4ab2e995 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -137,7 +137,7 @@ namespace BTCPayServer.Configuration foreach (var n in new BTCPayNetworkProvider(networkType).GetAll().OfType()) { builder.AppendLine(CultureInfo.InvariantCulture, $"#{n.CryptoCode}.explorer.url={n.NBXplorerNetwork.DefaultSettings.DefaultUrl}"); - builder.AppendLine(CultureInfo.InvariantCulture, $"#{n.CryptoCode}.explorer.cookiefile={ n.NBXplorerNetwork.DefaultSettings.DefaultCookieFile}"); + builder.AppendLine(CultureInfo.InvariantCulture, $"#{n.CryptoCode}.explorer.cookiefile={n.NBXplorerNetwork.DefaultSettings.DefaultCookieFile}"); builder.AppendLine(CultureInfo.InvariantCulture, $"#{n.CryptoCode}.blockexplorerlink=https://mempool.space/tx/{{0}}"); if (n.SupportLightning) { diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs index b7dd27015..621a57469 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs @@ -189,7 +189,7 @@ namespace BTCPayServer.Controllers.Greenfield { return AppNotFound(); } - + return Ok(ToPointOfSaleModel(app)); } @@ -202,7 +202,7 @@ namespace BTCPayServer.Controllers.Greenfield { return AppNotFound(); } - + return Ok(ToCrowdfundModel(app)); } @@ -267,7 +267,7 @@ namespace BTCPayServer.Controllers.Greenfield return new PointOfSaleSettings() { Title = request.Title, - DefaultView = (PosViewType) request.DefaultView, + DefaultView = (PosViewType)request.DefaultView, ShowCustomAmount = request.ShowCustomAmount, ShowDiscount = request.ShowDiscount, EnableTips = request.EnableTips, @@ -331,10 +331,10 @@ namespace BTCPayServer.Controllers.Greenfield Currency = settings.Currency, Items = JsonConvert.DeserializeObject( JsonConvert.SerializeObject( - _appService.Parse(settings.Template, settings.Currency), + _appService.Parse(settings.Template, settings.Currency), new JsonSerializerSettings - { - ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() } ) ), @@ -406,10 +406,10 @@ namespace BTCPayServer.Controllers.Greenfield Tagline = settings.Tagline, Perks = JsonConvert.DeserializeObject( JsonConvert.SerializeObject( - _appService.Parse(settings.PerksTemplate, settings.TargetCurrency), + _appService.Parse(settings.PerksTemplate, settings.TargetCurrency), new JsonSerializerSettings - { - ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() } ) ), diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldCustodianAccountController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldCustodianAccountController.cs index f5013c21d..79e4159eb 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldCustodianAccountController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldCustodianAccountController.cs @@ -362,10 +362,10 @@ namespace BTCPayServer.Controllers.Greenfield { return UnsupportedAsset(asset, ex.Message); } - + var simulateWithdrawResult = await withdrawableCustodian.SimulateWithdrawalAsync(request.PaymentMethod, qty, custodianAccount.GetBlob(), cancellationToken); - var result = new WithdrawalSimulationResponseData(simulateWithdrawResult.PaymentMethod, simulateWithdrawResult.Asset, + var result = new WithdrawalSimulationResponseData(simulateWithdrawResult.PaymentMethod, simulateWithdrawResult.Asset, accountId, custodian.Code, simulateWithdrawResult.LedgerEntries, simulateWithdrawResult.MinQty, simulateWithdrawResult.MaxQty); return Ok(result); } diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldPayoutProcessorsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldPayoutProcessorsController.cs index b92d90502..8c655c601 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldPayoutProcessorsController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldPayoutProcessorsController.cs @@ -11,8 +11,8 @@ using BTCPayServer.Security; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; -using StoreData = BTCPayServer.Data.StoreData; using PayoutProcessorData = BTCPayServer.Client.Models.PayoutProcessorData; +using StoreData = BTCPayServer.Data.StoreData; namespace BTCPayServer.Controllers.Greenfield { diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs index 883cc8182..d554e83b4 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs @@ -264,7 +264,8 @@ namespace BTCPayServer.Controllers.Greenfield pullPaymentId = pullPaymentId }, Request.Scheme, Request.Host.ToString())!); - return base.Ok(new PullPaymentLNURL() { + return base.Ok(new PullPaymentLNURL() + { LNURLBech32 = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", true).ToString(), LNURLUri = LNURL.LNURL.EncodeUri(lnurlEndpoint, "withdrawRequest", false).ToString() }); @@ -359,7 +360,7 @@ namespace BTCPayServer.Controllers.Greenfield return this.CreateAPIPermissionError(Policies.CanCreatePullPayments); } } - + if (request is null || !PaymentMethodId.TryParse(request?.PaymentMethod, out var paymentMethodId)) { ModelState.AddModelError(nameof(request.PaymentMethod), "Invalid payment method"); diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoreLightningAddressesController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoreLightningAddressesController.cs index 2f569da4b..59623fe4b 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldStoreLightningAddressesController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoreLightningAddressesController.cs @@ -33,7 +33,10 @@ namespace BTCPayServer.Controllers.Greenfield return new LightningAddressData(); return new LightningAddressData() { - Username = data.Username, Max = blob.Max, Min = blob.Min, CurrencyCode = blob.CurrencyCode + Username = data.Username, + Max = blob.Max, + Min = blob.Min, + CurrencyCode = blob.CurrencyCode }; } @@ -41,7 +44,7 @@ namespace BTCPayServer.Controllers.Greenfield [HttpGet("~/api/v1/stores/{storeId}/lightning-addresses")] public async Task GetStoreLightningAddresses(string storeId) { - return Ok((await _lightningAddressService.Get(new LightningAddressQuery() {StoreIds = new[] {storeId}})) + return Ok((await _lightningAddressService.Get(new LightningAddressQuery() { StoreIds = new[] { storeId } })) .Select(ToModel).ToArray()); } @@ -64,7 +67,8 @@ namespace BTCPayServer.Controllers.Greenfield { var res = await _lightningAddressService.Get(new LightningAddressQuery() { - Usernames = new[] {username}, StoreIds = new[] {storeId}, + Usernames = new[] { username }, + StoreIds = new[] { storeId }, }); return res?.Any() is true ? Ok(ToModel(res.First())) : this.CreateAPIError(404, "lightning-address-not-found", "The lightning address was not present."); } @@ -79,17 +83,17 @@ namespace BTCPayServer.Controllers.Greenfield ModelState.AddModelError(nameof(data.Min), "Minimum must be greater than 0 if provided."); return this.CreateValidationError(ModelState); } - + if (await _lightningAddressService.Set(new Data.LightningAddressData() - { - StoreDataId = storeId, - Username = username - }.SetBlob(new LightningAddressDataBlob() - { - Max = data.Max, - Min = data.Min, - CurrencyCode = data.CurrencyCode - }))) + { + StoreDataId = storeId, + Username = username + }.SetBlob(new LightningAddressDataBlob() + { + Max = data.Max, + Min = data.Min, + CurrencyCode = data.CurrencyCode + }))) { return await GetStoreLightningAddress(storeId, username); } diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesConfigurationController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesConfigurationController.cs index 7e9cc44ae..b4b6ec887 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesConfigurationController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesConfigurationController.cs @@ -111,7 +111,7 @@ namespace BTCPayServer.Controllers.GreenField { parsedCurrencyPairs = blob.DefaultCurrencyPairs.ToHashSet(); } - + ValidateAndSanitizeConfiguration(configuration, blob); if (!ModelState.IsValid) return this.CreateValidationError(ModelState); diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesController.cs index 946356f02..734f3f436 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoreRatesController.cs @@ -32,7 +32,7 @@ namespace BTCPayServer.Controllers.GreenField _rateProviderFactory = rateProviderFactory; _btcPayNetworkProvider = btcPayNetworkProvider; } - + [HttpGet("")] [Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] public async Task GetStoreRates([FromQuery] string[]? currencyPair) @@ -59,7 +59,7 @@ namespace BTCPayServer.Controllers.GreenField { parsedCurrencyPairs = blob.DefaultCurrencyPairs.ToHashSet(); } - + var rules = blob.GetRateRules(_btcPayNetworkProvider); diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs index 41fe168b3..f98751f24 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs @@ -149,13 +149,13 @@ namespace BTCPayServer.Controllers.Greenfield LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate, PaymentTolerance = storeBlob.PaymentTolerance, PayJoinEnabled = storeBlob.PayJoinEnabled, - PaymentMethodCriteria = storeBlob.PaymentMethodCriteria?.Where(criteria => criteria.Value is not null)?.Select(criteria => new PaymentMethodCriteriaData() + PaymentMethodCriteria = storeBlob.PaymentMethodCriteria?.Where(criteria => criteria.Value is not null)?.Select(criteria => new PaymentMethodCriteriaData() { Above = criteria.Above, Amount = criteria.Value.Value, CurrencyCode = criteria.Value.Currency, PaymentMethod = criteria.PaymentMethod.ToStringNormalized() - })?.ToList()?? new List() + })?.ToList() ?? new List() }; } @@ -249,7 +249,8 @@ namespace BTCPayServer.Controllers.Greenfield if (string.IsNullOrEmpty(pmc.CurrencyCode)) { request.AddModelError(data => data.PaymentMethodCriteria[index].CurrencyCode, "CurrencyCode is required", this); - }else if (CurrencyNameTable.Instance.GetCurrencyData(pmc.CurrencyCode, false) is null) + } + else if (CurrencyNameTable.Instance.GetCurrencyData(pmc.CurrencyCode, false) is null) { request.AddModelError(data => data.PaymentMethodCriteria[index].CurrencyCode, "CurrencyCode is invalid", this); } diff --git a/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs b/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs index 95d8df7aa..02f2602c9 100644 --- a/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs +++ b/BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs @@ -30,11 +30,11 @@ using LightningAddressData = BTCPayServer.Client.Models.LightningAddressData; using NotificationData = BTCPayServer.Client.Models.NotificationData; using PaymentRequestData = BTCPayServer.Client.Models.PaymentRequestData; using PayoutData = BTCPayServer.Client.Models.PayoutData; +using PayoutProcessorData = BTCPayServer.Client.Models.PayoutProcessorData; using PullPaymentData = BTCPayServer.Client.Models.PullPaymentData; using StoreData = BTCPayServer.Client.Models.StoreData; using StoreWebhookData = BTCPayServer.Client.Models.StoreWebhookData; using WebhookDeliveryData = BTCPayServer.Client.Models.WebhookDeliveryData; -using PayoutProcessorData = BTCPayServer.Client.Models.PayoutProcessorData; namespace BTCPayServer.Controllers.Greenfield { @@ -223,14 +223,14 @@ namespace BTCPayServer.Controllers.Greenfield return GetFromActionResult( await GetController().MarketTradeCustodianAccountAsset(storeId, accountId, request, cancellationToken)); } - + public override async Task SimulateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().SimulateWithdrawal(storeId, accountId, request, cancellationToken)); } - + public override async Task CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken cancellationToken = default) { @@ -1238,7 +1238,7 @@ namespace BTCPayServer.Controllers.Greenfield return Task.FromResult(GetFromActionResult(GetController().GetStoreRateConfiguration())); } - public override async Task> GetStoreRates (string storeId, + public override async Task> GetStoreRates(string storeId, string[] currencyPair, CancellationToken token = default) { return GetFromActionResult>(await GetController().GetStoreRates(currencyPair)); diff --git a/BTCPayServer/Controllers/LightningAddressService.cs b/BTCPayServer/Controllers/LightningAddressService.cs index 437b5759c..18d29ff07 100644 --- a/BTCPayServer/Controllers/LightningAddressService.cs +++ b/BTCPayServer/Controllers/LightningAddressService.cs @@ -62,7 +62,7 @@ public class LightningAddressService { data.Username = NormalizeUsername(data.Username); await using var context = _applicationDbContextFactory.CreateContext(); - var result = (await GetCore(context, new LightningAddressQuery() { Usernames = new[] { data.Username} })) + var result = (await GetCore(context, new LightningAddressQuery() { Usernames = new[] { data.Username } })) .FirstOrDefault(); if (result is not null) { diff --git a/BTCPayServer/Controllers/UIAccountController.cs b/BTCPayServer/Controllers/UIAccountController.cs index 78c5b9d1e..8d40d3d18 100644 --- a/BTCPayServer/Controllers/UIAccountController.cs +++ b/BTCPayServer/Controllers/UIAccountController.cs @@ -88,7 +88,7 @@ namespace BTCPayServer.Controllers [HttpGet("/cheat/permissions")] [HttpGet("/cheat/permissions/stores/{storeId}")] [CheatModeRoute] - public async Task CheatPermissions([FromServices]IAuthorizationService authorizationService, string storeId = null) + public async Task CheatPermissions([FromServices] IAuthorizationService authorizationService, string storeId = null) { var vm = new CheatPermissionsViewModel(); vm.StoreId = storeId; @@ -790,7 +790,7 @@ namespace BTCPayServer.Controllers if (matchedDomainMapping is not null) return RedirectToAction(nameof(UIHomeController.Home), "UIHome"); } - + return RedirectToAction(nameof(UIHomeController.Index), "UIHome"); } diff --git a/BTCPayServer/Controllers/UIAppsController.cs b/BTCPayServer/Controllers/UIAppsController.cs index 227655fb1..08e10e405 100644 --- a/BTCPayServer/Controllers/UIAppsController.cs +++ b/BTCPayServer/Controllers/UIAppsController.cs @@ -54,7 +54,7 @@ namespace BTCPayServer.Controllers var app = await _appService.GetApp(appId, null); if (app is null) return NotFound(); - + var res = await _appService.ViewLink(app); if (res is null) { @@ -150,11 +150,11 @@ namespace BTCPayServer.Controllers var defaultCurrency = await GetStoreDefaultCurrentIfEmpty(appData.StoreDataId, null); await _appService.SetDefaultSettings(appData, defaultCurrency); await _appService.UpdateOrCreateApp(appData); - + TempData[WellKnownTempData.SuccessMessage] = "App successfully created"; CreatedAppId = appData.Id; - + var url = await type.ConfigureLink(appData); return Redirect(url); } diff --git a/BTCPayServer/Controllers/UIInvoiceController.UI.cs b/BTCPayServer/Controllers/UIInvoiceController.UI.cs index 368e66236..75bafdf8b 100644 --- a/BTCPayServer/Controllers/UIInvoiceController.UI.cs +++ b/BTCPayServer/Controllers/UIInvoiceController.UI.cs @@ -123,7 +123,7 @@ namespace BTCPayServer.Controllers var metaData = PosDataParser.ParsePosData(invoice.Metadata.ToJObject()); var additionalData = metaData .Where(dict => !InvoiceAdditionalDataExclude.Contains(dict.Key)) - .ToDictionary(dict=> dict.Key, dict=> dict.Value); + .ToDictionary(dict => dict.Key, dict => dict.Value); var model = new InvoiceDetailsModel { StoreId = store.Id, @@ -201,12 +201,12 @@ namespace BTCPayServer.Controllers CssFileId = storeBlob.CssFileId, ReceiptOptions = receipt }; - + if (i.Status.ToModernStatus() != InvoiceStatus.Settled) { return View(vm); } - + JToken? receiptData = null; i.Metadata?.AdditionalData?.TryGetValue("receiptData", out receiptData); @@ -897,22 +897,22 @@ namespace BTCPayServer.Controllers { var currency = invoiceEntity.Currency; var crypto = cryptoCode.ToUpperInvariant(); // uppercase to make comparison easier, might be "sats" - + // if invoice source currency is the same as currently display currency, no need for "order amount from invoice" if (crypto == currency || (crypto == "SATS" && currency == "BTC") || (crypto == "BTC" && currency == "SATS")) return null; return _displayFormatter.Currency(invoiceEntity.Price, currency, format); } - + private string? ExchangeRate(string cryptoCode, PaymentMethod paymentMethod, DisplayFormatter.CurrencyFormat format = DisplayFormatter.CurrencyFormat.Code) { var currency = paymentMethod.ParentEntity.Currency; var crypto = cryptoCode.ToUpperInvariant(); // uppercase to make comparison easier, might be "sats" - + if (crypto == currency || (crypto == "SATS" && currency == "BTC") || (crypto == "BTC" && currency == "SATS")) return null; - + return _displayFormatter.Currency(paymentMethod.Rate, currency, format); } diff --git a/BTCPayServer/Controllers/UILNURLController.cs b/BTCPayServer/Controllers/UILNURLController.cs index d5cd33c1c..7304dda34 100644 --- a/BTCPayServer/Controllers/UILNURLController.cs +++ b/BTCPayServer/Controllers/UILNURLController.cs @@ -192,7 +192,7 @@ namespace BTCPayServer case PayResult.Error: default: await _pullPaymentHostedService.Cancel( - new PullPaymentHostedService.CancelRequest(new [] + new PullPaymentHostedService.CancelRequest(new[] { claimResponse.PayoutData.Id }, null)); return BadRequest(new LNUrlStatusResponse @@ -305,7 +305,7 @@ namespace BTCPayServer }; var invoiceMetadata = new InvoiceMetadata(); - invoiceMetadata.OrderId =AppService.GetAppOrderId(app); + invoiceMetadata.OrderId = AppService.GetAppOrderId(app); if (item != null) { invoiceMetadata.ItemCode = item.Id; @@ -355,8 +355,8 @@ namespace BTCPayServer public string InvoiceMetadata { get; set; } } - public ConcurrentDictionary Items { get; } = new (); - public ConcurrentDictionary StoreToItemMap { get; } = new (); + public ConcurrentDictionary Items { get; } = new(); + public ConcurrentDictionary StoreToItemMap { get; } = new(); public override string ToString() { @@ -466,7 +466,7 @@ namespace BTCPayServer lnurlRequest ??= new LNURLPayRequest(); lnUrlMetadata ??= new Dictionary(); - if (lnUrlMetadata?.TryGetValue("text/identifier", out var lnAddress) is true && lnAddress is string) + if (lnUrlMetadata?.TryGetValue("text/identifier", out var lnAddress) is true && lnAddress is not null) { var pm = i.GetPaymentMethod(pmi); var paymentMethodDetails = (LNURLPayPaymentMethodDetails)pm.GetPaymentMethodDetails(); @@ -642,7 +642,7 @@ namespace BTCPayServer { var expiry = i.ExpirationTime.ToUniversalTime() - DateTimeOffset.UtcNow; var metadata = JsonConvert.SerializeObject(lnurlPayRequest.Metadata); - var description = (await _pluginHookService.ApplyFilter("modify-lnurlp-description", metadata)) as string; + var description = (await _pluginHookService.ApplyFilter("modify-lnurlp-description", metadata)) as string; if (description is null) return NotFound(); @@ -704,7 +704,7 @@ namespace BTCPayServer Reason = "Invoice not in a valid payable state" }); } - + [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] [HttpGet("~/stores/{storeId}/plugins/lightning-address")] @@ -759,11 +759,11 @@ namespace BTCPayServer } JObject metadata = null; - if (!string.IsNullOrEmpty(vm.Add.InvoiceMetadata) ) + if (!string.IsNullOrEmpty(vm.Add.InvoiceMetadata)) { try { - metadata = JObject.Parse(vm.Add.InvoiceMetadata); + metadata = JObject.Parse(vm.Add.InvoiceMetadata); } catch (Exception e) { diff --git a/BTCPayServer/Controllers/UIPaymentRequestController.cs b/BTCPayServer/Controllers/UIPaymentRequestController.cs index 533dc0259..ccb7a3c8c 100644 --- a/BTCPayServer/Controllers/UIPaymentRequestController.cs +++ b/BTCPayServer/Controllers/UIPaymentRequestController.cs @@ -198,14 +198,14 @@ namespace BTCPayServer.Controllers { return NotFound(); } - + var storeBlob = store.GetStoreBlob(); vm.StoreName = store.StoreName; vm.BrandColor = storeBlob.BrandColor; vm.LogoFileId = storeBlob.LogoFileId; vm.CssFileId = storeBlob.CssFileId; vm.HubPath = PaymentRequestHub.GetHubPath(Request); - + return View(vm); } @@ -224,14 +224,14 @@ namespace BTCPayServer.Controllers var prBlob = result.GetBlob(); if (prBlob.FormResponse is not null) { - return RedirectToAction("PayPaymentRequest", new {payReqId}); + return RedirectToAction("PayPaymentRequest", new { payReqId }); } var prFormId = prBlob.FormId; var formData = await FormDataService.GetForm(prFormId); if (formData is null) { - - return RedirectToAction("PayPaymentRequest", new {payReqId}); + + return RedirectToAction("PayPaymentRequest", new { payReqId }); } var form = Form.Parse(formData.Config); @@ -239,11 +239,11 @@ namespace BTCPayServer.Controllers { form.ApplyValuesFromForm(Request.Form); if (FormDataService.Validate(form, ModelState)) - { + { prBlob.FormResponse = FormDataService.GetValues(form); result.SetBlob(prBlob); await _PaymentRequestRepository.CreateOrUpdatePaymentRequest(result); - return RedirectToAction("PayPaymentRequest", new {payReqId}); + return RedirectToAction("PayPaymentRequest", new { payReqId }); } } viewModel.FormName = formData.Name; @@ -283,7 +283,7 @@ namespace BTCPayServer.Controllers var formData = await FormDataService.GetForm(result.FormId); if (formData is not null) { - return RedirectToAction("ViewPaymentRequestForm", new {payReqId}); + return RedirectToAction("ViewPaymentRequestForm", new { payReqId }); } } diff --git a/BTCPayServer/Controllers/UIPullPaymentController.cs b/BTCPayServer/Controllers/UIPullPaymentController.cs index 5bc027ae9..e56db6b5c 100644 --- a/BTCPayServer/Controllers/UIPullPaymentController.cs +++ b/BTCPayServer/Controllers/UIPullPaymentController.cs @@ -63,7 +63,7 @@ namespace BTCPayServer.Controllers var store = await _storeRepository.FindStore(pp.StoreId); if (store is null) return NotFound(); - + var storeBlob = store.GetStoreBlob(); var payouts = (await ctx.Payouts.GetPayoutInPeriod(pp) .OrderByDescending(o => o.Date) diff --git a/BTCPayServer/Controllers/UIServerController.cs b/BTCPayServer/Controllers/UIServerController.cs index 9a069f52e..1c126f72a 100644 --- a/BTCPayServer/Controllers/UIServerController.cs +++ b/BTCPayServer/Controllers/UIServerController.cs @@ -424,7 +424,7 @@ namespace BTCPayServer.Controllers { var types = _AppService.GetAvailableAppTypes(); var apps = (await _AppService.GetAllApps(null, true)) - .Select(a => + .Select(a => new SelectListItem($"{types[a.AppType]} - {a.AppName} - {a.StoreName}", a.Id)).ToList(); apps.Insert(0, new SelectListItem("(None)", null)); return apps; diff --git a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs index 9041a0b38..261fd0ab0 100644 --- a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs +++ b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs @@ -455,9 +455,9 @@ namespace BTCPayServer.Controllers { IncludeArchived = false, IncludeStoreData = true, - Stores = new[] {storeId}, + Stores = new[] { storeId }, PayoutIds = payoutIds, - PaymentMethods = new[] {paymentMethodId.ToString()} + PaymentMethods = new[] { paymentMethodId.ToString() } }, ctx, cancellationToken); } diff --git a/BTCPayServer/Controllers/UIStoresController.cs b/BTCPayServer/Controllers/UIStoresController.cs index 49e3b6589..7e4a9dd22 100644 --- a/BTCPayServer/Controllers/UIStoresController.cs +++ b/BTCPayServer/Controllers/UIStoresController.cs @@ -730,7 +730,7 @@ namespace BTCPayServer.Controllers { await _fileService.RemoveFile(blob.CssFileId, userId); } - + // add new CSS file try { diff --git a/BTCPayServer/Controllers/UIWalletsController.PSBT.cs b/BTCPayServer/Controllers/UIWalletsController.PSBT.cs index 882d080f5..72a735745 100644 --- a/BTCPayServer/Controllers/UIWalletsController.PSBT.cs +++ b/BTCPayServer/Controllers/UIWalletsController.PSBT.cs @@ -267,7 +267,7 @@ namespace BTCPayServer.Controllers ModelState.Remove(nameof(vm.PSBT)); ModelState.Remove(nameof(vm.FileName)); ModelState.Remove(nameof(vm.UploadedPSBTFile)); - await FetchTransactionDetails(walletId,derivationSchemeSettings, vm, network); + await FetchTransactionDetails(walletId, derivationSchemeSettings, vm, network); return View("WalletPSBTDecoded", vm); case "save-psbt": @@ -386,15 +386,15 @@ namespace BTCPayServer.Controllers inputVm.BalanceChange = ValueToString(balanceChange2, network); inputVm.Positive = balanceChange2 >= Money.Zero; inputVm.Index = (int)input.Index; - + var walletObjectIds = new List(); - walletObjectIds.Add(new ObjectTypeId(WalletObjectData.Types.Utxo, input.PrevOut.ToString())); - walletObjectIds.Add(new ObjectTypeId(WalletObjectData.Types.Tx, input.PrevOut.Hash.ToString())); + walletObjectIds.Add(new ObjectTypeId(WalletObjectData.Types.Utxo, input.PrevOut.ToString())); + walletObjectIds.Add(new ObjectTypeId(WalletObjectData.Types.Tx, input.PrevOut.Hash.ToString())); var address = txOut?.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork)?.ToString(); - if(address != null) + if (address != null) walletObjectIds.Add(new ObjectTypeId(WalletObjectData.Types.Address, address)); inputToObjects.Add(input.Index, walletObjectIds.ToArray()); - + } vm.Destinations = new List(); foreach (var output in psbtObject.Outputs) @@ -409,9 +409,9 @@ namespace BTCPayServer.Controllers dest.Positive = balanceChange2 >= Money.Zero; dest.Destination = output.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork)?.ToString() ?? output.ScriptPubKey.ToString(); var address = output.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork)?.ToString(); - if(address != null) + if (address != null) outputToObjects.Add(dest.Destination, new ObjectTypeId(WalletObjectData.Types.Address, address)); - + } if (psbtObject.TryGetFee(out var fee)) @@ -442,13 +442,14 @@ namespace BTCPayServer.Controllers .DistinctBy(id => $"{id.Type}:{id.Id}").ToArray(); var labelInfo = await WalletRepository.GetWalletTransactionsInfo(walletId, combinedTypeIds); - foreach (KeyValuePair inputToObject in inputToObjects) + foreach (KeyValuePair inputToObject in inputToObjects) { var keys = inputToObject.Value.Select(id => id.Id).ToArray(); WalletTransactionInfo ix = null; foreach (var key in keys) { - if (!labelInfo.TryGetValue(key, out var i)) continue; + if (!labelInfo.TryGetValue(key, out var i)) + continue; if (ix is null) { ix = i; @@ -458,20 +459,22 @@ namespace BTCPayServer.Controllers ix.Merge(i); } } - if (ix is null) continue; - + if (ix is null) + continue; + var labels = _labelService.CreateTransactionTagModels(ix, Request); var input = vm.Inputs.First(model => model.Index == inputToObject.Key); input.Labels = labels; } foreach (var outputToObject in outputToObjects) { - if (!labelInfo.TryGetValue(outputToObject.Value.Id, out var ix)) continue; + if (!labelInfo.TryGetValue(outputToObject.Value.Id, out var ix)) + continue; var labels = _labelService.CreateTransactionTagModels(ix, Request); var destination = vm.Destinations.First(model => model.Destination == outputToObject.Key); destination.Labels = labels; } - + } [HttpPost("{walletId}/psbt/ready")] @@ -491,7 +494,7 @@ namespace BTCPayServer.Controllers if (derivationSchemeSettings == null) return NotFound(); - await FetchTransactionDetails(walletId,derivationSchemeSettings, vm, network); + await FetchTransactionDetails(walletId, derivationSchemeSettings, vm, network); switch (command) { @@ -622,7 +625,7 @@ namespace BTCPayServer.Controllers BackUrl = vm.BackUrl }); case "decode": - await FetchTransactionDetails(walletId,derivationSchemeSettings, vm, network); + await FetchTransactionDetails(walletId, derivationSchemeSettings, vm, network); return View("WalletPSBTDecoded", vm); default: vm.Errors.Add("Unknown command"); diff --git a/BTCPayServer/Controllers/UIWalletsController.cs b/BTCPayServer/Controllers/UIWalletsController.cs index 090d17a1c..d8ed6a456 100644 --- a/BTCPayServer/Controllers/UIWalletsController.cs +++ b/BTCPayServer/Controllers/UIWalletsController.cs @@ -340,7 +340,7 @@ namespace BTCPayServer.Controllers CryptoImage = GetImage(paymentMethod.PaymentId, network), PaymentLink = bip21.ToString(), ReturnUrl = returnUrl ?? HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath, - SelectedLabels = labels?? Array.Empty() + SelectedLabels = labels ?? Array.Empty() }); } @@ -733,14 +733,14 @@ namespace BTCPayServer.Controllers { var labels = transactionOutput.Labels.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); var walletObjectAddress = new WalletObjectId(walletId, WalletObjectData.Types.Address, transactionOutput.DestinationAddress.ToLowerInvariant()); - var obj = await WalletRepository.GetWalletObject(walletObjectAddress); - if (obj is null) + var obj = await WalletRepository.GetWalletObject(walletObjectAddress); + if (obj is null) { - await WalletRepository.EnsureWalletObject(walletObjectAddress); + await WalletRepository.EnsureWalletObject(walletObjectAddress); } await WalletRepository.AddWalletObjectLabels(walletObjectAddress, labels); } - + var derivationScheme = GetDerivationSchemeSettings(walletId); if (derivationScheme is null) return NotFound(); @@ -787,10 +787,10 @@ namespace BTCPayServer.Controllers switch (response.Result) { case ClaimRequest.ClaimResult.Duplicate: - errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString() } - address reuse
"; + errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString()} - address reuse
"; break; case ClaimRequest.ClaimResult.AmountTooLow: - errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString() } - amount too low
"; + errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString()} - amount too low
"; break; } } @@ -919,8 +919,8 @@ namespace BTCPayServer.Controllers ModelState.Clear(); if (address is not null) { - var addressLabels = await WalletRepository.GetWalletLabels(new WalletObjectId(walletId, WalletObjectData.Types.Address, address.ToString())); - vm.Outputs.Last().Labels = addressLabels.Select(tuple => tuple.Label).ToArray(); + var addressLabels = await WalletRepository.GetWalletLabels(new WalletObjectId(walletId, WalletObjectData.Types.Address, address.ToString())); + vm.Outputs.Last().Labels = addressLabels.Select(tuple => tuple.Label).ToArray(); } } @@ -1350,14 +1350,14 @@ namespace BTCPayServer.Controllers Response.Headers.Add("X-Content-Type-Options", "nosniff"); return Content(res, mimeType); } - + public class UpdateLabelsRequest { public string? Id { get; set; } public string? Type { get; set; } public string[]? Labels { get; set; } } - + [HttpPost("{walletId}/update-labels")] [IgnoreAntiforgeryToken] public async Task UpdateLabels( @@ -1366,23 +1366,23 @@ namespace BTCPayServer.Controllers { if (string.IsNullOrEmpty(request.Type) || string.IsNullOrEmpty(request.Id) || request.Labels is null) return BadRequest(); - + var objid = new WalletObjectId(walletId, request.Type, request.Id); - var obj = await WalletRepository.GetWalletObject(objid); - if (obj is null) + var obj = await WalletRepository.GetWalletObject(objid); + if (obj is null) { - await WalletRepository.EnsureWalletObject(objid); + await WalletRepository.EnsureWalletObject(objid); } else { - var currentLabels = obj.GetNeighbours().Where(data => data.Type == WalletObjectData.Types.Label).ToArray(); - var toRemove = currentLabels.Where(data => !request.Labels.Contains(data.Id)).Select(data => data.Id).ToArray(); - await WalletRepository.RemoveWalletObjectLabels(objid, toRemove); + var currentLabels = obj.GetNeighbours().Where(data => data.Type == WalletObjectData.Types.Label).ToArray(); + var toRemove = currentLabels.Where(data => !request.Labels.Contains(data.Id)).Select(data => data.Id).ToArray(); + await WalletRepository.RemoveWalletObjectLabels(objid, toRemove); } await WalletRepository.AddWalletObjectLabels(objid, request.Labels); return Ok(); } - + [HttpGet("{walletId}/labels")] [IgnoreAntiforgeryToken] public async Task GetLabels( @@ -1399,11 +1399,11 @@ namespace BTCPayServer.Controllers : await WalletRepository.GetWalletLabels(walletObjectId); return Ok(labels .Where(l => !excludeTypes || !WalletObjectData.Types.AllTypes.Contains(l.Label)) - .Select(tuple => new + .Select(tuple => new { label = tuple.Label, color = tuple.Color, - textColor = ColorPalette.Default.TextColor(tuple.Color) + textColor = ColorPalette.Default.TextColor(tuple.Color) })); } diff --git a/BTCPayServer/Data/IHasBlobExtensions.cs b/BTCPayServer/Data/IHasBlobExtensions.cs index 241007d4e..643909428 100644 --- a/BTCPayServer/Data/IHasBlobExtensions.cs +++ b/BTCPayServer/Data/IHasBlobExtensions.cs @@ -12,7 +12,7 @@ namespace BTCPayServer.Data { public static class IHasBlobExtensions { - static readonly JsonSerializerSettings DefaultSerializer; + static readonly JsonSerializerSettings DefaultSerializer; static IHasBlobExtensions() { DefaultSerializer = new JsonSerializerSettings() @@ -30,7 +30,7 @@ namespace BTCPayServer.Data this.data = data; } [Obsolete("Use Blob2 instead")] - public byte[] Blob { get { return data.Blob; } set { data.Blob = value; } } + public byte[] Blob { get { return data.Blob; } set { data.Blob = value; } } public string Blob2 { get { return data.Blob2; } set { data.Blob2 = value; } } } class HasBlobWrapper : IHasBlob diff --git a/BTCPayServer/Data/InvoiceDataExtensions.cs b/BTCPayServer/Data/InvoiceDataExtensions.cs index 4042742b3..aea717198 100644 --- a/BTCPayServer/Data/InvoiceDataExtensions.cs +++ b/BTCPayServer/Data/InvoiceDataExtensions.cs @@ -34,7 +34,7 @@ namespace BTCPayServer.Data } else { - var entity = invoiceData.HasTypedBlob().GetBlob(); + var entity = invoiceData.HasTypedBlob().GetBlob(); entity.Networks = networks; return entity; } diff --git a/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs b/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs index d5e224aa5..f8dd970a1 100644 --- a/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs +++ b/BTCPayServer/Data/Payouts/BitcoinLike/BitcoinLikePayoutHandler.cs @@ -70,7 +70,7 @@ public class BitcoinLikePayoutHandler : IPayoutHandler var explorerClient = _explorerClientProvider.GetExplorerClient(network); if (claimRequest.Destination is IBitcoinLikeClaimDestination bitcoinLikeClaimDestination) { - + await explorerClient.TrackAsync(TrackedSource.Create(bitcoinLikeClaimDestination.Address)); await WalletRepository.AddWalletTransactionAttachment( new WalletId(claimRequest.StoreId, claimRequest.PaymentMethodId.CryptoCode), @@ -210,11 +210,13 @@ public class BitcoinLikePayoutHandler : IPayoutHandler await using (var context = _dbContextFactory.CreateContext()) { var payouts = (await PullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() - { - States = new[] {PayoutState.AwaitingPayment}, Stores = new[] {storeId}, PayoutIds = payoutIds - }, context)).Where(data => - PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && - CanHandle(paymentMethodId)) + { + States = new[] { PayoutState.AwaitingPayment }, + Stores = new[] { storeId }, + PayoutIds = payoutIds + }, context)).Where(data => + PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && + CanHandle(paymentMethodId)) .Select(data => (data, ParseProof(data) as PayoutTransactionOnChainBlob)).Where(tuple => tuple.Item2 != null && tuple.Item2.TransactionId != null && tuple.Item2.Accounted == false); foreach (var valueTuple in payouts) { @@ -230,14 +232,16 @@ public class BitcoinLikePayoutHandler : IPayoutHandler Severity = StatusMessageModel.StatusSeverity.Success }; case "reject-payment": - await using (var context = _dbContextFactory.CreateContext()) + await using (var context = _dbContextFactory.CreateContext()) { var payouts = (await PullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() - { - States = new[] {PayoutState.AwaitingPayment}, Stores = new[] {storeId}, PayoutIds = payoutIds - }, context)).Where(data => - PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && - CanHandle(paymentMethodId)) + { + States = new[] { PayoutState.AwaitingPayment }, + Stores = new[] { storeId }, + PayoutIds = payoutIds + }, context)).Where(data => + PaymentMethodId.TryParse(data.PaymentMethodId, out var paymentMethodId) && + CanHandle(paymentMethodId)) .Select(data => (data, ParseProof(data) as PayoutTransactionOnChainBlob)).Where(tuple => tuple.Item2 != null && tuple.Item2.TransactionId != null && tuple.Item2.Accounted == true); foreach (var valueTuple in payouts) { diff --git a/BTCPayServer/Data/StoreBlob.cs b/BTCPayServer/Data/StoreBlob.cs index 62d115503..a2ef9ea30 100644 --- a/BTCPayServer/Data/StoreBlob.cs +++ b/BTCPayServer/Data/StoreBlob.cs @@ -225,11 +225,11 @@ namespace BTCPayServer.Data [DefaultValue(true)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public bool ShowPayInWalletButton { get; set; } = true; - + [DefaultValue(true)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public bool ShowStoreHeader { get; set; } = true; - + [DefaultValue(true)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] public bool CelebratePayment { get; set; } = true; diff --git a/BTCPayServer/Data/StoreDataExtensions.cs b/BTCPayServer/Data/StoreDataExtensions.cs index 4662478d9..72b5325ed 100644 --- a/BTCPayServer/Data/StoreDataExtensions.cs +++ b/BTCPayServer/Data/StoreDataExtensions.cs @@ -186,12 +186,12 @@ namespace BTCPayServer.Data { return IsPaymentTypeEnabled(storeData, networks, cryptoCode, LNURLPayPaymentType.Instance); } - + private static bool IsPaymentTypeEnabled(this StoreData storeData, BTCPayNetworkProvider networks, string cryptoCode, PaymentType paymentType) { var paymentMethods = storeData.GetSupportedPaymentMethods(networks); var excludeFilters = storeData.GetStoreBlob().GetExcludedPaymentMethods(); - return paymentMethods.Any(method => + return paymentMethods.Any(method => method.PaymentId.CryptoCode == cryptoCode && method.PaymentId.PaymentType == paymentType && !excludeFilters.Match(method.PaymentId)); diff --git a/BTCPayServer/DerivationSchemeSettings.cs b/BTCPayServer/DerivationSchemeSettings.cs index aaab81fc5..026c9f122 100644 --- a/BTCPayServer/DerivationSchemeSettings.cs +++ b/BTCPayServer/DerivationSchemeSettings.cs @@ -49,7 +49,7 @@ namespace BTCPayServer { return AccountDerivation is null ? null : DBUtils.nbxv1_get_wallet_id(Network.CryptoCode, AccountDerivation.ToString()); } - + private static bool TryParseXpub(string xpub, DerivationSchemeParser derivationSchemeParser, ref DerivationSchemeSettings derivationSchemeSettings, ref string error, bool electrum = true) { if (!electrum) @@ -87,9 +87,12 @@ namespace BTCPayServer var match = derivationRegex.Match(xpub.Trim()); if (match.Success) { - if (!string.IsNullOrEmpty(match.Groups[1].Value)) rootFingerprint = HDFingerprint.Parse(match.Groups[1].Value); - if (!string.IsNullOrEmpty(match.Groups[2].Value)) accountKeyPath = KeyPath.Parse(match.Groups[2].Value); - if (!string.IsNullOrEmpty(match.Groups[3].Value)) xpub = match.Groups[3].Value; + if (!string.IsNullOrEmpty(match.Groups[1].Value)) + rootFingerprint = HDFingerprint.Parse(match.Groups[1].Value); + if (!string.IsNullOrEmpty(match.Groups[2].Value)) + accountKeyPath = KeyPath.Parse(match.Groups[2].Value); + if (!string.IsNullOrEmpty(match.Groups[3].Value)) + xpub = match.Groups[3].Value; } derivationSchemeSettings.AccountOriginal = xpub.Trim(); derivationSchemeSettings.AccountDerivation = electrum ? derivationSchemeParser.ParseElectrum(derivationSchemeSettings.AccountOriginal) : derivationSchemeParser.Parse(derivationSchemeSettings.AccountOriginal); diff --git a/BTCPayServer/FileTypeDetector.cs b/BTCPayServer/FileTypeDetector.cs index 4dff3934a..8328c11a3 100644 --- a/BTCPayServer/FileTypeDetector.cs +++ b/BTCPayServer/FileTypeDetector.cs @@ -41,13 +41,13 @@ namespace BTCPayServer { pattern = pattern.Replace(" ", ""); int[] res = new int[pattern.Length / 2]; - for (int i = 0; i < pattern.Length; i+=2) + for (int i = 0; i < pattern.Length; i += 2) { var b = pattern[i..(i + 2)]; if (b == "XX") - res[i/2] = -1; + res[i / 2] = -1; else - res[i/2] = byte.Parse(b, System.Globalization.NumberStyles.HexNumber); + res[i / 2] = byte.Parse(b, System.Globalization.NumberStyles.HexNumber); } return res; } diff --git a/BTCPayServer/Filters/DomainMappingConstraintAttribute.cs b/BTCPayServer/Filters/DomainMappingConstraintAttribute.cs index 407a8a645..f93529cd1 100644 --- a/BTCPayServer/Filters/DomainMappingConstraintAttribute.cs +++ b/BTCPayServer/Filters/DomainMappingConstraintAttribute.cs @@ -13,12 +13,12 @@ namespace BTCPayServer.Filters public DomainMappingConstraintAttribute() { } - + public DomainMappingConstraintAttribute(string appType) { AppType = appType; } - + public int Order => 100; private string AppType { get; } @@ -33,21 +33,22 @@ namespace BTCPayServer.Filters { var appId = (string)context.RouteContext.RouteData.Values["appId"]; var matchedDomainMapping = mapping.FirstOrDefault(item => item.AppId == appId); - + // App is accessed via path, redirect to canonical domain var req = context.RouteContext.HttpContext.Request; if (matchedDomainMapping != null && req.Method != "POST" && !req.HasFormContentType) { var uri = new UriBuilder(req.Scheme, matchedDomainMapping.Domain); - if (req.Host.Port.HasValue) uri.Port = req.Host.Port.Value; + if (req.Host.Port.HasValue) + uri.Port = req.Host.Port.Value; context.RouteContext.HttpContext.Response.Redirect(uri.ToString()); return true; } } - + if (hasDomainMapping) { - var matchedDomainMapping = mapping.FirstOrDefault(item => + var matchedDomainMapping = mapping.FirstOrDefault(item => item.Domain.Equals(context.RouteContext.HttpContext.Request.Host.Host, StringComparison.InvariantCultureIgnoreCase)); if (matchedDomainMapping != null) diff --git a/BTCPayServer/Forms/FormDataExtensions.cs b/BTCPayServer/Forms/FormDataExtensions.cs index ec98c9fda..013ee14c5 100644 --- a/BTCPayServer/Forms/FormDataExtensions.cs +++ b/BTCPayServer/Forms/FormDataExtensions.cs @@ -16,8 +16,8 @@ public static class FormDataExtensions serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); } - - public static JObject Deserialize(this FormData form) + + public static JObject Deserialize(this FormData form) { return JsonConvert.DeserializeObject(form.Config); } diff --git a/BTCPayServer/Forms/FormDataService.cs b/BTCPayServer/Forms/FormDataService.cs index 8db337bab..45e9a43b9 100644 --- a/BTCPayServer/Forms/FormDataService.cs +++ b/BTCPayServer/Forms/FormDataService.cs @@ -22,7 +22,7 @@ public class FormDataService private readonly FormComponentProviders _formProviders; public FormDataService( - ApplicationDbContextFactory applicationDbContextFactory, + ApplicationDbContextFactory applicationDbContextFactory, FormComponentProviders formProviders) { _applicationDbContextFactory = applicationDbContextFactory; @@ -47,16 +47,16 @@ public class FormDataService Field.Create("State", "buyerState", null, false, null), new SelectField() { - Name = "buyerCountry", + Name = "buyerCountry", Label = "Country", Required = true, Type = "select", Options = "Afghanistan, Albania, Algeria, Andorra, Angola, Antigua and Barbuda, Argentina, Armenia, Australia, Austria, Azerbaijan, The Bahamas, Bahrain, Bangladesh, Barbados, Belarus, Belgium, Belize, Benin, Bhutan, Bolivia, Bosnia and Herzegovina, Botswana, Brazil, Brunei, Bulgaria, Burkina Faso, Burundi, Cabo Verde, Cambodia, Cameroon, Canada, Central African Republic (CAR), Chad, Chile, China, Colombia, Comoros, Democratic Republic of the Congo, Republic of the Congo, Costa Rica, Cote d'Ivoire, Croatia, Cuba, Cyprus, Czech Republic, Denmark, Djibouti, Dominica, Dominican Republic, Ecuador, Egypt, El Salvador, Equatorial Guinea, Eritrea, Estonia, Eswatini (formerly Swaziland), Ethiopia, Fiji, Finland, France, Gabon, The Gambia, Georgia, Germany, Ghana, Greece, Grenada, Guatemala, Guinea, Guinea-Bissau, Guyana, Haiti, Honduras, Hungary, Iceland, India, Indonesia, Iran, Iraq, Ireland, Israel, Italy, Jamaica, Japan, Jordan, Kazakhstan, Kenya, Kiribati, Kosovo, Kuwait, Kyrgyzstan, Laos, Latvia, Lebanon, Lesotho, Liberia, Libya, Liechtenstein, Lithuania, Luxembourg, Madagascar, Malawi, Malaysia, Maldives, Mali, Malta, Marshall Islands, Mauritania, Mauritius, Mexico, Micronesia, Moldova, Monaco, Mongolia, Montenegro, Morocco, Mozambique, Myanmar (formerly Burma), Namibia, Nauru, Nepal, Netherlands, New Zealand, Nicaragua, Niger, Nigeria, North Korea, North Macedonia (formerly Macedonia), Norway, Oman, Pakistan, Palau, Palestine, Panama, Papua New Guinea, Paraguay, Peru, Philippines, Poland, Portugal, Qatar, Romania, Russia, Rwanda, Saint Kitts and Nevis, Saint Lucia, Saint Vincent and the Grenadines, Samoa, San Marino, Sao Tome and Principe, Saudi Arabia, Senegal, Serbia, Seychelles, Sierra Leone, Singapore, Slovakia, Slovenia, Solomon Islands, Somalia, South Africa, South Korea, South Sudan, Spain, Sri Lanka, Sudan, Suriname, Sweden, Switzerland, Syria, Taiwan, Tajikistan, Tanzania, Thailand, Timor-Leste (formerly East Timor), Togo, Tonga, Trinidad and Tobago, Tunisia, Turkey, Turkmenistan, Tuvalu, Uganda, Ukraine, United Arab Emirates (UAE), United Kingdom (UK), United States of America (USA), Uruguay, Uzbekistan, Vanuatu, Vatican City (Holy See), Venezuela, Vietnam, Yemen, Zambia, Zimbabwe.".Split(',').Select(s => new SelectListItem(s,s)).ToList() - + } } }; - + private static readonly Dictionary _hardcodedOptions = new() { {"", ("Do not request any information", null, null)!}, @@ -64,13 +64,13 @@ public class FormDataService {"Address", ("Request shipping address", "Provide your address", StaticFormAddress)}, }; - public async Task GetSelect(string storeId ,string selectedFormId) + public async Task GetSelect(string storeId, string selectedFormId) { var forms = await GetForms(storeId); return new SelectList(_hardcodedOptions.Select(pair => new SelectListItem(pair.Value.selectText, pair.Key, selectedFormId == pair.Key)).Concat(forms.Select(data => new SelectListItem(data.Name, data.Id, data.Id == selectedFormId))), nameof(SelectListItem.Value), nameof(SelectListItem.Text)); } - + public async Task> GetForms(string storeId) { ArgumentNullException.ThrowIfNull(storeId); @@ -129,7 +129,7 @@ public class FormDataService { return _formProviders.Validate(form, modelState); } - + public bool IsFormSchemaValid(string schema, [MaybeNullWhen(false)] out Form form, [MaybeNullWhen(false)] out string error) { error = null; @@ -144,7 +144,7 @@ public class FormDataService } catch (Exception ex) { - error = $"Form config was invalid: {ex.Message}"; + error = $"Form config was invalid: {ex.Message}"; } return error is null && form is not null; } @@ -177,7 +177,7 @@ public class FormDataService public JObject GetValues(Form form) { var r = new JObject(); - + foreach (var f in form.GetAllFields()) { var node = r; diff --git a/BTCPayServer/Forms/HtmlInputFormProvider.cs b/BTCPayServer/Forms/HtmlInputFormProvider.cs index e9ea4cd3d..abe660349 100644 --- a/BTCPayServer/Forms/HtmlInputFormProvider.cs +++ b/BTCPayServer/Forms/HtmlInputFormProvider.cs @@ -12,7 +12,7 @@ public class FieldValueMirror : IFormComponentProvider { if (form.GetFieldByFullName(field.Value) is null) { - field.ValidationErrors = new List() {$"{field.Name} requires {field.Value} to be present"}; + field.ValidationErrors = new List() { $"{field.Name} requires {field.Value} to be present" }; } } diff --git a/BTCPayServer/Forms/HtmlSelectFormProvider.cs b/BTCPayServer/Forms/HtmlSelectFormProvider.cs index 8a4b670bd..558040d01 100644 --- a/BTCPayServer/Forms/HtmlSelectFormProvider.cs +++ b/BTCPayServer/Forms/HtmlSelectFormProvider.cs @@ -24,7 +24,7 @@ public class HtmlSelectFormProvider : FormComponentProviderBase } } -public class SelectField: Field +public class SelectField : Field { public List Options { get; set; } } diff --git a/BTCPayServer/Forms/ModifyForm.cs b/BTCPayServer/Forms/ModifyForm.cs index 5066a762e..5f8d16049 100644 --- a/BTCPayServer/Forms/ModifyForm.cs +++ b/BTCPayServer/Forms/ModifyForm.cs @@ -8,7 +8,7 @@ public class ModifyForm [DisplayName("Form configuration (JSON)")] public string FormConfig { get; set; } - + [DisplayName("Allow form for public use")] public bool Public { get; set; } } diff --git a/BTCPayServer/Forms/UIFormsController.cs b/BTCPayServer/Forms/UIFormsController.cs index 6930f8706..9e8d86da3 100644 --- a/BTCPayServer/Forms/UIFormsController.cs +++ b/BTCPayServer/Forms/UIFormsController.cs @@ -49,7 +49,7 @@ public class UIFormsController : Controller [HttpGet("~/stores/{storeId}/forms/new")] public IActionResult Create(string storeId) { - var vm = new ModifyForm {FormConfig = new Form().ToString()}; + var vm = new ModifyForm { FormConfig = new Form().ToString() }; return View("Modify", vm); } @@ -57,10 +57,11 @@ public class UIFormsController : Controller public async Task Modify(string storeId, string id) { var form = await _formDataService.GetForm(storeId, id); - if (form is null) return NotFound(); + if (form is null) + return NotFound(); var config = Form.Parse(form.Config); - return View(new ModifyForm {Name = form.Name, FormConfig = config.ToString(), Public = form.Public}); + return View(new ModifyForm { Name = form.Name, FormConfig = config.ToString(), Public = form.Public }); } [HttpPost("~/stores/{storeId}/forms/modify/{id?}")] @@ -76,7 +77,7 @@ public class UIFormsController : Controller if (!_formDataService.IsFormSchemaValid(modifyForm.FormConfig, out var form, out var error)) { - + ModelState.AddModelError(nameof(modifyForm.FormConfig), $"Form config was invalid: {error})"); } @@ -84,7 +85,7 @@ public class UIFormsController : Controller { modifyForm.FormConfig = form.ToString(); } - + if (!ModelState.IsValid) { @@ -95,7 +96,11 @@ public class UIFormsController : Controller { var formData = new FormData { - Id = id, StoreId = storeId, Name = modifyForm.Name, Config = modifyForm.FormConfig,Public = modifyForm.Public + Id = id, + StoreId = storeId, + Name = modifyForm.Name, + Config = modifyForm.FormConfig, + Public = modifyForm.Public }; var isNew = id is null; await _formDataService.AddOrUpdateForm(formData); @@ -106,7 +111,7 @@ public class UIFormsController : Controller }); if (isNew) { - return RedirectToAction("Modify", new {storeId, id = formData.Id}); + return RedirectToAction("Modify", new { storeId, id = formData.Id }); } } catch (Exception e) @@ -123,9 +128,10 @@ public class UIFormsController : Controller await _formDataService.RemoveForm(id, storeId); TempData.SetStatusMessageModel(new StatusMessageModel { - Severity = StatusMessageModel.StatusSeverity.Success, Message = "Form removed" + Severity = StatusMessageModel.StatusSeverity.Success, + Message = "Form removed" }); - return RedirectToAction("FormsList", new {storeId}); + return RedirectToAction("FormsList", new { storeId }); } [AllowAnonymous] @@ -154,7 +160,7 @@ public class UIFormsController : Controller form.ApplyValuesFromForm(Request.Query); var store = formData.Store ?? await _storeRepository.FindStore(formData.StoreId); var storeBlob = store?.GetStoreBlob(); - + return View("View", new FormViewModel { FormName = formData.Name, @@ -187,7 +193,7 @@ public class UIFormsController : Controller if (!Request.HasFormContentType) return await GetFormView(formData); - + var form = Form.Parse(formData.Config); form.ApplyValuesFromForm(Request.Form); @@ -202,6 +208,6 @@ public class UIFormsController : Controller var request = _formDataService.GenerateInvoiceParametersFromForm(form); var inv = await invoiceController.CreateInvoiceCoreRaw(request, store, Request.GetAbsoluteRoot()); - return RedirectToAction("Checkout", "UIInvoice", new {invoiceId = inv.Id}); + return RedirectToAction("Checkout", "UIInvoice", new { invoiceId = inv.Id }); } } diff --git a/BTCPayServer/HostedServices/PullPaymentHostedService.cs b/BTCPayServer/HostedServices/PullPaymentHostedService.cs index 06bdb33fd..06d21f3a4 100644 --- a/BTCPayServer/HostedServices/PullPaymentHostedService.cs +++ b/BTCPayServer/HostedServices/PullPaymentHostedService.cs @@ -120,7 +120,7 @@ namespace BTCPayServer.HostedServices o.Period = create.Period is TimeSpan period ? (long?)period.TotalSeconds : null; o.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(20)); o.StoreId = create.StoreId; - + o.SetBlob(new PullPaymentBlob() { Name = create.Name ?? string.Empty, @@ -203,7 +203,7 @@ namespace BTCPayServer.HostedServices { query = query.Include(data => data.StoreData); } - + if (payoutQuery.IncludePullPaymentData || !payoutQuery.IncludeArchived) { query = query.Include(data => data.PullPaymentData); diff --git a/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs b/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs index d4021bf6a..b40955eb3 100644 --- a/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs +++ b/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs @@ -28,7 +28,7 @@ public class StoreEmailRuleProcessorSender : EventHostedServiceBase public StoreEmailRuleProcessorSender(StoreRepository storeRepository, EventAggregator eventAggregator, ILogger logger, EmailSenderFactory emailSenderFactory, - LinkGenerator linkGenerator, + LinkGenerator linkGenerator, CurrencyNameTable currencyNameTable) : base( eventAggregator, logger) { diff --git a/BTCPayServer/HostedServices/TransactionLabelMarkerHostedService.cs b/BTCPayServer/HostedServices/TransactionLabelMarkerHostedService.cs index b7429be50..451b5904b 100644 --- a/BTCPayServer/HostedServices/TransactionLabelMarkerHostedService.cs +++ b/BTCPayServer/HostedServices/TransactionLabelMarkerHostedService.cs @@ -78,21 +78,21 @@ namespace BTCPayServer.HostedServices { await _walletRepository.EnsureWalletObjectLink(txWalletObject, walletObjectData.Key); //if the object is an address, we also link the labels to the tx - if(walletObjectData.Value.Type == WalletObjectData.Types.Address) + if (walletObjectData.Value.Type == WalletObjectData.Types.Address) { var neighbours = walletObjectData.Value.GetNeighbours().ToArray(); var labels = neighbours .Where(data => data.Type == WalletObjectData.Types.Label).Select(data => new WalletObjectId(walletObjectDatas.Key, data.Type, data.Id)); - foreach (var label in labels) - { - await _walletRepository.EnsureWalletObjectLink(label, txWalletObject); - var attachments = neighbours.Where(data => data.Type == label.Id); - foreach (var attachment in attachments) - { - await _walletRepository.EnsureWalletObjectLink(new WalletObjectId(walletObjectDatas.Key, attachment.Type, attachment.Id), txWalletObject); - } - } + foreach (var label in labels) + { + await _walletRepository.EnsureWalletObjectLink(label, txWalletObject); + var attachments = neighbours.Where(data => data.Type == label.Id); + foreach (var attachment in attachments) + { + await _walletRepository.EnsureWalletObjectLink(new WalletObjectId(walletObjectDatas.Key, attachment.Type, attachment.Id), txWalletObject); + } + } } } } diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index 1a4754d95..08e582bc0 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -1,4 +1,5 @@ using System; +using System.Configuration.Provider; using System.IO; using System.Linq; using System.Net.Http; @@ -26,6 +27,8 @@ using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.PayJoin; using BTCPayServer.PayoutProcessors; using BTCPayServer.Plugins; +using BTCPayServer.Rating; +using BTCPayServer.Rating.Providers; using BTCPayServer.Security; using BTCPayServer.Security.Bitpay; using BTCPayServer.Security.Greenfield; @@ -42,6 +45,7 @@ using BTCPayServer.Services.PaymentRequests; using BTCPayServer.Services.Rates; using BTCPayServer.Services.Stores; using BTCPayServer.Services.Wallets; +using ExchangeSharp; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; @@ -61,10 +65,6 @@ using NBXplorer.DerivationStrategy; using Newtonsoft.Json; using NicolasDorier.RateLimits; using Serilog; -using ExchangeSharp; -using BTCPayServer.Rating; -using System.Configuration.Provider; -using BTCPayServer.Rating.Providers; #if ALTCOINS using BTCPayServer.Services.Altcoins.Monero; using BTCPayServer.Services.Altcoins.Zcash; diff --git a/BTCPayServer/Models/AppViewModels/CreateAppViewModel.cs b/BTCPayServer/Models/AppViewModels/CreateAppViewModel.cs index 6062502e3..969e8e8b0 100644 --- a/BTCPayServer/Models/AppViewModels/CreateAppViewModel.cs +++ b/BTCPayServer/Models/AppViewModels/CreateAppViewModel.cs @@ -11,12 +11,12 @@ namespace BTCPayServer.Models.AppViewModels public CreateAppViewModel() { } - + public CreateAppViewModel(AppService appService) { SetApps(appService); } - + [Required] [MaxLength(50)] [MinLength(1)] @@ -37,7 +37,7 @@ namespace BTCPayServer.Models.AppViewModels var defaultAppType = PointOfSaleAppType.AppType; var choices = appService.GetAvailableAppTypes().Select(pair => new SelectListItem(pair.Value, pair.Key, pair.Key == defaultAppType)); - + var chosen = choices.FirstOrDefault(f => f.Value == defaultAppType) ?? choices.FirstOrDefault(); AppTypes = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Text), chosen); SelectedAppType = chosen.Value; diff --git a/BTCPayServer/Models/CustodianAccountViewModels/AssetBalanceInfo.cs b/BTCPayServer/Models/CustodianAccountViewModels/AssetBalanceInfo.cs index 5692c9e1b..c6eb99c08 100644 --- a/BTCPayServer/Models/CustodianAccountViewModels/AssetBalanceInfo.cs +++ b/BTCPayServer/Models/CustodianAccountViewModels/AssetBalanceInfo.cs @@ -14,7 +14,7 @@ public class AssetBalanceInfo public string FormattedFiatValue { get; set; } public decimal? FiatValue { get; set; } public Dictionary TradableAssetPairs { get; set; } - + public List WithdrawablePaymentMethods { get; set; } = new(); public string FormattedBid { get; set; } public string FormattedAsk { get; set; } diff --git a/BTCPayServer/Models/CustodianAccountViewModels/EditCustodianAccountViewModel.cs b/BTCPayServer/Models/CustodianAccountViewModels/EditCustodianAccountViewModel.cs index 49af6ea2d..af359bb63 100644 --- a/BTCPayServer/Models/CustodianAccountViewModels/EditCustodianAccountViewModel.cs +++ b/BTCPayServer/Models/CustodianAccountViewModels/EditCustodianAccountViewModel.cs @@ -8,6 +8,6 @@ namespace BTCPayServer.Models.CustodianAccountViewModels public CustodianAccountData CustodianAccount { get; set; } public Form ConfigForm { get; set; } - public string Config { get; set; } + public string Config { get; set; } } } diff --git a/BTCPayServer/Models/CustodianAccountViewModels/TradePrepareViewModel.cs b/BTCPayServer/Models/CustodianAccountViewModels/TradePrepareViewModel.cs index 15ea42294..db28562e1 100644 --- a/BTCPayServer/Models/CustodianAccountViewModels/TradePrepareViewModel.cs +++ b/BTCPayServer/Models/CustodianAccountViewModels/TradePrepareViewModel.cs @@ -5,5 +5,5 @@ namespace BTCPayServer.Models.CustodianAccountViewModels; public class TradePrepareViewModel : AssetQuoteResult { public decimal MaxQty { get; set; } - + } diff --git a/BTCPayServer/Models/PostRedictViewModel.cs b/BTCPayServer/Models/PostRedictViewModel.cs index c3ede2888..4d83e582d 100644 --- a/BTCPayServer/Models/PostRedictViewModel.cs +++ b/BTCPayServer/Models/PostRedictViewModel.cs @@ -9,7 +9,7 @@ namespace BTCPayServer.Models public string FormUrl { get; set; } public bool AllowExternal { get; set; } - public MultiValueDictionary FormParameters { get; set; } = new (); - public Dictionary RouteParameters { get; set; } = new (); + public MultiValueDictionary FormParameters { get; set; } = new(); + public Dictionary RouteParameters { get; set; } = new(); } } diff --git a/BTCPayServer/Models/StoreViewModels/CheckoutAppearanceViewModel.cs b/BTCPayServer/Models/StoreViewModels/CheckoutAppearanceViewModel.cs index 9d2beb094..aa5b87686 100644 --- a/BTCPayServer/Models/StoreViewModels/CheckoutAppearanceViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/CheckoutAppearanceViewModel.cs @@ -28,7 +28,7 @@ namespace BTCPayServer.Models.StoreViewModels [Display(Name = "Show \"Pay in wallet\" button")] public bool ShowPayInWalletButton { get; set; } - + [Display(Name = "Show the store header")] public bool ShowStoreHeader { get; set; } diff --git a/BTCPayServer/Models/WalletViewModels/ListTransactionsViewModel.cs b/BTCPayServer/Models/WalletViewModels/ListTransactionsViewModel.cs index b8cc16fc3..bd21a111b 100644 --- a/BTCPayServer/Models/WalletViewModels/ListTransactionsViewModel.cs +++ b/BTCPayServer/Models/WalletViewModels/ListTransactionsViewModel.cs @@ -14,10 +14,10 @@ namespace BTCPayServer.Models.WalletViewModels public string Link { get; set; } public bool Positive { get; set; } public string Balance { get; set; } - public HashSet Tags { get; set; } = new (); + public HashSet Tags { get; set; } = new(); } - public HashSet<(string Text, string Color, string TextColor)> Labels { get; set; } = new (); - public List Transactions { get; set; } = new (); + public HashSet<(string Text, string Color, string TextColor)> Labels { get; set; } = new(); + public List Transactions { get; set; } = new(); public override int CurrentPageCount => Transactions.Count; public string CryptoCode { get; set; } } diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index 12866f044..f478d86e4 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -76,7 +76,7 @@ namespace BTCPayServer.Payments.Bitcoin if (lightningInfo is not null && !string.IsNullOrEmpty(lightningInfo.PaymentUrls?.BOLT11)) { lightningFallback = lightningInfo.PaymentUrls.BOLT11; - } + } else { var lnurlInfo = invoiceResponse.CryptoInfo.FirstOrDefault(a => @@ -84,7 +84,7 @@ namespace BTCPayServer.Payments.Bitcoin if (lnurlInfo is not null) { lightningFallback = lnurlInfo.PaymentUrls?.AdditionalData["LNURLP"].ToObject(); - + // This seems to be an edge case in the Selenium tests, in which the LNURLP isn't populated. // I have come across it only in the tests and this is supposed to make them happy. if (string.IsNullOrEmpty(lightningFallback)) @@ -122,7 +122,7 @@ namespace BTCPayServer.Payments.Bitcoin var delimiterUrl = model.InvoiceBitcoinUrl.Contains("?") ? "&" : "?"; model.InvoiceBitcoinUrl += $"{delimiterUrl}{lightningFallback}"; // model.InvoiceBitcoinUrl: bitcoin:bcrt1qxp2qa5dhn7?amount=0.00044007&lightning=lnbcrt440070n1... - + var delimiterUrlQR = model.InvoiceBitcoinUrlQR.Contains("?") ? "&" : "?"; model.InvoiceBitcoinUrlQR += $"{delimiterUrlQR}{lightningFallback.ToUpperInvariant().Replace("LIGHTNING=", "lightning=", StringComparison.OrdinalIgnoreCase)}"; // model.InvoiceBitcoinUrlQR: bitcoin:bcrt1qxp2qa5dhn7?amount=0.00044007&lightning=LNBCRT4400... @@ -140,7 +140,7 @@ namespace BTCPayServer.Payments.Bitcoin { model.InvoiceBitcoinUrl = model.InvoiceBitcoinUrlQR = string.Empty; } - + if (model.Activated && amountInSats) { base.PreparePaymentModelForAmountInSats(model, paymentMethod, _displayFormatter); diff --git a/BTCPayServer/Payments/IPaymentMethodHandler.cs b/BTCPayServer/Payments/IPaymentMethodHandler.cs index 76f754b20..da5be36d8 100644 --- a/BTCPayServer/Payments/IPaymentMethodHandler.cs +++ b/BTCPayServer/Payments/IPaymentMethodHandler.cs @@ -100,11 +100,11 @@ namespace BTCPayServer.Payments { return null; } - + public virtual void PreparePaymentModelForAmountInSats(PaymentModel model, IPaymentMethod paymentMethod, DisplayFormatter displayFormatter) { var satoshiCulture = new CultureInfo(CultureInfo.InvariantCulture.Name) - { + { NumberFormat = { NumberGroupSeparator = " " } }; model.CryptoCode = "sats"; diff --git a/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs b/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs index a655d07de..4238c0e55 100644 --- a/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs +++ b/BTCPayServer/Payments/LNURLPay/LNURLPayPaymentHandler.cs @@ -41,7 +41,7 @@ namespace BTCPayServer.Payments.Lightning public override PaymentType PaymentType => PaymentTypes.LightningLike; private const string UriScheme = "lightning:"; - + public IOptions Options { get; } public override async Task CreatePaymentMethodDetails( @@ -121,13 +121,13 @@ namespace BTCPayServer.Payments.Lightning var network = _networkProvider.GetNetwork(model.CryptoCode); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var lnurl = cryptoInfo.PaymentUrls?.AdditionalData["LNURLP"].ToObject(); - + model.PaymentMethodName = GetPaymentMethodName(network); model.BtcAddress = lnurl?.Replace(UriScheme, ""); model.InvoiceBitcoinUrl = lnurl; model.InvoiceBitcoinUrlQR = lnurl?.ToUpperInvariant().Replace(UriScheme.ToUpperInvariant(), UriScheme); model.PeerInfo = ((LNURLPayPaymentMethodDetails)paymentMethod.GetPaymentMethodDetails()).NodeInfo; - + if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC") { base.PreparePaymentModelForAmountInSats(model, paymentMethod, _displayFormatter); diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs index 6bf5d8415..1e3ac790b 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs @@ -11,19 +11,19 @@ namespace BTCPayServer.Payments.Lightning { [JsonIgnore] public BTCPayNetworkBase Network { get; set; } - + [JsonConverter(typeof(LightMoneyJsonConverter))] public LightMoney Amount { get; set; } - + public string BOLT11 { get; set; } - + [JsonConverter(typeof(NBitcoin.JsonConverters.UInt256JsonConverter))] public uint256 PaymentHash { get; set; } - + [JsonConverter(typeof(NBitcoin.JsonConverters.UInt256JsonConverter))] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public uint256 Preimage { get; set; } - + public string PaymentType { get; set; } public string GetDestination() diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index 544b76313..e5991070a 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -212,12 +212,12 @@ namespace BTCPayServer.Payments.Lightning var paymentMethodId = paymentMethod.GetId(); var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId); var network = _networkProvider.GetNetwork(model.CryptoCode); - + model.PaymentMethodName = GetPaymentMethodName(network); model.InvoiceBitcoinUrl = cryptoInfo.PaymentUrls?.BOLT11; model.InvoiceBitcoinUrlQR = $"lightning:{cryptoInfo.PaymentUrls?.BOLT11?.ToUpperInvariant()?.Substring("LIGHTNING:".Length)}"; model.PeerInfo = ((LightningLikePaymentMethodDetails)paymentMethod.GetPaymentMethodDetails()).NodeInfo; - + if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC") { base.PreparePaymentModelForAmountInSats(model, paymentMethod, _displayFormatter); diff --git a/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs b/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs index 26194fd5c..deb2e2a84 100644 --- a/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs +++ b/BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs @@ -62,9 +62,9 @@ public abstract class BaseAutomatedPayoutProcessor : BaseAsyncService where T var blob = GetBlob(_PayoutProcesserSettings); if (paymentMethod is not null) { - + // Allow plugins to do something before the automatic payouts are executed - await _pluginHookService.ApplyFilter("before-automated-payout-processing", + await _pluginHookService.ApplyFilter("before-automated-payout-processing", new BeforePayoutFilterData(store, paymentMethod)); await using var context = _applicationDbContextFactory.CreateContext(); @@ -80,9 +80,9 @@ public abstract class BaseAutomatedPayoutProcessor : BaseAsyncService where T Logs.PayServer.LogInformation($"{payouts.Count} found to process. Starting (and after will sleep for {blob.Interval})"); await Process(paymentMethod, payouts); await context.SaveChangesAsync(); - + // Allow plugins do to something after automatic payout processing - await _pluginHookService.ApplyFilter("after-automated-payout-processing", + await _pluginHookService.ApplyFilter("after-automated-payout-processing", new AfterPayoutFilterData(store, paymentMethod, payouts)); } } diff --git a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs index 3bfbb82a0..420c0883b 100644 --- a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs +++ b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs @@ -403,7 +403,7 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers { return null; } - var info = (ViewCrowdfundViewModel) await _app.GetInfo(app); + var info = (ViewCrowdfundViewModel)await _app.GetInfo(app); info.HubPath = AppHub.GetHubPath(Request); info.SimpleDisplay = Request.Query.ContainsKey("simple"); return info; diff --git a/BTCPayServer/Plugins/Crowdfund/CrowdfundPlugin.cs b/BTCPayServer/Plugins/Crowdfund/CrowdfundPlugin.cs index 64db7b221..05b9cf2ce 100644 --- a/BTCPayServer/Plugins/Crowdfund/CrowdfundPlugin.cs +++ b/BTCPayServer/Plugins/Crowdfund/CrowdfundPlugin.cs @@ -33,12 +33,12 @@ namespace BTCPayServer.Plugins.Crowdfund services.AddSingleton(new UIExtension("Crowdfund/NavExtension", "header-nav")); services.AddSingleton(); services.AddSingleton(); - + base.Execute(services); } } - - public class CrowdfundAppType: AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType + + public class CrowdfundAppType : AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType { private readonly LinkGenerator _linkGenerator; private readonly IOptions _options; @@ -146,7 +146,7 @@ namespace BTCPayServer.Plugins.Crowdfund } } - var invoices = await AppService.GetInvoicesForApp(_invoiceRepository,appData, lastResetDate); + var invoices = await AppService.GetInvoicesForApp(_invoiceRepository, appData, lastResetDate); var completeInvoices = invoices.Where(IsComplete).ToArray(); var pendingInvoices = invoices.Where(IsPending).ToArray(); var paidInvoices = invoices.Where(IsPaid).ToArray(); @@ -256,7 +256,7 @@ namespace BTCPayServer.Plugins.Crowdfund public override Task ViewLink(AppData app) { return Task.FromResult(_linkGenerator.GetPathByAction(nameof(UICrowdfundController.ViewCrowdfund), - "UICrowdfund", new {appId = app.Id}, _options.Value.RootPath)!); + "UICrowdfund", new { appId = app.Id }, _options.Value.RootPath)!); } private static bool IsPaid(InvoiceEntity entity) diff --git a/BTCPayServer/Plugins/Crowdfund/Models/ViewCrowdfundViewModel.cs b/BTCPayServer/Plugins/Crowdfund/Models/ViewCrowdfundViewModel.cs index b599ec9e5..7a90949e1 100644 --- a/BTCPayServer/Plugins/Crowdfund/Models/ViewCrowdfundViewModel.cs +++ b/BTCPayServer/Plugins/Crowdfund/Models/ViewCrowdfundViewModel.cs @@ -60,8 +60,8 @@ namespace BTCPayServer.Plugins.Crowdfund.Models public DateTime? LastResetDate { get; set; } public DateTime? NextResetDate { get; set; } } - - + + public bool Started => !StartDate.HasValue || DateTime.UtcNow > StartDate; diff --git a/BTCPayServer/Plugins/FakeCustodian/FakeCustodian.cs b/BTCPayServer/Plugins/FakeCustodian/FakeCustodian.cs index c2c1aa1d3..227d43d50 100644 --- a/BTCPayServer/Plugins/FakeCustodian/FakeCustodian.cs +++ b/BTCPayServer/Plugins/FakeCustodian/FakeCustodian.cs @@ -120,7 +120,7 @@ public class FakeCustodian : ICustodian, ICanDeposit, ICanWithdraw, ICanTrade if (ValidWithdrawalPaymentMethod.Equals(paymentMethod)) { LedgerEntryData ledgerEntryWithdrawal = new(ValidAsset, -amount, LedgerEntryData.LedgerEntryType.Withdrawal); - LedgerEntryData ledgerEntryFee = new(ValidAsset, - _btcWithdrawalFee, LedgerEntryData.LedgerEntryType.Fee); + LedgerEntryData ledgerEntryFee = new(ValidAsset, -_btcWithdrawalFee, LedgerEntryData.LedgerEntryType.Fee); List ledgerEntries = new(); ledgerEntries.Add(ledgerEntryWithdrawal); ledgerEntries.Add(ledgerEntryFee); diff --git a/BTCPayServer/Plugins/NFC/NFCController.cs b/BTCPayServer/Plugins/NFC/NFCController.cs index a09749770..22b43dbfe 100644 --- a/BTCPayServer/Plugins/NFC/NFCController.cs +++ b/BTCPayServer/Plugins/NFC/NFCController.cs @@ -94,7 +94,7 @@ namespace BTCPayServer.Plugins.NFC var details = ex.InnerException?.Message ?? ex.Message; return BadRequest($"Could not fetch info from LNURL-Withdraw: {details}"); } - + if (info?.Callback is null) { return BadRequest("Could not fetch info from LNURL-Withdraw"); @@ -127,7 +127,7 @@ namespace BTCPayServer.Plugins.NFC { due = new LightMoney(lnPaymentMethod.Calculate().Due); } - + if (info.MinWithdrawable > due || due > info.MaxWithdrawable) { return BadRequest("Invoice amount is not payable with the LNURL allowed amounts."); diff --git a/BTCPayServer/Plugins/NFC/NFCPlugin.cs b/BTCPayServer/Plugins/NFC/NFCPlugin.cs index 36aa2b3f8..722f2a99a 100644 --- a/BTCPayServer/Plugins/NFC/NFCPlugin.cs +++ b/BTCPayServer/Plugins/NFC/NFCPlugin.cs @@ -7,18 +7,18 @@ namespace BTCPayServer.Plugins.NFC { public class NFCPlugin : BaseBTCPayServerPlugin { - + public override string Identifier => "BTCPayServer.Plugins.NFC"; public override string Name => "NFC"; public override string Description => "Allows you to support contactless card payments over NFC and LNURL Withdraw!"; - + public override void Execute(IServiceCollection applicationBuilder) { applicationBuilder.AddSingleton(new UIExtension("NFC/CheckoutEnd", "checkout-end")); applicationBuilder.AddSingleton(new UIExtension("NFC/LNURLNFCPostContent", - "checkout-lightning-post-content")); + "checkout-lightning-post-content")); applicationBuilder.AddSingleton(new UIExtension("NFC/CheckoutEnd", "checkout-v2-end")); applicationBuilder.AddSingleton(new UIExtension("NFC/LNURLNFCPostContent-v2", diff --git a/BTCPayServer/Plugins/PluginBuilderClient.cs b/BTCPayServer/Plugins/PluginBuilderClient.cs index 7f3d5c814..f37ef46be 100644 --- a/BTCPayServer/Plugins/PluginBuilderClient.cs +++ b/BTCPayServer/Plugins/PluginBuilderClient.cs @@ -59,7 +59,7 @@ namespace BTCPayServer.Plugins public async Task GetPublishedVersions(string btcpayVersion, bool includePreRelease) { var queryString = $"?includePreRelease={includePreRelease}"; - if(btcpayVersion is not null) + if (btcpayVersion is not null) queryString += $"&btcpayVersion={btcpayVersion}&"; var result = await httpClient.GetStringAsync($"api/v1/plugins{queryString}"); return JsonConvert.DeserializeObject(result, serializerSettings) ?? throw new InvalidOperationException(); diff --git a/BTCPayServer/Plugins/PluginManager.cs b/BTCPayServer/Plugins/PluginManager.cs index 935704b7b..d0e190b82 100644 --- a/BTCPayServer/Plugins/PluginManager.cs +++ b/BTCPayServer/Plugins/PluginManager.cs @@ -98,7 +98,7 @@ namespace BTCPayServer.Plugins // Formatted either as "::" or "" var idx = plugin.IndexOf("::"); if (idx != -1) - pluginsToLoad.Add((plugin[0..idx], plugin[(idx+1)..])); + pluginsToLoad.Add((plugin[0..idx], plugin[(idx + 1)..])); else pluginsToLoad.Add((Path.GetFileNameWithoutExtension(plugin), plugin)); } @@ -198,7 +198,7 @@ namespace BTCPayServer.Plugins if (ordersByPlugin.TryAdd(p.PluginIdentifier, order)) order++; } - pluginsToLoad.Sort((a,b) => ordersByPlugin[a.PluginIdentifier] - ordersByPlugin[b.PluginIdentifier]); + pluginsToLoad.Sort((a, b) => ordersByPlugin[a.PluginIdentifier] - ordersByPlugin[b.PluginIdentifier]); } public static void UsePlugins(this IApplicationBuilder applicationBuilder) diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index b6b8d66b4..507a56c86 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -200,7 +200,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers price = amount; title = settings.Title; //if cart IS enabled and we detect posdata that matches the cart system's, check inventory for the items - + if (currentView == PosViewType.Cart && AppService.TryParsePosCartItems(jposData, out cartItems)) { @@ -242,7 +242,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var store = await _appService.GetStore(app); var posFormId = settings.FormId; var formData = await FormDataService.GetForm(posFormId); - + JObject formResponseJObject = null; switch (formData) { @@ -308,7 +308,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var receiptData = new JObject(); if (choice is not null) { - receiptData = JObject.FromObject(new Dictionary() + receiptData = JObject.FromObject(new Dictionary() { {"Title", choice.Title}, {"Description", choice.Description}, }); @@ -337,19 +337,20 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers if (appPosData.DiscountAmount > 0) { receiptData.Add("Discount", - $"{_displayFormatter.Currency(appPosData.DiscountAmount, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol) } {(appPosData.DiscountPercentage > 0 ? $"({appPosData.DiscountPercentage}%)" : string.Empty)}"); + $"{_displayFormatter.Currency(appPosData.DiscountAmount, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)} {(appPosData.DiscountPercentage > 0 ? $"({appPosData.DiscountPercentage}%)" : string.Empty)}"); } if (appPosData.Tip > 0) { receiptData.Add("Tip", - $"{_displayFormatter.Currency(appPosData.Tip, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol) }"); + $"{_displayFormatter.Currency(appPosData.Tip, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)}"); } } entity.Metadata.SetAdditionalData("receiptData", receiptData); - if (formResponseJObject is null) return; + if (formResponseJObject is null) + return; var meta = entity.Metadata.ToJObject(); meta.Merge(formResponseJObject); entity.Metadata = InvoiceMetadata.FromJObject(meta); @@ -388,14 +389,14 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var app = await _appService.GetApp(appId, PointOfSaleAppType.AppType); if (app == null) return NotFound(); - + var settings = app.GetSettings(); var formData = await FormDataService.GetForm(settings.FormId); if (formData is null) { return RedirectToAction(nameof(ViewPointOfSale), new { appId, viewType }); } - + var prefix = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)) + "_"; var formParameters = Request.Form .Where(pair => pair.Key != "__RequestVerificationToken") @@ -422,7 +423,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers { vm.RouteParameters.Add("viewType", viewType.Value.ToString()); } - + return View("Views/UIForms/View", vm); } @@ -434,7 +435,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var app = await _appService.GetApp(appId, PointOfSaleAppType.AppType); if (app == null) return NotFound(); - + var settings = app.GetSettings(); var formData = await FormDataService.GetForm(settings.FormId); if (formData is null) @@ -447,16 +448,16 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers .Where(pair => pair.Key.StartsWith(viewModel.FormParameterPrefix)) .ToDictionary(pair => pair.Key.Replace(viewModel.FormParameterPrefix, string.Empty), pair => pair.Value) .ToMultiValueDictionary(p => p.Key, p => p.Value.ToString()); - + if (Request is { Method: "POST", HasFormContentType: true }) { form.ApplyValuesFromForm(Request.Form.Where(pair => formFieldNames.Contains(pair.Key))); - + if (FormDataService.Validate(form, ModelState)) { var controller = nameof(UIPointOfSaleController).TrimEnd("Controller", StringComparison.InvariantCulture); var redirectUrl = - Request.GetAbsoluteUri(Url.Action(nameof(ViewPointOfSale), controller, new {appId, viewType})); + Request.GetAbsoluteUri(Url.Action(nameof(ViewPointOfSale), controller, new { appId, viewType })); formParameters.Add("formResponse", FormDataService.GetValues(form).ToString()); return View("PostRedirect", new PostRedirectViewModel { diff --git a/BTCPayServer/Plugins/PointOfSale/PointOfSalePlugin.cs b/BTCPayServer/Plugins/PointOfSale/PointOfSalePlugin.cs index 6030e2cab..1f3b0b383 100644 --- a/BTCPayServer/Plugins/PointOfSale/PointOfSalePlugin.cs +++ b/BTCPayServer/Plugins/PointOfSale/PointOfSalePlugin.cs @@ -33,7 +33,7 @@ namespace BTCPayServer.Plugins.PointOfSale base.Execute(services); } } - + public enum PosViewType { [Display(Name = "Product list")] @@ -46,7 +46,7 @@ namespace BTCPayServer.Plugins.PointOfSale Print } - public class PointOfSaleAppType: AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType + public class PointOfSaleAppType : AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType { private readonly LinkGenerator _linkGenerator; private readonly IOptions _btcPayServerOptions; diff --git a/BTCPayServer/Roles.cs b/BTCPayServer/Roles.cs index 86ef8428e..f76bf18ee 100644 --- a/BTCPayServer/Roles.cs +++ b/BTCPayServer/Roles.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; using System; +using System.Collections.Generic; using System.Linq; namespace BTCPayServer diff --git a/BTCPayServer/Services/Apps/AppService.cs b/BTCPayServer/Services/Apps/AppService.cs index b83bcac18..3502e68c8 100644 --- a/BTCPayServer/Services/Apps/AppService.cs +++ b/BTCPayServer/Services/Apps/AppService.cs @@ -48,7 +48,7 @@ namespace BTCPayServer.Services.Apps StoreRepository storeRepository, HtmlSanitizer htmlSanitizer) { - _appTypes = apps.ToDictionary(a => a.Type, a=> a); + _appTypes = apps.ToDictionary(a => a.Type, a => a); _ContextFactory = contextFactory; _InvoiceRepository = invoiceRepository; _Currencies = currencies; @@ -83,8 +83,8 @@ namespace BTCPayServer.Services.Apps { if (GetAppType(appData.AppType) is not IHasItemStatsAppType salesType) throw new InvalidOperationException("This app isn't a SalesAppBaseType"); - var paidInvoices = await GetInvoicesForApp(_InvoiceRepository,appData, - null, new [] + var paidInvoices = await GetInvoicesForApp(_InvoiceRepository, appData, + null, new[] { InvoiceState.ToString(InvoiceStatusLegacy.Paid), InvoiceState.ToString(InvoiceStatusLegacy.Confirmed), @@ -94,7 +94,7 @@ namespace BTCPayServer.Services.Apps } public static Task GetSalesStatswithPOSItems(ViewPointOfSaleViewModel.Item[] items, - InvoiceEntity[] paidInvoices, int numberOfDays) + InvoiceEntity[] paidInvoices, int numberOfDays) { var series = paidInvoices .Aggregate(new List(), AggregateInvoiceEntitiesForStats(items)) @@ -126,19 +126,19 @@ namespace BTCPayServer.Services.Apps Series = series.OrderBy(i => i.Label) }); } - + public async Task GetSalesStats(AppData app, int numberOfDays = 7) { if (GetAppType(app.AppType) is not IHasSaleStatsAppType salesType) throw new InvalidOperationException("This app isn't a SalesAppBaseType"); var paidInvoices = await GetInvoicesForApp(_InvoiceRepository, app, DateTimeOffset.UtcNow - TimeSpan.FromDays(numberOfDays), - new [] + new[] { InvoiceState.ToString(InvoiceStatusLegacy.Paid), InvoiceState.ToString(InvoiceStatusLegacy.Confirmed), InvoiceState.ToString(InvoiceStatusLegacy.Complete) }); - + return await salesType.GetSalesStats(app, paidInvoices, numberOfDays); } @@ -195,7 +195,7 @@ namespace BTCPayServer.Services.Apps return res; }; } - + public static string GetAppOrderId(AppData app) => GetAppOrderId(app.AppType, app.Id); public static string GetAppOrderId(string appType, string appId) => appType switch @@ -211,13 +211,13 @@ namespace BTCPayServer.Services.Apps return invoice.GetInternalTags("APP#"); } - public static async Task GetInvoicesForApp(InvoiceRepository invoiceRepository, AppData appData, DateTimeOffset? startDate = null, string[]? status = null) + public static async Task GetInvoicesForApp(InvoiceRepository invoiceRepository, AppData appData, DateTimeOffset? startDate = null, string[]? status = null) { var invoices = await invoiceRepository.GetInvoices(new InvoiceQuery { StoreId = new[] { appData.StoreDataId }, OrderId = appData.TagAllInvoices ? null : new[] { GetAppOrderId(appData) }, - Status = status?? new[]{ + Status = status ?? new[]{ InvoiceState.ToString(InvoiceStatusLegacy.New), InvoiceState.ToString(InvoiceStatusLegacy.Paid), InvoiceState.ToString(InvoiceStatusLegacy.Confirmed), @@ -270,7 +270,7 @@ namespace BTCPayServer.Services.Apps }) .OrderBy(b => b.Created) .ToArrayAsync(); - + // allowNoUser can lead to apps being included twice, unify them with distinct if (allowNoUser) { @@ -295,7 +295,7 @@ namespace BTCPayServer.Services.Apps string posViewStyle = (settings.EnableShoppingCart ? PosViewType.Cart : settings.DefaultView).ToString(); style = typeof(PosViewType).DisplayName(posViewStyle); break; - + default: style = string.Empty; break; @@ -386,7 +386,7 @@ namespace BTCPayServer.Services.Apps return serializer.Serialize(mappingNode); } - public ViewPointOfSaleViewModel.Item[] Parse( string template, string currency) + public ViewPointOfSaleViewModel.Item[] Parse(string template, string currency) { return Parse(_HtmlSanitizer, _displayFormatter, template, currency); } @@ -401,7 +401,7 @@ namespace BTCPayServer.Services.Apps if (string.IsNullOrWhiteSpace(template)) return Array.Empty(); using var input = new StringReader(template); - YamlStream stream = new (); + YamlStream stream = new(); stream.Load(input); var root = (YamlMappingNode)stream.Documents[0].RootNode; return root @@ -410,7 +410,7 @@ namespace BTCPayServer.Services.Apps .Where(kv => kv.Value != null) .Select(c => { - ViewPointOfSaleViewModel.Item.ItemPrice price = new (); + ViewPointOfSaleViewModel.Item.ItemPrice price = new(); var pValue = c.GetDetail("price")?.FirstOrDefault(); switch (c.GetDetailString("custom") ?? c.GetDetailString("price_type")?.ToLowerInvariant()) diff --git a/BTCPayServer/Services/DisplayFormatter.cs b/BTCPayServer/Services/DisplayFormatter.cs index 37abdc6c2..6324435fb 100644 --- a/BTCPayServer/Services/DisplayFormatter.cs +++ b/BTCPayServer/Services/DisplayFormatter.cs @@ -13,7 +13,7 @@ public class DisplayFormatter { _currencyNameTable = currencyNameTable; } - + public enum CurrencyFormat { Code, @@ -49,7 +49,7 @@ public class DisplayFormatter _ => throw new ArgumentOutOfRangeException(nameof(format), format, null) }; } - + public string Currency(string value, string currency, CurrencyFormat format = CurrencyFormat.Code) { return Currency(decimal.Parse(value, CultureInfo.InvariantCulture), currency, format); diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs index a4b9fbb46..667c83d5f 100644 --- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs +++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs @@ -780,8 +780,8 @@ namespace BTCPayServer.Services.Invoices { return network == null ? JsonConvert.SerializeObject(data, DefaultSerializerSettings) : network.ToString(data); } - - + + public InvoiceStatistics GetContributionsByPaymentMethodId(string currency, InvoiceEntity[] invoices, bool softcap) { var contributions = invoices @@ -905,7 +905,7 @@ namespace BTCPayServer.Services.Invoices public bool IncludeArchived { get; set; } = true; public bool IncludeRefunds { get; set; } } - + public class InvoiceStatistics : Dictionary { public InvoiceStatistics(IEnumerable> collection) : base(collection) @@ -913,7 +913,7 @@ namespace BTCPayServer.Services.Invoices TotalCurrency = Values.Select(v => v.CurrencyValue).Sum(); } public decimal TotalCurrency { get; } - + public class Contribution { public PaymentMethodId PaymentMethodId { get; set; } diff --git a/BTCPayServer/Services/Labels/LabelService.cs b/BTCPayServer/Services/Labels/LabelService.cs index 3183ceb27..448d46299 100644 --- a/BTCPayServer/Services/Labels/LabelService.cs +++ b/BTCPayServer/Services/Labels/LabelService.cs @@ -15,12 +15,12 @@ namespace BTCPayServer.Services.Labels; public class LabelService { private readonly LinkGenerator _linkGenerator; - + public LabelService(LinkGenerator linkGenerator) { _linkGenerator = linkGenerator; } - + public IEnumerable CreateTransactionTagModels(WalletTransactionInfo? transactionInfo, HttpRequest req) { if (transactionInfo is null) @@ -32,7 +32,7 @@ public class LabelService { return "Paid a payout"; } - + if (payoutsByPullPaymentId.Count() == 1) { var pp = payoutsByPullPaymentId.Key; diff --git a/BTCPayServer/Services/Notifications/NotificationManager.cs b/BTCPayServer/Services/Notifications/NotificationManager.cs index 17f0c5d66..f3faf55a4 100644 --- a/BTCPayServer/Services/Notifications/NotificationManager.cs +++ b/BTCPayServer/Services/Notifications/NotificationManager.cs @@ -155,14 +155,14 @@ namespace BTCPayServer.Services.Notifications if (handler is null) return null; var notification = data.HasTypedBlob(handler.NotificationBlobType).GetBlob(); - var obj = new NotificationViewModel - { - Id = data.Id, - Type = data.NotificationType, - Created = data.Created, - Seen = data.Seen - }; - handler.FillViewModel(notification, obj); + var obj = new NotificationViewModel + { + Id = data.Id, + Type = data.NotificationType, + Created = data.Created, + Seen = data.Seen + }; + handler.FillViewModel(notification, obj); return obj; } diff --git a/BTCPayServer/Services/PoliciesSettings.cs b/BTCPayServer/Services/PoliciesSettings.cs index 9f7739ca2..d34d55737 100644 --- a/BTCPayServer/Services/PoliciesSettings.cs +++ b/BTCPayServer/Services/PoliciesSettings.cs @@ -61,8 +61,8 @@ namespace BTCPayServer.Services public class DomainToAppMappingItem { - [Display(Name = "Domain")] [Required] [HostName] public string Domain { get; set; } - [Display(Name = "App")] [Required] public string AppId { get; set; } + [Display(Name = "Domain")][Required][HostName] public string Domain { get; set; } + [Display(Name = "App")][Required] public string AppId { get; set; } public string AppType { get; set; } } diff --git a/BTCPayServer/Services/Stores/StoreRepository.cs b/BTCPayServer/Services/Stores/StoreRepository.cs index c96627d39..ceab5490e 100644 --- a/BTCPayServer/Services/Stores/StoreRepository.cs +++ b/BTCPayServer/Services/Stores/StoreRepository.cs @@ -163,7 +163,7 @@ namespace BTCPayServer.Services.Stores { ctx.Stores.Remove(store); await ctx.SaveChangesAsync(); - _eventAggregator.Publish(new StoreRemovedEvent(store.Id)); + _eventAggregator.Publish(new StoreRemovedEvent(store.Id)); } } } diff --git a/BTCPayServer/Services/WalletRepository.cs b/BTCPayServer/Services/WalletRepository.cs index c9ba11468..1c55680f4 100644 --- a/BTCPayServer/Services/WalletRepository.cs +++ b/BTCPayServer/Services/WalletRepository.cs @@ -311,19 +311,19 @@ namespace BTCPayServer.Services public async Task<(string Label, string Color)[]> GetWalletLabels(WalletId walletId) { - return await GetWalletLabels(w => + return await GetWalletLabels(w => w.WalletId == walletId.ToString() && w.Type == WalletObjectData.Types.Label); } - + public async Task<(string Label, string Color)[]> GetWalletLabels(WalletObjectId objectId) { - + await using var ctx = _ContextFactory.CreateContext(); var obj = await GetWalletObject(objectId, true); return obj is null ? Array.Empty<(string Label, string Color)>() : obj.GetNeighbours().Where(data => data.Type == WalletObjectData.Types.Label).Select(FormatToLabel).ToArray(); } - + private async Task<(string Label, string Color)[]> GetWalletLabels(Expression> predicate) { await using var ctx = _ContextFactory.CreateContext(); diff --git a/BTCPayServer/Services/Wallets/Export/TransactionsExport.cs b/BTCPayServer/Services/Wallets/Export/TransactionsExport.cs index 90ef2c7fc..43cac554e 100644 --- a/BTCPayServer/Services/Wallets/Export/TransactionsExport.cs +++ b/BTCPayServer/Services/Wallets/Export/TransactionsExport.cs @@ -44,7 +44,7 @@ namespace BTCPayServer.Services.Wallets.Export return model; }).ToList(); - + return fileFormat switch { "bip329" => ProcessBip329(list), diff --git a/BTCPayServer/TagHelpers/CurrenciesSuggestionsTagHelper.cs b/BTCPayServer/TagHelpers/CurrenciesSuggestionsTagHelper.cs index f178640ac..9f7375d76 100644 --- a/BTCPayServer/TagHelpers/CurrenciesSuggestionsTagHelper.cs +++ b/BTCPayServer/TagHelpers/CurrenciesSuggestionsTagHelper.cs @@ -14,7 +14,7 @@ namespace BTCPayServer.TagHelpers { _currencies = currencies; } - + public override void Process(TagHelperContext context, TagHelperOutput output) { output.Attributes.RemoveAll("currency-selection"); diff --git a/Plugins/BTCPayServer.Plugins.Test/TestPluginMigrationRunner.cs b/Plugins/BTCPayServer.Plugins.Test/TestPluginMigrationRunner.cs index 1973a2653..07f0caaa6 100644 --- a/Plugins/BTCPayServer.Plugins.Test/TestPluginMigrationRunner.cs +++ b/Plugins/BTCPayServer.Plugins.Test/TestPluginMigrationRunner.cs @@ -1,4 +1,4 @@ -using System.Threading; +using System.Threading; using System.Threading.Tasks; using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Plugins.Test.Services;