mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 05:54:26 +01:00
Dotnet reformat
This commit is contained in:
@@ -52,10 +52,10 @@ public class Field
|
||||
public string HelpText;
|
||||
|
||||
[JsonExtensionData] public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
public List<Field> Fields { get; set; } = new ();
|
||||
public List<Field> Fields { get; set; } = new();
|
||||
|
||||
// The field is considered "valid" if there are no validation errors
|
||||
public List<string> ValidationErrors = new ();
|
||||
public List<string> ValidationErrors = new();
|
||||
|
||||
public virtual bool IsValid()
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace BTCPayServer.Client
|
||||
return await HandleResponse<TradeQuoteResponseData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<WithdrawalResponseData> CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
||||
public virtual async Task<WithdrawalResponseData> 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<WithdrawalResponseData>(response);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<NotificationData>()
|
||||
.HasOne(o => o.ApplicationUser)
|
||||
.WithMany(n => n.Notifications)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
@@ -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<PairRate[]> GetRatesAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
@@ -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<AvailableRateProvider> AvailableRateProviders { get; } = new List<AvailableRateProvider>();
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -185,7 +185,7 @@ public class FormTests : UnitTestBase
|
||||
form.SetValues(obj);
|
||||
obj = service.GetValues(form);
|
||||
Assert.Null(obj["test"].Value<string>());
|
||||
form.SetValues(new JObject{ ["test"] = "hello" });
|
||||
form.SetValues(new JObject { ["test"] = "hello" });
|
||||
obj = service.GetValues(form);
|
||||
Assert.Equal("hello", obj["test"].Value<string>());
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -513,7 +517,7 @@ 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" });
|
||||
|
||||
@@ -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<PaymentMethodCriteriaData>()
|
||||
var updatedStore = await client.UpdateStore(newStore.Id, new UpdateStoreRequest()
|
||||
{
|
||||
Name = "B",
|
||||
PaymentMethodCriteria = new List<PaymentMethodCriteriaData>()
|
||||
{
|
||||
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,7 +1283,7 @@ 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
|
||||
@@ -3193,7 +3201,7 @@ namespace BTCPayServer.Tests
|
||||
|
||||
}
|
||||
|
||||
[Fact(Timeout =TestTimeout)]
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Integration", "Integration")]
|
||||
public async Task StoreLightningAddressesAPITests()
|
||||
{
|
||||
@@ -3205,12 +3213,12 @@ 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()
|
||||
@@ -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());
|
||||
|
||||
@@ -3234,7 +3242,7 @@ namespace BTCPayServer.Tests
|
||||
});
|
||||
await adminClient.RemoveStoreLightningAddress(store2, address2);
|
||||
|
||||
Assert.Empty(await adminClient.GetStoreLightningAddresses(store2));
|
||||
Assert.Empty(await adminClient.GetStoreLightningAddresses(store2));
|
||||
}
|
||||
|
||||
[Fact(Timeout = 60 * 2 * 1000)]
|
||||
@@ -3986,7 +3994,7 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi
|
||||
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));
|
||||
@@ -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,10 +4057,10 @@ 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);
|
||||
@@ -4063,27 +4071,27 @@ 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);
|
||||
@@ -4115,7 +4123,7 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi
|
||||
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));
|
||||
|
||||
@@ -4128,14 +4136,14 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi
|
||||
|
||||
// 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"));
|
||||
@@ -4159,14 +4167,14 @@ clientBasic.PreviewUpdateStoreRateConfiguration(user.StoreId, new StoreRateConfi
|
||||
|
||||
// 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"));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace BTCPayServer.Tests
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -61,34 +61,34 @@ namespace BTCPayServer.Tests
|
||||
return description;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// This will take the translations from v1 or v2
|
||||
// /// and upload them to transifex if not found
|
||||
// /// </summary>
|
||||
// [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
|
||||
// /// <summary>
|
||||
// /// This will take the translations from v1 or v2
|
||||
// /// and upload them to transifex if not found
|
||||
// /// </summary>
|
||||
// [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
|
||||
|
||||
@@ -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<string,string> sourceTranslations)
|
||||
public void Translate(Dictionary<string, string> sourceTranslations)
|
||||
{
|
||||
foreach (var o in sourceTranslations)
|
||||
if (o.Value != null)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace BTCPayServer.Components.LabelManager
|
||||
{
|
||||
ExcludeTypes = excludeTypes,
|
||||
WalletObjectId = walletObjectId,
|
||||
SelectedLabels = selectedLabels?? Array.Empty<string>(),
|
||||
SelectedLabels = selectedLabels ?? Array.Empty<string>(),
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace BTCPayServer.Components.QRCode
|
||||
{
|
||||
public class QRCode : ViewComponent
|
||||
{
|
||||
private static QRCodeGenerator _qrGenerator = new ();
|
||||
private static QRCodeGenerator _qrGenerator = new();
|
||||
|
||||
public IViewComponentResult Invoke(string data)
|
||||
{
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace BTCPayServer.Configuration
|
||||
foreach (var n in new BTCPayNetworkProvider(networkType).GetAll().OfType<BTCPayNetwork>())
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
});
|
||||
|
||||
@@ -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<IActionResult> 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.");
|
||||
}
|
||||
@@ -81,15 +85,15 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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<PaymentMethodCriteriaData>()
|
||||
})?.ToList() ?? new List<PaymentMethodCriteriaData>()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -1238,7 +1238,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
return Task.FromResult(GetFromActionResult<StoreRateConfiguration>(GetController<GreenfieldStoreRateConfigurationController>().GetStoreRateConfiguration()));
|
||||
}
|
||||
|
||||
public override async Task<List<StoreRateResult>> GetStoreRates (string storeId,
|
||||
public override async Task<List<StoreRateResult>> GetStoreRates(string storeId,
|
||||
string[] currencyPair, CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<List<StoreRateResult>>(await GetController<GreenfieldStoreRatesController>().GetStoreRates(currencyPair));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace BTCPayServer.Controllers
|
||||
[HttpGet("/cheat/permissions")]
|
||||
[HttpGet("/cheat/permissions/stores/{storeId}")]
|
||||
[CheatModeRoute]
|
||||
public async Task<IActionResult> CheatPermissions([FromServices]IAuthorizationService authorizationService, string storeId = null)
|
||||
public async Task<IActionResult> CheatPermissions([FromServices] IAuthorizationService authorizationService, string storeId = null)
|
||||
{
|
||||
var vm = new CheatPermissionsViewModel();
|
||||
vm.StoreId = storeId;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<string, LightningAddressItem> Items { get; } = new ();
|
||||
public ConcurrentDictionary<string, string[]> StoreToItemMap { get; } = new ();
|
||||
public ConcurrentDictionary<string, LightningAddressItem> Items { get; } = new();
|
||||
public ConcurrentDictionary<string, string[]> StoreToItemMap { get; } = new();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -466,7 +466,7 @@ namespace BTCPayServer
|
||||
lnurlRequest ??= new LNURLPayRequest();
|
||||
lnUrlMetadata ??= new Dictionary<string, string>();
|
||||
|
||||
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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
@@ -243,7 +243,7 @@ namespace BTCPayServer.Controllers
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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":
|
||||
@@ -388,10 +388,10 @@ namespace BTCPayServer.Controllers
|
||||
inputVm.Index = (int)input.Index;
|
||||
|
||||
var walletObjectIds = new List<ObjectTypeId>();
|
||||
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());
|
||||
|
||||
@@ -409,7 +409,7 @@ 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));
|
||||
|
||||
}
|
||||
@@ -442,13 +442,14 @@ namespace BTCPayServer.Controllers
|
||||
.DistinctBy(id => $"{id.Type}:{id.Id}").ToArray();
|
||||
|
||||
var labelInfo = await WalletRepository.GetWalletTransactionsInfo(walletId, combinedTypeIds);
|
||||
foreach (KeyValuePair<uint,ObjectTypeId[]> inputToObject in inputToObjects)
|
||||
foreach (KeyValuePair<uint, ObjectTypeId[]> 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,7 +459,8 @@ 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);
|
||||
@@ -466,7 +468,8 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
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;
|
||||
@@ -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");
|
||||
|
||||
@@ -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<string>()
|
||||
SelectedLabels = labels ?? Array.Empty<string>()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -787,10 +787,10 @@ namespace BTCPayServer.Controllers
|
||||
switch (response.Result)
|
||||
{
|
||||
case ClaimRequest.ClaimResult.Duplicate:
|
||||
errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString() } - address reuse<br/>";
|
||||
errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString()} - address reuse<br/>";
|
||||
break;
|
||||
case ClaimRequest.ClaimResult.AmountTooLow:
|
||||
errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString() } - amount too low<br/>";
|
||||
errorMessage += $"{claimRequest.Value} to {claimRequest.Destination.ToString()} - amount too low<br/>";
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace BTCPayServer.Data
|
||||
}
|
||||
else
|
||||
{
|
||||
var entity = invoiceData.HasTypedBlob<InvoiceEntity>().GetBlob();
|
||||
var entity = invoiceData.HasTypedBlob<InvoiceEntity>().GetBlob();
|
||||
entity.Networks = networks;
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ namespace BTCPayServer.Filters
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class FormDataService
|
||||
{"Address", ("Request shipping address", "Provide your address", StaticFormAddress)},
|
||||
};
|
||||
|
||||
public async Task<SelectList> GetSelect(string storeId ,string selectedFormId)
|
||||
public async Task<SelectList> 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))),
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class FieldValueMirror : IFormComponentProvider
|
||||
{
|
||||
if (form.GetFieldByFullName(field.Value) is null)
|
||||
{
|
||||
field.ValidationErrors = new List<string>() {$"{field.Name} requires {field.Value} to be present"};
|
||||
field.ValidationErrors = new List<string>() { $"{field.Name} requires {field.Value} to be present" };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public class HtmlSelectFormProvider : FormComponentProviderBase
|
||||
}
|
||||
}
|
||||
|
||||
public class SelectField: Field
|
||||
public class SelectField : Field
|
||||
{
|
||||
public List<SelectListItem> Options { get; set; }
|
||||
}
|
||||
|
||||
@@ -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<IActionResult> 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?}")]
|
||||
@@ -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]
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace BTCPayServer.Models
|
||||
public string FormUrl { get; set; }
|
||||
public bool AllowExternal { get; set; }
|
||||
|
||||
public MultiValueDictionary<string, string> FormParameters { get; set; } = new ();
|
||||
public Dictionary<string, string> RouteParameters { get; set; } = new ();
|
||||
public MultiValueDictionary<string, string> FormParameters { get; set; } = new();
|
||||
public Dictionary<string, string> RouteParameters { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<TransactionTagModel> Tags { get; set; } = new ();
|
||||
public HashSet<TransactionTagModel> Tags { get; set; } = new();
|
||||
}
|
||||
public HashSet<(string Text, string Color, string TextColor)> Labels { get; set; } = new ();
|
||||
public List<TransactionViewModel> Transactions { get; set; } = new ();
|
||||
public HashSet<(string Text, string Color, string TextColor)> Labels { get; set; } = new();
|
||||
public List<TransactionViewModel> Transactions { get; set; } = new();
|
||||
public override int CurrentPageCount => Transactions.Count;
|
||||
public string CryptoCode { get; set; }
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace BTCPayServer.Plugins.Crowdfund
|
||||
}
|
||||
}
|
||||
|
||||
public class CrowdfundAppType: AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType
|
||||
public class CrowdfundAppType : AppBaseType, IHasSaleStatsAppType, IHasItemStatsAppType
|
||||
{
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
private readonly IOptions<BTCPayServerOptions> _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<string> 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)
|
||||
|
||||
@@ -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<LedgerEntryData> ledgerEntries = new();
|
||||
ledgerEntries.Add(ledgerEntryWithdrawal);
|
||||
ledgerEntries.Add(ledgerEntryFee);
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BTCPayServer.Plugins
|
||||
public async Task<PublishedVersion[]> 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<PublishedVersion[]>(result, serializerSettings) ?? throw new InvalidOperationException();
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace BTCPayServer.Plugins
|
||||
// Formatted either as "<PLUGIN_IDENTIFIER>::<PathToDll>" or "<PathToDll>"
|
||||
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)
|
||||
|
||||
@@ -308,7 +308,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
var receiptData = new JObject();
|
||||
if (choice is not null)
|
||||
{
|
||||
receiptData = JObject.FromObject(new Dictionary<string, string>()
|
||||
receiptData = JObject.FromObject(new Dictionary<string, string>()
|
||||
{
|
||||
{"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);
|
||||
@@ -456,7 +457,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
@@ -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> _btcPayServerOptions;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BTCPayServer
|
||||
|
||||
@@ -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<SalesStats> GetSalesStatswithPOSItems(ViewPointOfSaleViewModel.Item[] items,
|
||||
InvoiceEntity[] paidInvoices, int numberOfDays)
|
||||
InvoiceEntity[] paidInvoices, int numberOfDays)
|
||||
{
|
||||
var series = paidInvoices
|
||||
.Aggregate(new List<InvoiceStatsItem>(), AggregateInvoiceEntitiesForStats(items))
|
||||
@@ -132,7 +132,7 @@ namespace BTCPayServer.Services.Apps
|
||||
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),
|
||||
@@ -211,13 +211,13 @@ namespace BTCPayServer.Services.Apps
|
||||
return invoice.GetInternalTags("APP#");
|
||||
}
|
||||
|
||||
public static async Task<InvoiceEntity[]> GetInvoicesForApp(InvoiceRepository invoiceRepository, AppData appData, DateTimeOffset? startDate = null, string[]? status = null)
|
||||
public static async Task<InvoiceEntity[]> 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),
|
||||
@@ -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<ViewPointOfSaleViewModel.Item>();
|
||||
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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Plugins.Test.Services;
|
||||
|
||||
Reference in New Issue
Block a user