mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
Code formatting updates (#4502)
* Editorconfig: Add space_before_self_closing setting This was a difference between the way dotnet-format and Rider format code. See https://www.jetbrains.com/help/rider/EditorConfig_Index.html * Editorconfig: Keep 4 spaces indentation for Swagger JSON files They are all formatted that way, let's keep it like that. * Apply dotnet-format, mostly white-space related changes
This commit is contained in:
parent
3fa28bb46d
commit
d5d0be5824
@ -11,10 +11,14 @@ insert_final_newline = true
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
space_before_self_closing = true
|
||||||
|
|
||||||
[*.json]
|
[*.json]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[swagger*.json]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
# C# files
|
# C# files
|
||||||
[*.cs]
|
[*.cs]
|
||||||
# New line preferences
|
# New line preferences
|
||||||
@ -67,7 +71,7 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
|||||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
||||||
|
|
||||||
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
||||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||||
|
|
||||||
# Code style defaults
|
# Code style defaults
|
||||||
dotnet_sort_system_directives_first = true
|
dotnet_sort_system_directives_first = true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
namespace BTCPayServer.Abstractions.Contracts;
|
namespace BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
public interface IScopeProvider
|
public interface IScopeProvider
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Contracts;
|
namespace BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ public class AssetQuoteResult
|
|||||||
|
|
||||||
public AssetQuoteResult() { }
|
public AssetQuoteResult() { }
|
||||||
|
|
||||||
public AssetQuoteResult(string fromAsset, string toAsset,decimal bid, decimal ask)
|
public AssetQuoteResult(string fromAsset, string toAsset, decimal bid, decimal ask)
|
||||||
{
|
{
|
||||||
FromAsset = fromAsset;
|
FromAsset = fromAsset;
|
||||||
ToAsset = toAsset;
|
ToAsset = toAsset;
|
||||||
|
@ -2,10 +2,7 @@ namespace BTCPayServer.Abstractions.Custodians;
|
|||||||
|
|
||||||
public class AssetBalancesUnavailableException : CustodianApiException
|
public class AssetBalancesUnavailableException : CustodianApiException
|
||||||
{
|
{
|
||||||
|
|
||||||
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
public class CustodianApiException: Exception {
|
public class CustodianApiException : Exception
|
||||||
|
{
|
||||||
public int HttpStatus { get; }
|
public int HttpStatus { get; }
|
||||||
public string Code { get; }
|
public string Code { get; }
|
||||||
|
|
||||||
@ -9,7 +10,8 @@ public class CustodianApiException: Exception {
|
|||||||
HttpStatus = httpStatus;
|
HttpStatus = httpStatus;
|
||||||
Code = code;
|
Code = code;
|
||||||
}
|
}
|
||||||
public CustodianApiException( int httpStatus, string code, string message) : this(httpStatus, code, message, null)
|
|
||||||
|
public CustodianApiException(int httpStatus, string code, string message) : this(httpStatus, code, message, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class CustodianFeatureNotImplementedException: CustodianApiException
|
public class CustodianFeatureNotImplementedException : CustodianApiException
|
||||||
{
|
{
|
||||||
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class InsufficientFundsException : CustodianApiException
|
public class InsufficientFundsException : CustodianApiException
|
||||||
{
|
{
|
||||||
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ public class TradeNotFoundException : CustodianApiException
|
|||||||
{
|
{
|
||||||
private string tradeId { get; }
|
private string tradeId { get; }
|
||||||
|
|
||||||
public TradeNotFoundException(string tradeId) : base(404,"trade-not-found","Could not find trade ID " + tradeId)
|
public TradeNotFoundException(string tradeId) : base(404, "trade-not-found", "Could not find trade ID " + tradeId)
|
||||||
{
|
{
|
||||||
this.tradeId = tradeId;
|
this.tradeId = tradeId;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class WrongTradingPairException: CustodianApiException
|
public class WrongTradingPairException : CustodianApiException
|
||||||
{
|
{
|
||||||
public const int HttpCode = 404;
|
public const int HttpCode = 404;
|
||||||
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
|
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
|
||||||
|
@ -9,18 +9,16 @@ namespace BTCPayServer.Abstractions.Custodians;
|
|||||||
|
|
||||||
public interface ICanTrade
|
public interface ICanTrade
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
|
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
|
||||||
*/
|
*/
|
||||||
public List<AssetPairData> GetTradableAssetPairs();
|
public List<AssetPairData> GetTradableAssetPairs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a market order right now.
|
* Execute a market order right now.
|
||||||
*/
|
*/
|
||||||
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the details about a previous market trade.
|
* Get the details about a previous market trade.
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,7 @@ public interface ICustodian
|
|||||||
* Get the unique code that identifies this custodian.
|
* Get the unique code that identifies this custodian.
|
||||||
*/
|
*/
|
||||||
string Code { get; }
|
string Code { get; }
|
||||||
|
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,12 +30,12 @@ public static class GreenfieldExtensions
|
|||||||
{
|
{
|
||||||
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
||||||
{
|
{
|
||||||
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
||||||
{
|
{
|
||||||
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
||||||
|
@ -11,7 +11,7 @@ public static class HttpRequestExtensions
|
|||||||
return false;
|
return false;
|
||||||
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAbsoluteRoot(this HttpRequest request)
|
public static string GetAbsoluteRoot(this HttpRequest request)
|
||||||
{
|
{
|
||||||
return string.Concat(
|
return string.Concat(
|
||||||
|
@ -6,7 +6,6 @@ namespace BTCPayServer.Abstractions.Extensions;
|
|||||||
|
|
||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
{
|
{
|
||||||
|
|
||||||
public static bool IsValidFileName(this string fileName)
|
public static bool IsValidFileName(this string fileName)
|
||||||
{
|
{
|
||||||
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
||||||
@ -41,5 +40,4 @@ public static class StringExtensions
|
|||||||
return str.Substring(0, str.Length - 1);
|
return str.Substring(0, str.Length - 1);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
{
|
{
|
||||||
return IsActiveCategory(viewData, category.ToString(), id);
|
return IsActiveCategory(viewData, category.ToString(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
||||||
@ -77,7 +77,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
? ActivePageClass
|
? ActivePageClass
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
||||||
@ -126,7 +126,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
{
|
{
|
||||||
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
||||||
}
|
}
|
||||||
return timeSpan.Days < 1
|
return timeSpan.Days < 1
|
||||||
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
|
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
|
||||||
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,16 @@ public class AlertMessage
|
|||||||
Danger,
|
Danger,
|
||||||
Info
|
Info
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public AlertMessageType Type;
|
public AlertMessageType Type;
|
||||||
|
|
||||||
// The translated message to be shown to the user
|
// The translated message to be shown to the user
|
||||||
public string Message;
|
public string Message;
|
||||||
|
|
||||||
public AlertMessage()
|
public AlertMessage()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertMessage(AlertMessageType type, string message)
|
public AlertMessage(AlertMessageType type, string message)
|
||||||
|
@ -17,7 +17,7 @@ public class Field
|
|||||||
Label = label,
|
Label = label,
|
||||||
Name = name,
|
Name = name,
|
||||||
Value = value,
|
Value = value,
|
||||||
OriginalValue = value,
|
OriginalValue = value,
|
||||||
Required = required,
|
Required = required,
|
||||||
HelpText = helpText,
|
HelpText = helpText,
|
||||||
Type = type
|
Type = type
|
||||||
|
@ -22,10 +22,10 @@ public class Form
|
|||||||
#nullable restore
|
#nullable restore
|
||||||
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
|
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
|
||||||
public List<AlertMessage> TopMessages { get; set; } = new();
|
public List<AlertMessage> TopMessages { get; set; } = new();
|
||||||
|
|
||||||
// Groups of fields in the form
|
// Groups of fields in the form
|
||||||
public List<Field> Fields { get; set; } = new();
|
public List<Field> Fields { get; set; } = new();
|
||||||
|
|
||||||
// Are all the fields valid in the form?
|
// Are all the fields valid in the form?
|
||||||
public bool IsValid()
|
public bool IsValid()
|
||||||
{
|
{
|
||||||
@ -36,7 +36,7 @@ public class Form
|
|||||||
{
|
{
|
||||||
return GetFieldByName(name, Fields, null);
|
return GetFieldByName(name, Fields, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field GetFieldByName(string name, List<Field> fields, string prefix)
|
private static Field GetFieldByName(string name, List<Field> fields, string prefix)
|
||||||
{
|
{
|
||||||
prefix ??= string.Empty;
|
prefix ??= string.Empty;
|
||||||
@ -45,7 +45,7 @@ public class Form
|
|||||||
var currentPrefix = prefix;
|
var currentPrefix = prefix;
|
||||||
if (!string.IsNullOrEmpty(field.Name))
|
if (!string.IsNullOrEmpty(field.Name))
|
||||||
{
|
{
|
||||||
|
|
||||||
currentPrefix = $"{prefix}{field.Name}";
|
currentPrefix = $"{prefix}{field.Name}";
|
||||||
if (currentPrefix.Equals(name, StringComparison.InvariantCultureIgnoreCase))
|
if (currentPrefix.Equals(name, StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
@ -60,7 +60,7 @@ public class Form
|
|||||||
{
|
{
|
||||||
return subFieldResult;
|
return subFieldResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ public class Form
|
|||||||
private static List<string> GetAllNames(List<Field> fields)
|
private static List<string> GetAllNames(List<Field> fields)
|
||||||
{
|
{
|
||||||
var names = new List<string>();
|
var names = new List<string>();
|
||||||
|
|
||||||
foreach (var field in fields)
|
foreach (var field in fields)
|
||||||
{
|
{
|
||||||
string prefix = string.Empty;
|
string prefix = string.Empty;
|
||||||
@ -85,7 +85,7 @@ public class Form
|
|||||||
|
|
||||||
if (field.Fields.Any())
|
if (field.Fields.Any())
|
||||||
{
|
{
|
||||||
names.AddRange(GetAllNames(field.Fields).Select(s => $"{prefix}{s}" ));
|
names.AddRange(GetAllNames(field.Fields).Select(s => $"{prefix}{s}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ public class Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyValuesFromForm(IFormCollection form)
|
public void ApplyValuesFromForm(IFormCollection form)
|
||||||
{
|
{
|
||||||
var names = GetAllNames();
|
var names = GetAllNames();
|
||||||
@ -125,7 +125,7 @@ public class Form
|
|||||||
{
|
{
|
||||||
return GetValues(Fields);
|
return GetValues(Fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, object> GetValues(List<Field> fields)
|
private static Dictionary<string, object> GetValues(List<Field> fields)
|
||||||
{
|
{
|
||||||
var result = new Dictionary<string, object>();
|
var result = new Dictionary<string, object>();
|
||||||
@ -136,11 +136,12 @@ public class Form
|
|||||||
{
|
{
|
||||||
var values = GetValues(fields);
|
var values = GetValues(fields);
|
||||||
values.Remove(string.Empty, out var keylessValue);
|
values.Remove(string.Empty, out var keylessValue);
|
||||||
|
|
||||||
result.TryAdd(name, values);
|
result.TryAdd(name, values);
|
||||||
|
|
||||||
if (keylessValue is not Dictionary<string, object> dict) continue;
|
if (keylessValue is not Dictionary<string, object> dict)
|
||||||
foreach (KeyValuePair<string,object> keyValuePair in dict)
|
continue;
|
||||||
|
foreach (KeyValuePair<string, object> keyValuePair in dict)
|
||||||
{
|
{
|
||||||
result.TryAdd(keyValuePair.Key, keyValuePair.Value);
|
result.TryAdd(keyValuePair.Key, keyValuePair.Value);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ public class AuthorizationFilterHandle
|
|||||||
public AuthorizationHandlerContext Context { get; }
|
public AuthorizationHandlerContext Context { get; }
|
||||||
public PolicyRequirement Requirement { get; }
|
public PolicyRequirement Requirement { get; }
|
||||||
public HttpContext HttpContext { get; }
|
public HttpContext HttpContext { get; }
|
||||||
public bool Success { get; private set; }
|
public bool Success { get; private set; }
|
||||||
|
|
||||||
public AuthorizationFilterHandle(
|
public AuthorizationFilterHandle(
|
||||||
AuthorizationHandlerContext context,
|
AuthorizationHandlerContext context,
|
||||||
|
@ -29,5 +29,5 @@ public class SVGUse : UrlResolutionTagHelper2
|
|||||||
attr = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, attr);
|
attr = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, attr);
|
||||||
output.Attributes.SetAttribute("href", attr);
|
output.Attributes.SetAttribute("href", attr);
|
||||||
base.Process(context, output);
|
base.Process(context, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Post), token);
|
method: HttpMethod.Post), token);
|
||||||
return await HandleResponse<PointOfSaleAppData>(response);
|
return await HandleResponse<PointOfSaleAppData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||||
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ namespace BTCPayServer.Client
|
|||||||
|
|
||||||
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
|
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
|
||||||
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
||||||
//return await HandleResponse<ApplicationUserData>(response);
|
//return await HandleResponse<ApplicationUserData>(response);
|
||||||
var internalRequest = CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", null,
|
var internalRequest = CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", null,
|
||||||
@ -81,8 +81,8 @@ namespace BTCPayServer.Client
|
|||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
|
||||||
return await HandleResponse<TradeQuoteResponseData>(response);
|
return await HandleResponse<TradeQuoteResponseData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<WithdrawalResponseData> CreateWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
public virtual async Task<WithdrawalResponseData> CreateWithdrawal(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);
|
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);
|
return await HandleResponse<WithdrawalResponseData>(response);
|
||||||
|
@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningNodeInformationData>(response);
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningInvoiceData>(response);
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningNodeInformationData>(response);
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningInvoiceData>(response);
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace BTCPayServer.Client
|
|||||||
parameters.Add("includeNeighbourData", v);
|
parameters.Add("includeNeighbourData", v);
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method:HttpMethod.Get), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<OnChainWalletObjectData[]>(response);
|
return await HandleResponse<OnChainWalletObjectData[]>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||||
@ -47,7 +47,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method:HttpMethod.Delete), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method: HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||||
@ -55,7 +55,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method:HttpMethod.Post, bodyPayload: request), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method: HttpMethod.Post, bodyPayload: request), token);
|
||||||
return await HandleResponse<OnChainWalletObjectData>(response);
|
return await HandleResponse<OnChainWalletObjectData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||||
@ -65,7 +65,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method:HttpMethod.Post, bodyPayload: request), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method: HttpMethod.Post, bodyPayload: request), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||||
@ -75,7 +75,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method:HttpMethod.Delete), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method: HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
query.Add(nameof(statusFilter), statusFilter);
|
query.Add(nameof(statusFilter), statusFilter);
|
||||||
}
|
}
|
||||||
if (labelFilter != null) {
|
if (labelFilter != null)
|
||||||
|
{
|
||||||
query.Add(nameof(labelFilter), labelFilter);
|
query.Add(nameof(labelFilter), labelFilter);
|
||||||
}
|
}
|
||||||
var response =
|
var response =
|
||||||
|
@ -52,17 +52,17 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||||
|
@ -9,7 +9,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
public partial class BTCPayServerClient
|
public partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
||||||
@ -20,28 +20,28 @@ namespace BTCPayServer.Client
|
|||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod,LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}",null, request, HttpMethod.Put ), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod,OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}",null, request, HttpMethod.Put ), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
using var response = await _httpClient.SendAsync(
|
using var response = await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
|
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
|
||||||
queryPayload: new Dictionary<string, object>() {{"currencyPair", currencyPair}},
|
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||||
method: HttpMethod.Post),
|
method: HttpMethod.Post),
|
||||||
token);
|
token);
|
||||||
return await HandleResponse<List<StoreRatePreviewResult>>(response);
|
return await HandleResponse<List<StoreRatePreviewResult>>(response);
|
||||||
|
@ -36,12 +36,12 @@ namespace BTCPayServer.Client
|
|||||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
||||||
new LockUserRequest {Locked = locked}, HttpMethod.Post), token);
|
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
return response.IsSuccessStatusCode;
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData[]> GetUsers( CancellationToken token = default)
|
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
||||||
return await HandleResponse<ApplicationUserData[]>(response);
|
return await HandleResponse<ApplicationUserData[]>(response);
|
||||||
|
@ -8,7 +8,7 @@ public class AssetPairData
|
|||||||
public AssetPairData()
|
public AssetPairData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
|
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
|
||||||
{
|
{
|
||||||
AssetBought = assetBought;
|
AssetBought = assetBought;
|
||||||
@ -25,7 +25,7 @@ public class AssetPairData
|
|||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public decimal MinimumTradeQty { set; get; }
|
public decimal MinimumTradeQty { set; get; }
|
||||||
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return AssetBought + "/" + AssetSold;
|
return AssetBought + "/" + AssetSold;
|
||||||
|
@ -11,14 +11,14 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
|
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
|
||||||
{
|
{
|
||||||
Amount = amount;
|
Amount = amount;
|
||||||
Description = description;
|
Description = description;
|
||||||
Expiry = expiry;
|
Expiry = expiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.LightMoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.LightMoneyJsonConverter))]
|
||||||
public LightMoney Amount { get; set; }
|
public LightMoney Amount { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
@ -5,11 +5,11 @@ namespace BTCPayServer.Client.Models
|
|||||||
public abstract class CustodianAccountBaseData
|
public abstract class CustodianAccountBaseData
|
||||||
{
|
{
|
||||||
public string CustodianCode { get; set; }
|
public string CustodianCode { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
public string StoreId { get; set; }
|
public string StoreId { get; set; }
|
||||||
|
|
||||||
public JObject Config { get; set; }
|
public JObject Config { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class CustodianAccountResponse: CustodianAccountData
|
public class CustodianAccountResponse : CustodianAccountData
|
||||||
{
|
{
|
||||||
public IDictionary<string, decimal> AssetBalances { get; set; }
|
public IDictionary<string, decimal> AssetBalances { get; set; }
|
||||||
|
|
||||||
public CustodianAccountResponse()
|
public CustodianAccountResponse()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ public class CustodianData
|
|||||||
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
|
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
|
||||||
public string[] WithdrawablePaymentMethods { get; set; }
|
public string[] WithdrawablePaymentMethods { get; set; }
|
||||||
public string[] DepositablePaymentMethods { get; set; }
|
public string[] DepositablePaymentMethods { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ public class DepositAddressData
|
|||||||
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
|
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
|
||||||
// */
|
// */
|
||||||
// public string Type { get; set; }
|
// public string Type { get; set; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format depends hugely on the type.
|
* Format depends hugely on the type.
|
||||||
*/
|
*/
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using BTCPayServer.Client.JsonConverters;
|
using BTCPayServer.Client.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models;
|
|||||||
public class LightningAutomatedPayoutSettings
|
public class LightningAutomatedPayoutSettings
|
||||||
{
|
{
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
public TimeSpan IntervalSeconds { get; set; }
|
public TimeSpan IntervalSeconds { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonProperty("onchain")]
|
[JsonProperty("onchain")]
|
||||||
public OnchainBalanceData OnchainBalance { get; set; }
|
public OnchainBalanceData OnchainBalance { get; set; }
|
||||||
|
|
||||||
[JsonProperty("offchain")]
|
[JsonProperty("offchain")]
|
||||||
public OffchainBalanceData OffchainBalance { get; set; }
|
public OffchainBalanceData OffchainBalance { get; set; }
|
||||||
|
|
||||||
public LightningNodeBalanceData()
|
public LightningNodeBalanceData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||||
public Money Unconfirmed { get; set; }
|
public Money Unconfirmed { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||||
public Money Reserved { get; set; }
|
public Money Reserved { get; set; }
|
||||||
}
|
}
|
||||||
@ -40,13 +40,13 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Opening { get; set; }
|
public LightMoney Opening { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Local { get; set; }
|
public LightMoney Local { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Remote { get; set; }
|
public LightMoney Remote { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Closing { get; set; }
|
public LightMoney Closing { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ namespace BTCPayServer.Client.Models
|
|||||||
|
|
||||||
[JsonProperty("BOLT11")]
|
[JsonProperty("BOLT11")]
|
||||||
public string BOLT11 { get; set; }
|
public string BOLT11 { get; set; }
|
||||||
|
|
||||||
public string Preimage { get; set; }
|
public string Preimage { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset? CreatedAt { get; set; }
|
public DateTimeOffset? CreatedAt { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney TotalAmount { get; set; }
|
public LightMoney TotalAmount { get; set; }
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client;
|
||||||
|
|
||||||
public class LockUserRequest
|
public class LockUserRequest
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ public class MarketTradeResponseData
|
|||||||
public string TradeId { get; }
|
public string TradeId { get; }
|
||||||
|
|
||||||
public string AccountId { get; }
|
public string AccountId { get; }
|
||||||
|
|
||||||
public string CustodianCode { get; }
|
public string CustodianCode { get; }
|
||||||
|
|
||||||
public MarketTradeResponseData(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId, string accountId, string custodianCode)
|
public MarketTradeResponseData(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId, string accountId, string custodianCode)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using BTCPayServer.Client.JsonConverters;
|
using BTCPayServer.Client.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -7,9 +7,9 @@ namespace BTCPayServer.Client.Models;
|
|||||||
public class OnChainAutomatedPayoutSettings
|
public class OnChainAutomatedPayoutSettings
|
||||||
{
|
{
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
public TimeSpan IntervalSeconds { get; set; }
|
public TimeSpan IntervalSeconds { get; set; }
|
||||||
|
|
||||||
public int? FeeBlockTarget { get; set; }
|
public int? FeeBlockTarget { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,13 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonProperty("BOLT11")]
|
[JsonProperty("BOLT11")]
|
||||||
public string BOLT11 { get; set; }
|
public string BOLT11 { get; set; }
|
||||||
|
|
||||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||||
public float? MaxFeePercent { get; set; }
|
public float? MaxFeePercent { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||||
public Money MaxFeeFlat { get; set; }
|
public Money MaxFeeFlat { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Amount { get; set; }
|
public LightMoney Amount { get; set; }
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PointOfSaleAppData : AppDataBase
|
public class PointOfSaleAppData : AppDataBase
|
||||||
{
|
{
|
||||||
// We can add POS specific things here later
|
// We can add POS specific things here later
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class RateSource
|
public class RateSource
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
|
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
|
||||||
|
|
||||||
public bool PayJoinEnabled { get; set; }
|
public bool PayJoinEnabled { get; set; }
|
||||||
|
|
||||||
public InvoiceData.ReceiptOptions Receipt { get; set; }
|
public InvoiceData.ReceiptOptions Receipt { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StoreUserData
|
public class StoreUserData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
@ -7,4 +7,4 @@ public class StoreRatePreviewResult
|
|||||||
public string CurrencyPair { get; set; }
|
public string CurrencyPair { get; set; }
|
||||||
public decimal? Rate { get; set; }
|
public decimal? Rate { get; set; }
|
||||||
public List<string> Errors { get; set; }
|
public List<string> Errors { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class StoreRateResult
|
public class StoreRateResult
|
||||||
{
|
{
|
||||||
public string CurrencyPair { get; set; }
|
public string CurrencyPair { get; set; }
|
||||||
public decimal Rate { get; set; }
|
public decimal Rate { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace BTCPayServer
|
|||||||
internal Task ProcessTask;
|
internal Task ProcessTask;
|
||||||
public async Task Process(CancellationToken cancellationToken)
|
public async Task Process(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
while (Chan.Reader.TryRead(out var item))
|
while (Chan.Reader.TryRead(out var item))
|
||||||
{
|
{
|
||||||
await item(cancellationToken);
|
await item(cancellationToken);
|
||||||
@ -52,7 +52,7 @@ namespace BTCPayServer
|
|||||||
{
|
{
|
||||||
lock (_Queues)
|
lock (_Queues)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
if (stopped)
|
if (stopped)
|
||||||
return;
|
return;
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
@ -67,7 +67,7 @@ namespace BTCPayServer.Data
|
|||||||
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
||||||
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
|
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
|
||||||
public DbSet<WebhookData> Webhooks { get; set; }
|
public DbSet<WebhookData> Webhooks { get; set; }
|
||||||
public DbSet<LightningAddressData> LightningAddresses{ get; set; }
|
public DbSet<LightningAddressData> LightningAddresses { get; set; }
|
||||||
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
|
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
@ -14,28 +14,28 @@ public class CustodianAccountData
|
|||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string StoreId { get; set; }
|
public string StoreId { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string CustodianCode { get; set; }
|
public string CustodianCode { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public StoreData StoreData { get; set; }
|
public StoreData StoreData { get; set; }
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Entity<CustodianAccountData>()
|
builder.Entity<CustodianAccountData>()
|
||||||
.HasOne(o => o.StoreData)
|
.HasOne(o => o.StoreData)
|
||||||
.WithMany(i => i.CustodianAccounts)
|
.WithMany(i => i.CustodianAccounts)
|
||||||
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
builder.Entity<APIKeyData>()
|
builder.Entity<APIKeyData>()
|
||||||
.HasIndex(o => o.StoreId);
|
.HasIndex(o => o.StoreId);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace BTCPayServer.Data;
|
namespace BTCPayServer.Data;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace BTCPayServer.Data.Data;
|
namespace BTCPayServer.Data.Data;
|
||||||
@ -11,9 +11,9 @@ public class PayoutProcessorData
|
|||||||
public StoreData Store { get; set; }
|
public StoreData Store { get; set; }
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
public string Processor { get; set; }
|
public string Processor { get; set; }
|
||||||
|
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public class StoreSettingData
|
|||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
|
|
||||||
public StoreData Store { get; set; }
|
public StoreData Store { get; set; }
|
||||||
|
|
||||||
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<StoreSettingData>().HasKey(data => new { data.StoreId, data.Name });
|
builder.Entity<StoreSettingData>().HasKey(data => new { data.StoreId, data.Name });
|
||||||
|
@ -2,5 +2,5 @@ namespace BTCPayServer.Data;
|
|||||||
|
|
||||||
public class TradeResultData
|
public class TradeResultData
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ namespace BTCPayServer.PluginPacker
|
|||||||
|
|
||||||
var sha256sums = new StringBuilder();
|
var sha256sums = new StringBuilder();
|
||||||
sha256sums.AppendLine(
|
sha256sums.AppendLine(
|
||||||
$"{Encoders.Hex.EncodeData(Hashes.SHA256(Encoding.UTF8.GetBytes(json)))} {name}.btcpay.json");
|
$"{Encoders.Hex.EncodeData(Hashes.SHA256(Encoding.UTF8.GetBytes(json)))} {name}.btcpay.json");
|
||||||
|
|
||||||
sha256sums.AppendLine(
|
sha256sums.AppendLine(
|
||||||
$"{Encoders.Hex.EncodeData(Hashes.SHA256(await File.ReadAllBytesAsync(outputFile + ".btcpay")))} {name}.btcpay");
|
$"{Encoders.Hex.EncodeData(Hashes.SHA256(await File.ReadAllBytesAsync(outputFile + ".btcpay")))} {name}.btcpay");
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ namespace BTCPayServer.PluginPacker
|
|||||||
File.Delete(sha256dirs);
|
File.Delete(sha256dirs);
|
||||||
}
|
}
|
||||||
await File.WriteAllTextAsync(sha256dirs, sha256sums.ToString());
|
await File.WriteAllTextAsync(sha256dirs, sha256sums.ToString());
|
||||||
|
|
||||||
// try Windows executable first, fall back to macOS/Linux PowerShell
|
// try Windows executable first, fall back to macOS/Linux PowerShell
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -86,7 +86,7 @@ namespace BTCPayServer.PluginPacker
|
|||||||
$"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{ex.Message}");
|
$"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Created {outputFile}.btcpay at {directory}");
|
Console.WriteLine($"Created {outputFile}.btcpay at {directory}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ namespace BTCPayServer.Rating
|
|||||||
Url = url;
|
Url = url;
|
||||||
Source = source;
|
Source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DisplayName =>
|
public string DisplayName =>
|
||||||
Source switch
|
Source switch
|
||||||
{
|
{
|
||||||
RateSource.Direct => Name,
|
RateSource.Direct => Name,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Rating;
|
using BTCPayServer.Rating;
|
||||||
|
@ -23,7 +23,7 @@ namespace BTCPayServer.Services.Rates
|
|||||||
{
|
{
|
||||||
await new SynchronizationContextRemover();
|
await new SynchronizationContextRemover();
|
||||||
|
|
||||||
var exchangeAPI = (T) await ExchangeAPI.GetExchangeAPIAsync<T>();
|
var exchangeAPI = (T)await ExchangeAPI.GetExchangeAPIAsync<T>();
|
||||||
exchangeAPI.RequestMaker = new HttpClientRequestMaker(exchangeAPI, _httpClient, cancellationToken);
|
exchangeAPI.RequestMaker = new HttpClientRequestMaker(exchangeAPI, _httpClient, cancellationToken);
|
||||||
var rates = await exchangeAPI.GetTickersAsync();
|
var rates = await exchangeAPI.GetTickersAsync();
|
||||||
|
|
||||||
|
@ -177,11 +177,11 @@ namespace BTCPayServer.Services.Rates
|
|||||||
var result = JsonConvert.DeserializeObject<T>(stringResult);
|
var result = JsonConvert.DeserializeObject<T>(stringResult);
|
||||||
if (result is JToken json)
|
if (result is JToken json)
|
||||||
{
|
{
|
||||||
if (!(json is JArray) && json["result"] is JObject {Count: > 0} pairResult)
|
if (!(json is JArray) && json["result"] is JObject { Count: > 0 } pairResult)
|
||||||
{
|
{
|
||||||
return (T)(object)(pairResult);
|
return (T)(object)(pairResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(json is JArray) && json["error"] is JArray error && error.Count != 0)
|
if (!(json is JArray) && json["error"] is JArray error && error.Count != 0)
|
||||||
{
|
{
|
||||||
throw new APIException(string.Join("\n",
|
throw new APIException(string.Join("\n",
|
||||||
|
@ -7,8 +7,8 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Rating;
|
using BTCPayServer.Rating;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Rates
|
namespace BTCPayServer.Services.Rates
|
||||||
{
|
{
|
||||||
|
@ -58,14 +58,14 @@ namespace BTCPayServer.Tests
|
|||||||
s.GoToProfile(ManageNavPages.APIKeys);
|
s.GoToProfile(ManageNavPages.APIKeys);
|
||||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||||
Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
|
Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
|
||||||
|
|
||||||
//server management should show now
|
//server management should show now
|
||||||
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
|
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
|
||||||
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
||||||
s.Driver.SetCheckbox(By.Id("btcpay.user.canviewprofile"), true);
|
s.Driver.SetCheckbox(By.Id("btcpay.user.canviewprofile"), true);
|
||||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||||
var superApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
var superApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||||
|
|
||||||
//this api key has access to everything
|
//this api key has access to everything
|
||||||
await TestApiAgainstAccessToken(superApiKey, tester, user, Policies.CanModifyServerSettings, Policies.CanModifyStoreSettings, Policies.CanViewProfile);
|
await TestApiAgainstAccessToken(superApiKey, tester, user, Policies.CanModifyServerSettings, Policies.CanModifyStoreSettings, Policies.CanViewProfile);
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ namespace BTCPayServer.Tests
|
|||||||
var serverOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
var serverOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||||
await TestApiAgainstAccessToken(serverOnlyApiKey, tester, user,
|
await TestApiAgainstAccessToken(serverOnlyApiKey, tester, user,
|
||||||
Policies.CanModifyServerSettings);
|
Policies.CanModifyServerSettings);
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||||
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
||||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||||
@ -108,7 +108,7 @@ namespace BTCPayServer.Tests
|
|||||||
await TestApiAgainstAccessToken<bool>("incorrect key", $"{TestApiPath}/me/id",
|
await TestApiAgainstAccessToken<bool>("incorrect key", $"{TestApiPath}/me/id",
|
||||||
tester.PayTester.HttpClient);
|
tester.PayTester.HttpClient);
|
||||||
});
|
});
|
||||||
|
|
||||||
TestLogs.LogInformation("Checking authorize screen");
|
TestLogs.LogInformation("Checking authorize screen");
|
||||||
|
|
||||||
//let's test the authorized screen now
|
//let's test the authorized screen now
|
||||||
@ -124,35 +124,35 @@ namespace BTCPayServer.Tests
|
|||||||
var callbackUrl = s.ServerUri + "postredirect-callback-test";
|
var callbackUrl = s.ServerUri + "postredirect-callback-test";
|
||||||
var authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
var authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
||||||
new[] { Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
new[] { Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
||||||
|
|
||||||
// No upfront store selection with only server settings
|
// No upfront store selection with only server settings
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
Assert.Contains(appidentifier, s.Driver.PageSource);
|
Assert.Contains(appidentifier, s.Driver.PageSource);
|
||||||
Assert.True(s.Driver.ElementDoesNotExist(By.CssSelector("select#StoreId")));
|
Assert.True(s.Driver.ElementDoesNotExist(By.CssSelector("select#StoreId")));
|
||||||
|
|
||||||
// No upfront store selection with selectiveStores being false
|
// No upfront store selection with selectiveStores being false
|
||||||
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
||||||
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, selectiveStores: false, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, selectiveStores: false, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
Assert.True(s.Driver.ElementDoesNotExist(By.CssSelector("select#StoreId")));
|
Assert.True(s.Driver.ElementDoesNotExist(By.CssSelector("select#StoreId")));
|
||||||
|
|
||||||
// Now with store settings
|
// Now with store settings
|
||||||
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
|
||||||
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, selectiveStores: true, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, selectiveStores: true, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
Assert.Contains(appidentifier, s.Driver.PageSource);
|
Assert.Contains(appidentifier, s.Driver.PageSource);
|
||||||
|
|
||||||
// Select a store
|
// Select a store
|
||||||
var select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
var select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
||||||
select.SelectByIndex(0);
|
select.SelectByIndex(0);
|
||||||
s.Driver.FindElement(By.Id("continue")).Click();
|
s.Driver.FindElement(By.Id("continue")).Click();
|
||||||
|
|
||||||
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
|
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant());
|
||||||
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
|
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant());
|
||||||
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
|
Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant());
|
||||||
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
|
Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant());
|
||||||
Assert.DoesNotContain("change-store-mode", s.Driver.PageSource);
|
Assert.DoesNotContain("change-store-mode", s.Driver.PageSource);
|
||||||
|
|
||||||
s.Driver.WaitForAndClick(By.Id("consent-yes"));
|
s.Driver.WaitForAndClick(By.Id("consent-yes"));
|
||||||
Assert.Equal(callbackUrl, s.Driver.Url);
|
Assert.Equal(callbackUrl, s.Driver.Url);
|
||||||
|
|
||||||
@ -192,12 +192,12 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
//if it's the same, go to the confirm page
|
//if it's the same, go to the confirm page
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
|
|
||||||
// Select the same store
|
// Select the same store
|
||||||
select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
||||||
select.SelectByIndex(0);
|
select.SelectByIndex(0);
|
||||||
s.Driver.FindElement(By.Id("continue")).Click();
|
s.Driver.FindElement(By.Id("continue")).Click();
|
||||||
|
|
||||||
Assert.Contains("previously generated the API Key", s.Driver.PageSource);
|
Assert.Contains("previously generated the API Key", s.Driver.PageSource);
|
||||||
s.Driver.WaitForAndClick(By.Id("continue"));
|
s.Driver.WaitForAndClick(By.Id("continue"));
|
||||||
Assert.Equal(callbackUrl, s.Driver.Url);
|
Assert.Equal(callbackUrl, s.Driver.Url);
|
||||||
@ -207,12 +207,12 @@ namespace BTCPayServer.Tests
|
|||||||
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri("https://international.local/callback"))).ToString();
|
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri("https://international.local/callback"))).ToString();
|
||||||
|
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
|
|
||||||
// Select the same store
|
// Select the same store
|
||||||
select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
select = new SelectElement(s.Driver.FindElement(By.Id("StoreId")));
|
||||||
select.SelectByIndex(0);
|
select.SelectByIndex(0);
|
||||||
s.Driver.FindElement(By.Id("continue")).Click();
|
s.Driver.FindElement(By.Id("continue")).Click();
|
||||||
|
|
||||||
Assert.DoesNotContain("previously generated the API Key", s.Driver.PageSource);
|
Assert.DoesNotContain("previously generated the API Key", s.Driver.PageSource);
|
||||||
Assert.False(s.Driver.Url.StartsWith("https://international.com/callback"));
|
Assert.False(s.Driver.Url.StartsWith("https://international.com/callback"));
|
||||||
|
|
||||||
@ -230,11 +230,11 @@ namespace BTCPayServer.Tests
|
|||||||
TestLogs.LogInformation("Generating API key");
|
TestLogs.LogInformation("Generating API key");
|
||||||
s.Driver.WaitForAndClick(By.Id("Generate"));
|
s.Driver.WaitForAndClick(By.Id("Generate"));
|
||||||
var allAPIKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
var allAPIKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||||
|
|
||||||
TestLogs.LogInformation($"Checking API key permissions: {allAPIKey}");
|
TestLogs.LogInformation($"Checking API key permissions: {allAPIKey}");
|
||||||
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(allAPIKey, "api/v1/api-keys/current", tester.PayTester.HttpClient);
|
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(allAPIKey, "api/v1/api-keys/current", tester.PayTester.HttpClient);
|
||||||
Assert.Equal(checkedPermissionCount, apikeydata.Permissions.Length);
|
Assert.Equal(checkedPermissionCount, apikeydata.Permissions.Length);
|
||||||
|
|
||||||
TestLogs.LogInformation("Checking empty permissions");
|
TestLogs.LogInformation("Checking empty permissions");
|
||||||
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, Array.Empty<string>(), false, true).ToString();
|
authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, Array.Empty<string>(), false, true).ToString();
|
||||||
s.GoToUrl(authUrl);
|
s.GoToUrl(authUrl);
|
||||||
@ -279,10 +279,10 @@ namespace BTCPayServer.Tests
|
|||||||
var canModifyServer = Permission.Create(Policies.CanModifyServerSettings);
|
var canModifyServer = Permission.Create(Policies.CanModifyServerSettings);
|
||||||
var unrestricted = Permission.Create(Policies.Unrestricted);
|
var unrestricted = Permission.Create(Policies.Unrestricted);
|
||||||
var selectiveStorePermissions = permissions.Where(p => p.Scope != null && p.Policy == Policies.CanModifyStoreSettings);
|
var selectiveStorePermissions = permissions.Where(p => p.Scope != null && p.Policy == Policies.CanModifyStoreSettings);
|
||||||
|
|
||||||
TestLogs.LogInformation("Testing can edit store for first user");
|
TestLogs.LogInformation("Testing can edit store for first user");
|
||||||
IEnumerable<Permission> storePermissions = selectiveStorePermissions as Permission[] ?? selectiveStorePermissions.ToArray();
|
IEnumerable<Permission> storePermissions = selectiveStorePermissions as Permission[] ?? selectiveStorePermissions.ToArray();
|
||||||
|
|
||||||
if (permissions.Contains(canModifyAllStores) || storePermissions.Any())
|
if (permissions.Contains(canModifyAllStores) || storePermissions.Any())
|
||||||
{
|
{
|
||||||
var resultStores =
|
var resultStores =
|
||||||
|
@ -16,11 +16,11 @@ namespace BTCPayServer.Tests
|
|||||||
public class CheckoutV2Tests : UnitTestBase
|
public class CheckoutV2Tests : UnitTestBase
|
||||||
{
|
{
|
||||||
private const int TestTimeout = TestUtils.TestTimeout;
|
private const int TestTimeout = TestUtils.TestTimeout;
|
||||||
|
|
||||||
public CheckoutV2Tests(ITestOutputHelper helper) : base(helper)
|
public CheckoutV2Tests(ITestOutputHelper helper) : base(helper)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
[Trait("Lightning", "Lightning")]
|
[Trait("Lightning", "Lightning")]
|
||||||
public async Task CanConfigureCheckout()
|
public async Task CanConfigureCheckout()
|
||||||
@ -41,20 +41,20 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("StoreWebsite")).SendKeys(storeUrl);
|
s.Driver.FindElement(By.Id("StoreWebsite")).SendKeys(storeUrl);
|
||||||
s.Driver.FindElement(By.Id("Save")).Click();
|
s.Driver.FindElement(By.Id("Save")).Click();
|
||||||
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
||||||
|
|
||||||
// Default payment method
|
// Default payment method
|
||||||
var invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
var invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
||||||
s.GoToInvoiceCheckout(invoiceId);
|
s.GoToInvoiceCheckout(invoiceId);
|
||||||
|
|
||||||
// Ensure we are seeing Checkout v2
|
// Ensure we are seeing Checkout v2
|
||||||
s.Driver.WaitUntilAvailable(By.Id("Checkout-v2"));
|
s.Driver.WaitUntilAvailable(By.Id("Checkout-v2"));
|
||||||
|
|
||||||
Assert.Equal(2, s.Driver.FindElements(By.CssSelector(".payment-method")).Count);
|
Assert.Equal(2, s.Driver.FindElements(By.CssSelector(".payment-method")).Count);
|
||||||
Assert.Contains("Lightning", s.Driver.WaitForElement(By.CssSelector(".payment-method.active")).Text);
|
Assert.Contains("Lightning", s.Driver.WaitForElement(By.CssSelector(".payment-method.active")).Text);
|
||||||
Assert.DoesNotContain("LNURL", s.Driver.PageSource);
|
Assert.DoesNotContain("LNURL", s.Driver.PageSource);
|
||||||
var payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
var payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
||||||
Assert.StartsWith("lightning:", payUrl);
|
Assert.StartsWith("lightning:", payUrl);
|
||||||
|
|
||||||
// Lightning amount in Sats
|
// Lightning amount in Sats
|
||||||
Assert.Contains("BTC", s.Driver.FindElement(By.Id("AmountDue")).Text);
|
Assert.Contains("BTC", s.Driver.FindElement(By.Id("AmountDue")).Text);
|
||||||
s.GoToHome();
|
s.GoToHome();
|
||||||
@ -64,7 +64,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("BTC Lightning settings successfully updated", s.FindAlertMessage().Text);
|
Assert.Contains("BTC Lightning settings successfully updated", s.FindAlertMessage().Text);
|
||||||
s.GoToInvoiceCheckout(invoiceId);
|
s.GoToInvoiceCheckout(invoiceId);
|
||||||
Assert.Contains("Sats", s.Driver.FindElement(By.Id("AmountDue")).Text);
|
Assert.Contains("Sats", s.Driver.FindElement(By.Id("AmountDue")).Text);
|
||||||
|
|
||||||
// Expire
|
// Expire
|
||||||
var expirySeconds = s.Driver.FindElement(By.Id("ExpirySeconds"));
|
var expirySeconds = s.Driver.FindElement(By.Id("ExpirySeconds"));
|
||||||
expirySeconds.Clear();
|
expirySeconds.Clear();
|
||||||
@ -82,12 +82,12 @@ namespace BTCPayServer.Tests
|
|||||||
});
|
});
|
||||||
Assert.True(s.Driver.ElementDoesNotExist(By.Id("ReceiptLink")));
|
Assert.True(s.Driver.ElementDoesNotExist(By.Id("ReceiptLink")));
|
||||||
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));
|
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));
|
||||||
|
|
||||||
// Test payment
|
// Test payment
|
||||||
s.GoToHome();
|
s.GoToHome();
|
||||||
invoiceId = s.CreateInvoice();
|
invoiceId = s.CreateInvoice();
|
||||||
s.GoToInvoiceCheckout(invoiceId);
|
s.GoToInvoiceCheckout(invoiceId);
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
s.Driver.ToggleCollapse("PaymentDetails");
|
s.Driver.ToggleCollapse("PaymentDetails");
|
||||||
var details = s.Driver.FindElement(By.CssSelector(".payment-details"));
|
var details = s.Driver.FindElement(By.CssSelector(".payment-details"));
|
||||||
@ -96,7 +96,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("Exchange Rate", details.Text);
|
Assert.Contains("Exchange Rate", details.Text);
|
||||||
Assert.Contains("Amount Due", details.Text);
|
Assert.Contains("Amount Due", details.Text);
|
||||||
Assert.Contains("Recommended Fee", details.Text);
|
Assert.Contains("Recommended Fee", details.Text);
|
||||||
|
|
||||||
// Pay partial amount
|
// Pay partial amount
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
var address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-destination");
|
var address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-destination");
|
||||||
@ -104,7 +104,7 @@ namespace BTCPayServer.Tests
|
|||||||
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(address, Network.RegTest),
|
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(address, Network.RegTest),
|
||||||
Money.Parse(amountFraction));
|
Money.Parse(amountFraction));
|
||||||
await s.Server.ExplorerNode.GenerateAsync(1);
|
await s.Server.ExplorerNode.GenerateAsync(1);
|
||||||
|
|
||||||
// Fake Pay
|
// Fake Pay
|
||||||
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountFraction);
|
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountFraction);
|
||||||
s.Driver.FindElement(By.Id("FakePay")).Click();
|
s.Driver.FindElement(By.Id("FakePay")).Click();
|
||||||
@ -125,7 +125,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("Mined 1 block",
|
Assert.Contains("Mined 1 block",
|
||||||
s.Driver.WaitForElement(By.Id("CheatSuccessMessage")).Text);
|
s.Driver.WaitForElement(By.Id("CheatSuccessMessage")).Text);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pay full amount
|
// Pay full amount
|
||||||
var amountDue = s.Driver.FindElement(By.Id("AmountDue")).GetAttribute("data-amount-due");
|
var amountDue = s.Driver.FindElement(By.Id("AmountDue")).GetAttribute("data-amount-due");
|
||||||
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountDue);
|
s.Driver.FindElement(By.Id("FakePayAmount")).FillIn(amountDue);
|
||||||
@ -139,21 +139,21 @@ namespace BTCPayServer.Tests
|
|||||||
});
|
});
|
||||||
s.Driver.FindElement(By.Id("ReceiptLink"));
|
s.Driver.FindElement(By.Id("ReceiptLink"));
|
||||||
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));
|
Assert.Equal(storeUrl, s.Driver.FindElement(By.Id("StoreLink")).GetAttribute("href"));
|
||||||
|
|
||||||
// BIP21
|
// BIP21
|
||||||
s.GoToHome();
|
s.GoToHome();
|
||||||
s.GoToStore(StoreNavPages.CheckoutAppearance);
|
s.GoToStore(StoreNavPages.CheckoutAppearance);
|
||||||
s.Driver.SetCheckbox(By.Id("OnChainWithLnInvoiceFallback"), true);
|
s.Driver.SetCheckbox(By.Id("OnChainWithLnInvoiceFallback"), true);
|
||||||
s.Driver.FindElement(By.Id("Save")).Click();
|
s.Driver.FindElement(By.Id("Save")).Click();
|
||||||
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
Assert.Contains("Store successfully updated", s.FindAlertMessage().Text);
|
||||||
|
|
||||||
invoiceId = s.CreateInvoice();
|
invoiceId = s.CreateInvoice();
|
||||||
s.GoToInvoiceCheckout(invoiceId);
|
s.GoToInvoiceCheckout(invoiceId);
|
||||||
Assert.Empty(s.Driver.FindElements(By.CssSelector(".payment-method")));
|
Assert.Empty(s.Driver.FindElements(By.CssSelector(".payment-method")));
|
||||||
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
||||||
Assert.StartsWith("bitcoin:", payUrl);
|
Assert.StartsWith("bitcoin:", payUrl);
|
||||||
Assert.Contains("&LIGHTNING=", payUrl);
|
Assert.Contains("&LIGHTNING=", payUrl);
|
||||||
|
|
||||||
// BIP21 with LN as default payment method
|
// BIP21 with LN as default payment method
|
||||||
s.GoToHome();
|
s.GoToHome();
|
||||||
invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
invoiceId = s.CreateInvoice(defaultPaymentMethod: "BTC_LightningLike");
|
||||||
@ -162,7 +162,7 @@ namespace BTCPayServer.Tests
|
|||||||
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
||||||
Assert.StartsWith("bitcoin:", payUrl);
|
Assert.StartsWith("bitcoin:", payUrl);
|
||||||
Assert.Contains("&LIGHTNING=", payUrl);
|
Assert.Contains("&LIGHTNING=", payUrl);
|
||||||
|
|
||||||
// BIP21 with topup invoice (which is only available with Bitcoin onchain)
|
// BIP21 with topup invoice (which is only available with Bitcoin onchain)
|
||||||
s.GoToHome();
|
s.GoToHome();
|
||||||
invoiceId = s.CreateInvoice(amount: null);
|
invoiceId = s.CreateInvoice(amount: null);
|
||||||
@ -171,7 +171,7 @@ namespace BTCPayServer.Tests
|
|||||||
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
payUrl = s.Driver.FindElement(By.CssSelector(".btn-primary")).GetAttribute("href");
|
||||||
Assert.StartsWith("bitcoin:", payUrl);
|
Assert.StartsWith("bitcoin:", payUrl);
|
||||||
Assert.DoesNotContain("&LIGHTNING=", payUrl);
|
Assert.DoesNotContain("&LIGHTNING=", payUrl);
|
||||||
|
|
||||||
// Expiry message should not show amount for topup invoice
|
// Expiry message should not show amount for topup invoice
|
||||||
expirySeconds = s.Driver.FindElement(By.Id("ExpirySeconds"));
|
expirySeconds = s.Driver.FindElement(By.Id("ExpirySeconds"));
|
||||||
expirySeconds.Clear();
|
expirySeconds.Clear();
|
||||||
@ -199,12 +199,12 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.Navigate()
|
s.Driver.Navigate()
|
||||||
.GoToUrl(new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}"));
|
.GoToUrl(new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}"));
|
||||||
s.Driver.WaitUntilAvailable(By.Name("btcpay"));
|
s.Driver.WaitUntilAvailable(By.Name("btcpay"));
|
||||||
|
|
||||||
var frameElement = s.Driver.FindElement(By.Name("btcpay"));
|
var frameElement = s.Driver.FindElement(By.Name("btcpay"));
|
||||||
Assert.True(frameElement.Displayed);
|
Assert.True(frameElement.Displayed);
|
||||||
var iframe = s.Driver.SwitchTo().Frame(frameElement);
|
var iframe = s.Driver.SwitchTo().Frame(frameElement);
|
||||||
iframe.WaitUntilAvailable(By.Id("Checkout-v2"));
|
iframe.WaitUntilAvailable(By.Id("Checkout-v2"));
|
||||||
|
|
||||||
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(invoice
|
await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(invoice
|
||||||
.GetPaymentMethod(new PaymentMethodId("BTC", PaymentTypes.BTCLike))
|
.GetPaymentMethod(new PaymentMethodId("BTC", PaymentTypes.BTCLike))
|
||||||
.GetPaymentMethodDetails().GetPaymentDestination(), Network.RegTest),
|
.GetPaymentMethodDetails().GetPaymentDestination(), Network.RegTest),
|
||||||
|
@ -138,7 +138,7 @@ retry:
|
|||||||
el.Clear();
|
el.Clear();
|
||||||
el.SendKeys(text);
|
el.SendKeys(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ScrollTo(this IWebDriver driver, IWebElement element)
|
public static void ScrollTo(this IWebDriver driver, IWebElement element)
|
||||||
{
|
{
|
||||||
driver.ExecuteJavaScript("arguments[0].scrollIntoView();", element);
|
driver.ExecuteJavaScript("arguments[0].scrollIntoView();", element);
|
||||||
@ -148,7 +148,7 @@ retry:
|
|||||||
{
|
{
|
||||||
ScrollTo(driver, driver.FindElement(selector));
|
ScrollTo(driver, driver.FindElement(selector));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WaitUntilAvailable(this IWebDriver driver, By selector, TimeSpan? waitTime = null)
|
public static void WaitUntilAvailable(this IWebDriver driver, By selector, TimeSpan? waitTime = null)
|
||||||
{
|
{
|
||||||
// Try fast path
|
// Try fast path
|
||||||
@ -165,7 +165,7 @@ retry:
|
|||||||
wait.UntilJsIsReady();
|
wait.UntilJsIsReady();
|
||||||
|
|
||||||
int retriesLeft = 4;
|
int retriesLeft = 4;
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var el = driver.FindElement(selector);
|
var el = driver.FindElement(selector);
|
||||||
@ -176,18 +176,19 @@ retry:
|
|||||||
catch (NoSuchElementException) when (retriesLeft > 0)
|
catch (NoSuchElementException) when (retriesLeft > 0)
|
||||||
{
|
{
|
||||||
retriesLeft--;
|
retriesLeft--;
|
||||||
if (waitTime != null) Thread.Sleep(waitTime.Value);
|
if (waitTime != null)
|
||||||
|
Thread.Sleep(waitTime.Value);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
wait.UntilJsIsReady();
|
wait.UntilJsIsReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WaitForAndClick(this IWebDriver driver, By selector)
|
public static void WaitForAndClick(this IWebDriver driver, By selector)
|
||||||
{
|
{
|
||||||
driver.WaitUntilAvailable(selector);
|
driver.WaitUntilAvailable(selector);
|
||||||
driver.FindElement(selector).Click();
|
driver.FindElement(selector).Click();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ElementDoesNotExist(this IWebDriver driver, By selector)
|
public static bool ElementDoesNotExist(this IWebDriver driver, By selector)
|
||||||
{
|
{
|
||||||
Assert.Throws<NoSuchElementException>(() =>
|
Assert.Throws<NoSuchElementException>(() =>
|
||||||
|
@ -672,7 +672,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal(3, inner.Keys.Count);
|
Assert.Equal(3, inner.Keys.Count);
|
||||||
Assert.Equal(2, inner.RequiredSignatures);
|
Assert.Equal(2, inner.RequiredSignatures);
|
||||||
Assert.Equal(expected, inner.ToString());
|
Assert.Equal(expected, inner.ToString());
|
||||||
|
|
||||||
// Output Descriptor
|
// Output Descriptor
|
||||||
networkProvider = new BTCPayNetworkProvider(ChainName.Mainnet);
|
networkProvider = new BTCPayNetworkProvider(ChainName.Mainnet);
|
||||||
parser = new DerivationSchemeParser(networkProvider.BTC);
|
parser = new DerivationSchemeParser(networkProvider.BTC);
|
||||||
@ -681,7 +681,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Single(rootedKeyPath);
|
Assert.Single(rootedKeyPath);
|
||||||
Assert.IsType<DirectDerivationStrategy>(strategyBase);
|
Assert.IsType<DirectDerivationStrategy>(strategyBase);
|
||||||
Assert.True(((DirectDerivationStrategy)strategyBase).Segwit);
|
Assert.True(((DirectDerivationStrategy)strategyBase).Segwit);
|
||||||
|
|
||||||
// Failure cases
|
// Failure cases
|
||||||
Assert.Throws<FormatException>(() => { parser.Parse("xpub 661MyMwAqRbcGVBsTGeNZN6QGVHmMHLdSA4FteGsRrEriu4pnVZMZWnruFFFXkMnyoBjyHndD3Qwcfz4MPzBUxjSevweNFQx7SAYZATtcDw"); }); // invalid format because of space
|
Assert.Throws<FormatException>(() => { parser.Parse("xpub 661MyMwAqRbcGVBsTGeNZN6QGVHmMHLdSA4FteGsRrEriu4pnVZMZWnruFFFXkMnyoBjyHndD3Qwcfz4MPzBUxjSevweNFQx7SAYZATtcDw"); }); // invalid format because of space
|
||||||
Assert.Throws<ParsingException>(() => { parser.ParseOutputDescriptor("invalid"); }); // invalid in general
|
Assert.Throws<ParsingException>(() => { parser.ParseOutputDescriptor("invalid"); }); // invalid in general
|
||||||
@ -744,7 +744,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal("49'/0'/0'", specter.AccountKeySettings[0].AccountKeyPath.ToString());
|
Assert.Equal("49'/0'/0'", specter.AccountKeySettings[0].AccountKeyPath.ToString());
|
||||||
Assert.Equal("Specter", specter.Label);
|
Assert.Equal("Specter", specter.Label);
|
||||||
Assert.Null(error);
|
Assert.Null(error);
|
||||||
|
|
||||||
// Failure case
|
// Failure case
|
||||||
Assert.False(DerivationSchemeSettings.TryParseFromWalletFile(
|
Assert.False(DerivationSchemeSettings.TryParseFromWalletFile(
|
||||||
"{\"keystore\": {\"ckcc_xpub\": \"tpubFailure\", \"xpub\": \"tpubFailure\", \"label\": \"Failure\"}, \"wallet_type\": \"standard\"}",
|
"{\"keystore\": {\"ckcc_xpub\": \"tpubFailure\", \"xpub\": \"tpubFailure\", \"label\": \"Failure\"}, \"wallet_type\": \"standard\"}",
|
||||||
@ -1077,7 +1077,8 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
MultiProcessingQueueTest t = new MultiProcessingQueueTest();
|
MultiProcessingQueueTest t = new MultiProcessingQueueTest();
|
||||||
t.Tcs = new TaskCompletionSource();
|
t.Tcs = new TaskCompletionSource();
|
||||||
q.Enqueue(queueName, async (cancellationToken) => {
|
q.Enqueue(queueName, async (cancellationToken) =>
|
||||||
|
{
|
||||||
t.Started = true;
|
t.Started = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1774,11 +1775,11 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
foreach (var policy in Policies.AllPolicies)
|
foreach (var policy in Policies.AllPolicies)
|
||||||
{
|
{
|
||||||
Assert.True( UIManageController.AddApiKeyViewModel.PermissionValueItem.PermissionDescriptions.ContainsKey(policy));
|
Assert.True(UIManageController.AddApiKeyViewModel.PermissionValueItem.PermissionDescriptions.ContainsKey(policy));
|
||||||
if (Policies.IsStorePolicy(policy))
|
if (Policies.IsStorePolicy(policy))
|
||||||
{
|
{
|
||||||
Assert.True( UIManageController.AddApiKeyViewModel.PermissionValueItem.PermissionDescriptions.ContainsKey($"{policy}:"));
|
Assert.True(UIManageController.AddApiKeyViewModel.PermissionValueItem.PermissionDescriptions.ContainsKey($"{policy}:"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -1804,8 +1805,8 @@ namespace BTCPayServer.Tests
|
|||||||
PaymentMethod = new PaymentMethodId("BTC", PaymentTypes.BTCLike)
|
PaymentMethod = new PaymentMethodId("BTC", PaymentTypes.BTCLike)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var newBlob = new Serializer(null).ToString(blob).Replace( "paymentMethod\":\"BTC\"","paymentMethod\":\"ETH_ZYC\"");
|
var newBlob = new Serializer(null).ToString(blob).Replace("paymentMethod\":\"BTC\"", "paymentMethod\":\"ETH_ZYC\"");
|
||||||
Assert.Empty(StoreDataExtensions.GetStoreBlob(new StoreData() {StoreBlob = newBlob}).PaymentMethodCriteria);
|
Assert.Empty(StoreDataExtensions.GetStoreBlob(new StoreData() { StoreBlob = newBlob }).PaymentMethodCriteria);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,7 @@ public class MockCustodian : ICustodian, ICanDeposit, ICanTrade, ICanWithdraw
|
|||||||
public List<AssetPairData> GetTradableAssetPairs()
|
public List<AssetPairData> GetTradableAssetPairs()
|
||||||
{
|
{
|
||||||
var r = new List<AssetPairData>();
|
var r = new List<AssetPairData>();
|
||||||
r.Add(new AssetPairData("BTC", "EUR", (decimal) 0.0001));
|
r.Add(new AssetPairData("BTC", "EUR", (decimal)0.0001));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace BTCPayServer.Tests
|
|||||||
public PSBTTests(ITestOutputHelper helper) : base(helper)
|
public PSBTTests(ITestOutputHelper helper) : base(helper)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Selenium", "Selenium")]
|
[Trait("Selenium", "Selenium")]
|
||||||
public async Task CanPlayWithPSBT()
|
public async Task CanPlayWithPSBT()
|
||||||
|
@ -395,9 +395,9 @@ namespace BTCPayServer.Tests
|
|||||||
s.GoToWallet(receiverWalletId, WalletsNavPages.Transactions);
|
s.GoToWallet(receiverWalletId, WalletsNavPages.Transactions);
|
||||||
Assert.Contains(invoiceId, s.Driver.PageSource);
|
Assert.Contains(invoiceId, s.Driver.PageSource);
|
||||||
Assert.Contains("payjoin", s.Driver.PageSource);
|
Assert.Contains("payjoin", s.Driver.PageSource);
|
||||||
//this label does not always show since input gets used
|
//this label does not always show since input gets used
|
||||||
// Assert.Contains("payjoin-exposed", s.Driver.PageSource);
|
// Assert.Contains("payjoin-exposed", s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace BTCPayServer.Tests
|
|||||||
// Reset this using `dotnet user-secrets remove RunSeleniumInBrowser`
|
// Reset this using `dotnet user-secrets remove RunSeleniumInBrowser`
|
||||||
|
|
||||||
var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
|
var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
|
||||||
|
|
||||||
var options = new ChromeOptions();
|
var options = new ChromeOptions();
|
||||||
if (!runInBrowser)
|
if (!runInBrowser)
|
||||||
{
|
{
|
||||||
@ -284,12 +284,12 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
AddLightningNode(null, null, true);
|
AddLightningNode(null, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLightningNode(LightningConnectionType? connectionType = null, bool test = true)
|
public void AddLightningNode(LightningConnectionType? connectionType = null, bool test = true)
|
||||||
{
|
{
|
||||||
AddLightningNode(null, connectionType, test);
|
AddLightningNode(null, connectionType, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLightningNode(string cryptoCode = null, LightningConnectionType? connectionType = null, bool test = true)
|
public void AddLightningNode(string cryptoCode = null, LightningConnectionType? connectionType = null, bool test = true)
|
||||||
{
|
{
|
||||||
cryptoCode ??= "BTC";
|
cryptoCode ??= "BTC";
|
||||||
@ -405,7 +405,7 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
GoToStore(null, storeNavPage);
|
GoToStore(null, storeNavPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToStore(string storeId, StoreNavPages storeNavPage = StoreNavPages.General)
|
public void GoToStore(string storeId, StoreNavPages storeNavPage = StoreNavPages.General)
|
||||||
{
|
{
|
||||||
if (storeId is not null)
|
if (storeId is not null)
|
||||||
@ -415,7 +415,7 @@ namespace BTCPayServer.Tests
|
|||||||
if (WalletId != null)
|
if (WalletId != null)
|
||||||
WalletId = new WalletId(storeId, WalletId.CryptoCode);
|
WalletId = new WalletId(storeId, WalletId.CryptoCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click();
|
Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click();
|
||||||
|
|
||||||
if (storeNavPage != StoreNavPages.General)
|
if (storeNavPage != StoreNavPages.General)
|
||||||
@ -434,7 +434,7 @@ namespace BTCPayServer.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoToWalletSettings(string cryptoCode = "BTC")
|
public void GoToWalletSettings(string cryptoCode = "BTC")
|
||||||
{
|
{
|
||||||
Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||||
@ -555,7 +555,7 @@ namespace BTCPayServer.Tests
|
|||||||
for (var i = 0; i < coins; i++)
|
for (var i = 0; i < coins; i++)
|
||||||
{
|
{
|
||||||
bool mined = false;
|
bool mined = false;
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Server.ExplorerNode.SendToAddressAsync(address, Money.Coins(denomination));
|
await Server.ExplorerNode.SendToAddressAsync(address, Money.Coins(denomination));
|
||||||
|
@ -63,7 +63,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("Starting listening NBXplorer", s.Driver.PageSource);
|
Assert.Contains("Starting listening NBXplorer", s.Driver.PageSource);
|
||||||
s.Driver.Quit();
|
s.Driver.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
public async Task CanUseForms()
|
public async Task CanUseForms()
|
||||||
{
|
{
|
||||||
@ -72,14 +72,14 @@ namespace BTCPayServer.Tests
|
|||||||
s.RegisterNewUser(true);
|
s.RegisterNewUser(true);
|
||||||
s.CreateNewStore();
|
s.CreateNewStore();
|
||||||
s.GenerateWallet(isHotWallet: true);
|
s.GenerateWallet(isHotWallet: true);
|
||||||
|
|
||||||
// Point Of Sale
|
// Point Of Sale
|
||||||
s.Driver.FindElement(By.Id("StoreNav-CreateApp")).Click();
|
s.Driver.FindElement(By.Id("StoreNav-CreateApp")).Click();
|
||||||
new SelectElement(s.Driver.FindElement(By.Id("SelectedAppType"))).SelectByValue("PointOfSale");
|
new SelectElement(s.Driver.FindElement(By.Id("SelectedAppType"))).SelectByValue("PointOfSale");
|
||||||
s.Driver.FindElement(By.Id("AppName")).SendKeys(Guid.NewGuid().ToString());
|
s.Driver.FindElement(By.Id("AppName")).SendKeys(Guid.NewGuid().ToString());
|
||||||
s.Driver.FindElement(By.Id("Create")).Click();
|
s.Driver.FindElement(By.Id("Create")).Click();
|
||||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||||
|
|
||||||
new SelectElement(s.Driver.FindElement(By.Id("FormId"))).SelectByValue("Email");
|
new SelectElement(s.Driver.FindElement(By.Id("FormId"))).SelectByValue("Email");
|
||||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||||
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
||||||
@ -89,16 +89,16 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal(2, windows.Count);
|
Assert.Equal(2, windows.Count);
|
||||||
s.Driver.SwitchTo().Window(windows[1]);
|
s.Driver.SwitchTo().Window(windows[1]);
|
||||||
s.Driver.FindElement(By.CssSelector("button[type='submit']")).Click();
|
s.Driver.FindElement(By.CssSelector("button[type='submit']")).Click();
|
||||||
|
|
||||||
Assert.Contains("Enter your email", s.Driver.PageSource);
|
Assert.Contains("Enter your email", s.Driver.PageSource);
|
||||||
s.Driver.FindElement(By.Name("buyerEmail")).SendKeys("aa@aa.com");
|
s.Driver.FindElement(By.Name("buyerEmail")).SendKeys("aa@aa.com");
|
||||||
s.Driver.FindElement(By.CssSelector("input[type='submit']")).Click();
|
s.Driver.FindElement(By.CssSelector("input[type='submit']")).Click();
|
||||||
|
|
||||||
s.PayInvoice(true);
|
s.PayInvoice(true);
|
||||||
var invoiceId = s.Driver.Url[(s.Driver.Url.LastIndexOf("/", StringComparison.Ordinal) + 1)..];
|
var invoiceId = s.Driver.Url[(s.Driver.Url.LastIndexOf("/", StringComparison.Ordinal) + 1)..];
|
||||||
s.GoToInvoice(invoiceId);
|
s.GoToInvoice(invoiceId);
|
||||||
Assert.Contains("aa@aa.com", s.Driver.PageSource);
|
Assert.Contains("aa@aa.com", s.Driver.PageSource);
|
||||||
|
|
||||||
// Payment Request
|
// Payment Request
|
||||||
s.Driver.FindElement(By.Id("StoreNav-PaymentRequests")).Click();
|
s.Driver.FindElement(By.Id("StoreNav-PaymentRequests")).Click();
|
||||||
s.Driver.FindElement(By.Id("CreatePaymentRequest")).Click();
|
s.Driver.FindElement(By.Id("CreatePaymentRequest")).Click();
|
||||||
@ -106,19 +106,19 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("Amount")).SendKeys("700");
|
s.Driver.FindElement(By.Id("Amount")).SendKeys("700");
|
||||||
new SelectElement(s.Driver.FindElement(By.Id("FormId"))).SelectByValue("Email");
|
new SelectElement(s.Driver.FindElement(By.Id("FormId"))).SelectByValue("Email");
|
||||||
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
||||||
|
|
||||||
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
||||||
var editUrl = s.Driver.Url;
|
var editUrl = s.Driver.Url;
|
||||||
s.Driver.FindElement(By.Id("ViewPaymentRequest")).Click();
|
s.Driver.FindElement(By.Id("ViewPaymentRequest")).Click();
|
||||||
s.Driver.FindElement(By.CssSelector("[data-test='form-button']")).Click();
|
s.Driver.FindElement(By.CssSelector("[data-test='form-button']")).Click();
|
||||||
Assert.Contains("Enter your email", s.Driver.PageSource);
|
Assert.Contains("Enter your email", s.Driver.PageSource);
|
||||||
|
|
||||||
s.Driver.FindElement(By.Name("buyerEmail")).SendKeys("aa@aa.com");
|
s.Driver.FindElement(By.Name("buyerEmail")).SendKeys("aa@aa.com");
|
||||||
s.Driver.FindElement(By.CssSelector("input[type='submit']")).Click();
|
s.Driver.FindElement(By.CssSelector("input[type='submit']")).Click();
|
||||||
s.Driver.Navigate().GoToUrl(editUrl);
|
s.Driver.Navigate().GoToUrl(editUrl);
|
||||||
Assert.Contains("aa@aa.com", s.Driver.PageSource);
|
Assert.Contains("aa@aa.com", s.Driver.PageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
public async Task CanUseCPFP()
|
public async Task CanUseCPFP()
|
||||||
{
|
{
|
||||||
@ -372,7 +372,7 @@ namespace BTCPayServer.Tests
|
|||||||
using var s = CreateSeleniumTester();
|
using var s = CreateSeleniumTester();
|
||||||
await s.StartAsync();
|
await s.StartAsync();
|
||||||
s.RegisterNewUser(true);
|
s.RegisterNewUser(true);
|
||||||
|
|
||||||
// Server Emails
|
// Server Emails
|
||||||
s.Driver.Navigate().GoToUrl(s.Link("/server/emails"));
|
s.Driver.Navigate().GoToUrl(s.Link("/server/emails"));
|
||||||
if (s.Driver.PageSource.Contains("Configured"))
|
if (s.Driver.PageSource.Contains("Configured"))
|
||||||
@ -382,21 +382,21 @@ namespace BTCPayServer.Tests
|
|||||||
}
|
}
|
||||||
CanSetupEmailCore(s);
|
CanSetupEmailCore(s);
|
||||||
s.CreateNewStore();
|
s.CreateNewStore();
|
||||||
|
|
||||||
// Store Emails
|
// Store Emails
|
||||||
s.GoToStore(StoreNavPages.Emails);
|
s.GoToStore(StoreNavPages.Emails);
|
||||||
s.Driver.FindElement(By.Id("ConfigureEmailRules")).Click();
|
s.Driver.FindElement(By.Id("ConfigureEmailRules")).Click();
|
||||||
Assert.Contains("You need to configure email settings before this feature works", s.Driver.PageSource);
|
Assert.Contains("You need to configure email settings before this feature works", s.Driver.PageSource);
|
||||||
|
|
||||||
s.GoToStore(StoreNavPages.Emails);
|
s.GoToStore(StoreNavPages.Emails);
|
||||||
CanSetupEmailCore(s);
|
CanSetupEmailCore(s);
|
||||||
|
|
||||||
// Store Email Rules
|
// Store Email Rules
|
||||||
s.Driver.FindElement(By.Id("ConfigureEmailRules")).Click();
|
s.Driver.FindElement(By.Id("ConfigureEmailRules")).Click();
|
||||||
Assert.Contains("There are no rules yet.", s.Driver.PageSource);
|
Assert.Contains("There are no rules yet.", s.Driver.PageSource);
|
||||||
Assert.DoesNotContain("id=\"SaveEmailRules\"", s.Driver.PageSource);
|
Assert.DoesNotContain("id=\"SaveEmailRules\"", s.Driver.PageSource);
|
||||||
Assert.DoesNotContain("You need to configure email settings before this feature works", s.Driver.PageSource);
|
Assert.DoesNotContain("You need to configure email settings before this feature works", s.Driver.PageSource);
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("CreateEmailRule")).Click();
|
s.Driver.FindElement(By.Id("CreateEmailRule")).Click();
|
||||||
var select = new SelectElement(s.Driver.FindElement(By.Id("Rules_0__Trigger")));
|
var select = new SelectElement(s.Driver.FindElement(By.Id("Rules_0__Trigger")));
|
||||||
select.SelectByText("InvoiceSettled", true);
|
select.SelectByText("InvoiceSettled", true);
|
||||||
@ -456,7 +456,7 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
Assert.DoesNotContain("/server/services/dynamic-dns/pouet.hello.com/delete", s.Driver.PageSource);
|
Assert.DoesNotContain("/server/services/dynamic-dns/pouet.hello.com/delete", s.Driver.PageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
public async Task CanCreateInvoiceInUI()
|
public async Task CanCreateInvoiceInUI()
|
||||||
{
|
{
|
||||||
@ -491,7 +491,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElements(By.ClassName("changeInvoiceState"))[0].Click();
|
s.Driver.FindElements(By.ClassName("changeInvoiceState"))[0].Click();
|
||||||
TestUtils.Eventually(() => Assert.Contains("Settled (marked)", s.Driver.PageSource));
|
TestUtils.Eventually(() => Assert.Contains("Settled (marked)", s.Driver.PageSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
public async Task CanUseInvoiceReceipts()
|
public async Task CanUseInvoiceReceipts()
|
||||||
{
|
{
|
||||||
@ -513,9 +513,9 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.Navigate().Refresh();
|
s.Driver.Navigate().Refresh();
|
||||||
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
||||||
Assert.DoesNotContain("invoice-processing", s.Driver.PageSource);
|
Assert.DoesNotContain("invoice-processing", s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
|
|
||||||
Assert.Contains(s.Server.PayTester.GetService<CurrencyNameTable>().DisplayFormatCurrency(100, "USD"),
|
Assert.Contains(s.Server.PayTester.GetService<CurrencyNameTable>().DisplayFormatCurrency(100, "USD"),
|
||||||
s.Driver.PageSource);
|
s.Driver.PageSource);
|
||||||
Assert.Contains(i, s.Driver.PageSource);
|
Assert.Contains(i, s.Driver.PageSource);
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ namespace BTCPayServer.Tests
|
|||||||
var receipturl = s.Driver.Url + "/receipt";
|
var receipturl = s.Driver.Url + "/receipt";
|
||||||
s.Driver.Navigate().GoToUrl(receipturl);
|
s.Driver.Navigate().GoToUrl(receipturl);
|
||||||
s.Driver.FindElement(By.Id("invoice-unsettled"));
|
s.Driver.FindElement(By.Id("invoice-unsettled"));
|
||||||
|
|
||||||
s.GoToInvoices(s.StoreId);
|
s.GoToInvoices(s.StoreId);
|
||||||
s.GoToInvoiceCheckout(i);
|
s.GoToInvoiceCheckout(i);
|
||||||
var checkouturi = s.Driver.Url;
|
var checkouturi = s.Driver.Url;
|
||||||
@ -540,19 +540,19 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.Navigate().Refresh();
|
s.Driver.Navigate().Refresh();
|
||||||
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
||||||
Assert.Contains("invoice-processing", s.Driver.PageSource);
|
Assert.Contains("invoice-processing", s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
s.GoToUrl(checkouturi);
|
s.GoToUrl(checkouturi);
|
||||||
|
|
||||||
await s.Server.PayTester.InvoiceRepository.MarkInvoiceStatus(i, InvoiceStatus.Settled);
|
await s.Server.PayTester.InvoiceRepository.MarkInvoiceStatus(i, InvoiceStatus.Settled);
|
||||||
|
|
||||||
TestUtils.Eventually(() => s.Driver.FindElement(By.Id("receipt-btn")).Click());
|
TestUtils.Eventually(() => s.Driver.FindElement(By.Id("receipt-btn")).Click());
|
||||||
TestUtils.Eventually(() =>
|
TestUtils.Eventually(() =>
|
||||||
{
|
{
|
||||||
s.Driver.Navigate().Refresh();
|
s.Driver.Navigate().Refresh();
|
||||||
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
Assert.DoesNotContain("invoice-unsettled", s.Driver.PageSource);
|
||||||
Assert.DoesNotContain("invoice-processing", s.Driver.PageSource);
|
Assert.DoesNotContain("invoice-processing", s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
@ -571,7 +571,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("/stores/create", s.Driver.Url);
|
Assert.Contains("/stores/create", s.Driver.Url);
|
||||||
|
|
||||||
(_, string storeId) = s.CreateNewStore();
|
(_, string storeId) = s.CreateNewStore();
|
||||||
|
|
||||||
// should redirect to store
|
// should redirect to store
|
||||||
s.GoToUrl("/");
|
s.GoToUrl("/");
|
||||||
|
|
||||||
@ -623,7 +623,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains("There are no invoices matching your criteria.", s.Driver.PageSource);
|
Assert.Contains("There are no invoices matching your criteria.", s.Driver.PageSource);
|
||||||
var invoiceId = s.CreateInvoice();
|
var invoiceId = s.CreateInvoice();
|
||||||
s.FindAlertMessage();
|
s.FindAlertMessage();
|
||||||
|
|
||||||
var invoiceUrl = s.Driver.Url;
|
var invoiceUrl = s.Driver.Url;
|
||||||
|
|
||||||
//let's test archiving an invoice
|
//let's test archiving an invoice
|
||||||
@ -737,7 +737,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.RegisterNewUser();
|
s.RegisterNewUser();
|
||||||
s.CreateNewStore();
|
s.CreateNewStore();
|
||||||
s.AddDerivationScheme();
|
s.AddDerivationScheme();
|
||||||
|
|
||||||
s.GoToStore(StoreNavPages.Tokens);
|
s.GoToStore(StoreNavPages.Tokens);
|
||||||
s.Driver.FindElement(By.Id("CreateNewToken")).Click();
|
s.Driver.FindElement(By.Id("CreateNewToken")).Click();
|
||||||
s.Driver.FindElement(By.Id("RequestPairing")).Click();
|
s.Driver.FindElement(By.Id("RequestPairing")).Click();
|
||||||
@ -781,7 +781,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Point of Sale");
|
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Point of Sale");
|
||||||
s.Driver.FindElement(By.Id("Create")).Click();
|
s.Driver.FindElement(By.Id("Create")).Click();
|
||||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||||
|
|
||||||
s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1) .btn-primary")).Click();
|
s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1) .btn-primary")).Click();
|
||||||
s.Driver.FindElement(By.Id("BuyButtonText")).SendKeys("Take my money");
|
s.Driver.FindElement(By.Id("BuyButtonText")).SendKeys("Take my money");
|
||||||
s.Driver.FindElement(By.Id("SaveItemChanges")).Click();
|
s.Driver.FindElement(By.Id("SaveItemChanges")).Click();
|
||||||
@ -825,7 +825,7 @@ namespace BTCPayServer.Tests
|
|||||||
// Make sure after login, we are not redirected to the PoS
|
// Make sure after login, we are not redirected to the PoS
|
||||||
Assert.DoesNotContain("Tea shop", s.Driver.PageSource);
|
Assert.DoesNotContain("Tea shop", s.Driver.PageSource);
|
||||||
var prevUrl = s.Driver.Url;
|
var prevUrl = s.Driver.Url;
|
||||||
|
|
||||||
// We are only if explicitly going to /
|
// We are only if explicitly going to /
|
||||||
s.GoToUrl("/");
|
s.GoToUrl("/");
|
||||||
Assert.Contains("Tea shop", s.Driver.PageSource);
|
Assert.Contains("Tea shop", s.Driver.PageSource);
|
||||||
@ -848,7 +848,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.LogIn(userId);
|
s.LogIn(userId);
|
||||||
// Make sure after login, we are not redirected to the PoS
|
// Make sure after login, we are not redirected to the PoS
|
||||||
Assert.DoesNotContain("Tea shop", s.Driver.PageSource);
|
Assert.DoesNotContain("Tea shop", s.Driver.PageSource);
|
||||||
|
|
||||||
// We are only if explicitly going to /
|
// We are only if explicitly going to /
|
||||||
s.GoToUrl("/");
|
s.GoToUrl("/");
|
||||||
Assert.Contains("Tea shop", s.Driver.PageSource);
|
Assert.Contains("Tea shop", s.Driver.PageSource);
|
||||||
@ -868,20 +868,20 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Crowdfund");
|
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Crowdfund");
|
||||||
s.Driver.FindElement(By.Id("Create")).Click();
|
s.Driver.FindElement(By.Id("Create")).Click();
|
||||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter");
|
s.Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter");
|
||||||
s.Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC");
|
s.Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC");
|
||||||
s.Driver.FindElement(By.Id("TargetCurrency")).Clear();
|
s.Driver.FindElement(By.Id("TargetCurrency")).Clear();
|
||||||
s.Driver.FindElement(By.Id("TargetCurrency")).SendKeys("JPY");
|
s.Driver.FindElement(By.Id("TargetCurrency")).SendKeys("JPY");
|
||||||
s.Driver.FindElement(By.Id("TargetAmount")).SendKeys("700");
|
s.Driver.FindElement(By.Id("TargetAmount")).SendKeys("700");
|
||||||
|
|
||||||
// test wrong dates
|
// test wrong dates
|
||||||
s.Driver.ExecuteJavaScript("const now = new Date();document.getElementById('StartDate').value = now.toISOString();" +
|
s.Driver.ExecuteJavaScript("const now = new Date();document.getElementById('StartDate').value = now.toISOString();" +
|
||||||
"const yst = new Date(now.setDate(now.getDate() -1));document.getElementById('EndDate').value = yst.toISOString()");
|
"const yst = new Date(now.setDate(now.getDate() -1));document.getElementById('EndDate').value = yst.toISOString()");
|
||||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||||
Assert.Contains("End date cannot be before start date", s.Driver.PageSource);
|
Assert.Contains("End date cannot be before start date", s.Driver.PageSource);
|
||||||
Assert.DoesNotContain("App updated", s.Driver.PageSource);
|
Assert.DoesNotContain("App updated", s.Driver.PageSource);
|
||||||
|
|
||||||
// unset end date
|
// unset end date
|
||||||
s.Driver.ExecuteJavaScript("document.getElementById('EndDate').value = ''");
|
s.Driver.ExecuteJavaScript("document.getElementById('EndDate').value = ''");
|
||||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||||
@ -894,7 +894,7 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
Assert.Equal("currently active!",
|
Assert.Equal("currently active!",
|
||||||
s.Driver.FindElement(By.CssSelector("[data-test='time-state']")).Text);
|
s.Driver.FindElement(By.CssSelector("[data-test='time-state']")).Text);
|
||||||
|
|
||||||
s.Driver.Close();
|
s.Driver.Close();
|
||||||
s.Driver.SwitchTo().Window(windows[0]);
|
s.Driver.SwitchTo().Window(windows[0]);
|
||||||
}
|
}
|
||||||
@ -917,23 +917,23 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal("USD", currencyInput.GetAttribute("value"));
|
Assert.Equal("USD", currencyInput.GetAttribute("value"));
|
||||||
currencyInput.Clear();
|
currencyInput.Clear();
|
||||||
currencyInput.SendKeys("BTC");
|
currencyInput.SendKeys("BTC");
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
||||||
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
||||||
var editUrl = s.Driver.Url;
|
var editUrl = s.Driver.Url;
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("ViewPaymentRequest")).Click();
|
s.Driver.FindElement(By.Id("ViewPaymentRequest")).Click();
|
||||||
var viewUrl = s.Driver.Url;
|
var viewUrl = s.Driver.Url;
|
||||||
|
|
||||||
Assert.Equal("Amount due", s.Driver.FindElement(By.CssSelector("[data-test='amount-due-title']")).Text);
|
Assert.Equal("Amount due", s.Driver.FindElement(By.CssSelector("[data-test='amount-due-title']")).Text);
|
||||||
Assert.Equal("Pay Invoice", s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
|
Assert.Equal("Pay Invoice", s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
|
||||||
|
|
||||||
// expire
|
// expire
|
||||||
s.GoToUrl(editUrl);
|
s.GoToUrl(editUrl);
|
||||||
s.Driver.ExecuteJavaScript("document.getElementById('ExpiryDate').value = '2021-01-21T21:00:00.000Z'");
|
s.Driver.ExecuteJavaScript("document.getElementById('ExpiryDate').value = '2021-01-21T21:00:00.000Z'");
|
||||||
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
s.Driver.FindElement(By.Id("SaveButton")).Click();
|
||||||
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
s.Driver.FindElement(By.XPath("//a[starts-with(@id, 'Edit-')]")).Click();
|
||||||
|
|
||||||
s.GoToUrl(viewUrl);
|
s.GoToUrl(viewUrl);
|
||||||
Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
|
Assert.Equal("Expired", s.Driver.WaitForElement(By.CssSelector("[data-test='status']")).Text);
|
||||||
|
|
||||||
@ -947,22 +947,22 @@ namespace BTCPayServer.Tests
|
|||||||
s.GoToUrl(editUrl);
|
s.GoToUrl(editUrl);
|
||||||
Assert.True(s.Driver.FindElement(By.Id("Amount")).Enabled);
|
Assert.True(s.Driver.FindElement(By.Id("Amount")).Enabled);
|
||||||
Assert.True(s.Driver.FindElement(By.Id("Currency")).Enabled);
|
Assert.True(s.Driver.FindElement(By.Id("Currency")).Enabled);
|
||||||
|
|
||||||
s.GoToUrl(viewUrl);
|
s.GoToUrl(viewUrl);
|
||||||
s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']"));
|
s.Driver.AssertElementNotFound(By.CssSelector("[data-test='status']"));
|
||||||
Assert.Equal("Pay Invoice", s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
|
Assert.Equal("Pay Invoice", s.Driver.FindElement(By.CssSelector("[data-test='pay-button']")).Text.Trim());
|
||||||
|
|
||||||
// test invoice creation, click with JS, because the button is inside a sticky header
|
// test invoice creation, click with JS, because the button is inside a sticky header
|
||||||
s.Driver.ExecuteJavaScript("document.querySelector('[data-test=\"pay-button\"]').click()");
|
s.Driver.ExecuteJavaScript("document.querySelector('[data-test=\"pay-button\"]').click()");
|
||||||
// checkout v1
|
// checkout v1
|
||||||
s.Driver.WaitForElement(By.CssSelector("invoice"));
|
s.Driver.WaitForElement(By.CssSelector("invoice"));
|
||||||
Assert.Contains("Awaiting Payment", s.Driver.PageSource);
|
Assert.Contains("Awaiting Payment", s.Driver.PageSource);
|
||||||
|
|
||||||
// amount and currency should not be editable, because invoice exists
|
// amount and currency should not be editable, because invoice exists
|
||||||
s.GoToUrl(editUrl);
|
s.GoToUrl(editUrl);
|
||||||
Assert.False(s.Driver.FindElement(By.Id("Amount")).Enabled);
|
Assert.False(s.Driver.FindElement(By.Id("Amount")).Enabled);
|
||||||
Assert.False(s.Driver.FindElement(By.Id("Currency")).Enabled);
|
Assert.False(s.Driver.FindElement(By.Id("Currency")).Enabled);
|
||||||
|
|
||||||
// archive (from details page)
|
// archive (from details page)
|
||||||
var payReqId = s.Driver.Url.Split('/').Last();
|
var payReqId = s.Driver.Url.Split('/').Last();
|
||||||
s.Driver.FindElement(By.Id("ArchivePaymentRequest")).Click();
|
s.Driver.FindElement(By.Id("ArchivePaymentRequest")).Click();
|
||||||
@ -971,7 +971,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("SearchDropdownToggle")).Click();
|
s.Driver.FindElement(By.Id("SearchDropdownToggle")).Click();
|
||||||
s.Driver.FindElement(By.Id("SearchIncludeArchived")).Click();
|
s.Driver.FindElement(By.Id("SearchIncludeArchived")).Click();
|
||||||
Assert.Contains("Pay123", s.Driver.PageSource);
|
Assert.Contains("Pay123", s.Driver.PageSource);
|
||||||
|
|
||||||
// unarchive (from list)
|
// unarchive (from list)
|
||||||
s.Driver.FindElement(By.Id($"ToggleArchival-{payReqId}")).Click();
|
s.Driver.FindElement(By.Id($"ToggleArchival-{payReqId}")).Click();
|
||||||
Assert.Contains("The payment request has been unarchived", s.FindAlertMessage().Text);
|
Assert.Contains("The payment request has been unarchived", s.FindAlertMessage().Text);
|
||||||
@ -1123,7 +1123,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.GoToStore(StoreNavPages.Webhooks);
|
s.GoToStore(StoreNavPages.Webhooks);
|
||||||
s.Driver.FindElement(By.LinkText("Modify")).Click();
|
s.Driver.FindElement(By.LinkText("Modify")).Click();
|
||||||
var elements = s.Driver.FindElements(By.ClassName("redeliver"));
|
var elements = s.Driver.FindElements(By.ClassName("redeliver"));
|
||||||
|
|
||||||
// One worked, one failed
|
// One worked, one failed
|
||||||
s.Driver.FindElement(By.ClassName("fa-times"));
|
s.Driver.FindElement(By.ClassName("fa-times"));
|
||||||
s.Driver.FindElement(By.ClassName("fa-check"));
|
s.Driver.FindElement(By.ClassName("fa-check"));
|
||||||
@ -1199,7 +1199,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.True(s.Driver.ElementDoesNotExist(By.Id("GoBack")));
|
Assert.True(s.Driver.ElementDoesNotExist(By.Id("GoBack")));
|
||||||
s.Driver.FindElement(By.Id("CancelWizard")).Click();
|
s.Driver.FindElement(By.Id("CancelWizard")).Click();
|
||||||
s.Driver.FindElement(By.Id("WalletNav-Receive")).Click();
|
s.Driver.FindElement(By.Id("WalletNav-Receive")).Click();
|
||||||
|
|
||||||
//generate a receiving address
|
//generate a receiving address
|
||||||
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
|
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
|
||||||
Assert.True(s.Driver.FindElement(By.CssSelector("#address-tab .qr-container")).Displayed);
|
Assert.True(s.Driver.FindElement(By.CssSelector("#address-tab .qr-container")).Displayed);
|
||||||
@ -1343,7 +1343,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Empty(s.Driver.FindElements(By.Id("confirm")));
|
Assert.Empty(s.Driver.FindElements(By.Id("confirm")));
|
||||||
s.Driver.FindElement(By.Id("proceed")).Click();
|
s.Driver.FindElement(By.Id("proceed")).Click();
|
||||||
Assert.Equal(settingsUri.ToString(), s.Driver.Url);
|
Assert.Equal(settingsUri.ToString(), s.Driver.Url);
|
||||||
|
|
||||||
// Once more, test the cancel link of the wallet send page leads back to the previous page
|
// Once more, test the cancel link of the wallet send page leads back to the previous page
|
||||||
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
||||||
cancelUrl = s.Driver.FindElement(By.Id("CancelWizard")).GetAttribute("href");
|
cancelUrl = s.Driver.FindElement(By.Id("CancelWizard")).GetAttribute("href");
|
||||||
@ -1352,12 +1352,12 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.True(s.Driver.ElementDoesNotExist(By.Id("GoBack")));
|
Assert.True(s.Driver.ElementDoesNotExist(By.Id("GoBack")));
|
||||||
s.Driver.FindElement(By.Id("CancelWizard")).Click();
|
s.Driver.FindElement(By.Id("CancelWizard")).Click();
|
||||||
Assert.Equal(settingsUri.ToString(), s.Driver.Url);
|
Assert.Equal(settingsUri.ToString(), s.Driver.Url);
|
||||||
|
|
||||||
// Transactions list contains export and action, ensure functions are present.
|
// Transactions list contains export and action, ensure functions are present.
|
||||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||||
s.Driver.FindElement(By.Id("ActionsDropdownToggle")).Click();
|
s.Driver.FindElement(By.Id("ActionsDropdownToggle")).Click();
|
||||||
s.Driver.FindElement(By.Id("BumpFee"));
|
s.Driver.FindElement(By.Id("BumpFee"));
|
||||||
|
|
||||||
// JSON export
|
// JSON export
|
||||||
s.Driver.FindElement(By.Id("ExportDropdownToggle")).Click();
|
s.Driver.FindElement(By.Id("ExportDropdownToggle")).Click();
|
||||||
s.Driver.FindElement(By.Id("ExportJSON")).Click();
|
s.Driver.FindElement(By.Id("ExportJSON")).Click();
|
||||||
@ -1367,7 +1367,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.EndsWith("export?format=json", s.Driver.Url);
|
Assert.EndsWith("export?format=json", s.Driver.Url);
|
||||||
Assert.Contains("\"Amount\": \"3.00000000\"", s.Driver.PageSource);
|
Assert.Contains("\"Amount\": \"3.00000000\"", s.Driver.PageSource);
|
||||||
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
|
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
|
||||||
|
|
||||||
// CSV export
|
// CSV export
|
||||||
s.Driver.FindElement(By.Id("ExportDropdownToggle")).Click();
|
s.Driver.FindElement(By.Id("ExportDropdownToggle")).Click();
|
||||||
s.Driver.FindElement(By.Id("ExportCSV")).Click();
|
s.Driver.FindElement(By.Id("ExportCSV")).Click();
|
||||||
@ -1389,7 +1389,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("AccountKeys_0__MasterFingerprint")).GetAttribute("value"));
|
s.Driver.FindElement(By.Id("AccountKeys_0__MasterFingerprint")).GetAttribute("value"));
|
||||||
Assert.Contains("m/84'/1'/0'",
|
Assert.Contains("m/84'/1'/0'",
|
||||||
s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).GetAttribute("value"));
|
s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).GetAttribute("value"));
|
||||||
|
|
||||||
// Transactions list is empty
|
// Transactions list is empty
|
||||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||||
Assert.Contains("There are no transactions yet.", s.Driver.PageSource);
|
Assert.Contains("There are no transactions yet.", s.Driver.PageSource);
|
||||||
@ -1605,7 +1605,7 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
newStore = s.CreateNewStore();
|
newStore = s.CreateNewStore();
|
||||||
s.AddLightningNode();
|
s.AddLightningNode();
|
||||||
|
|
||||||
//Currently an onchain wallet is required to use the Lightning payouts feature..
|
//Currently an onchain wallet is required to use the Lightning payouts feature..
|
||||||
s.GenerateWallet("BTC", "", true, true);
|
s.GenerateWallet("BTC", "", true, true);
|
||||||
s.GoToStore(newStore.storeId, StoreNavPages.PullPayments);
|
s.GoToStore(newStore.storeId, StoreNavPages.PullPayments);
|
||||||
@ -1680,8 +1680,8 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id($"{PayoutState.Completed}-view")).Click();
|
s.Driver.FindElement(By.Id($"{PayoutState.Completed}-view")).Click();
|
||||||
Assert.Contains(bolt, s.Driver.PageSource);
|
Assert.Contains(bolt, s.Driver.PageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//auto-approve pull payments
|
//auto-approve pull payments
|
||||||
|
|
||||||
@ -1703,8 +1703,8 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains(PayoutState.AwaitingPayment.GetStateString(), s.Driver.PageSource);
|
Assert.Contains(PayoutState.AwaitingPayment.GetStateString(), s.Driver.PageSource);
|
||||||
|
|
||||||
//lnurl-w support check
|
//lnurl-w support check
|
||||||
|
|
||||||
s.GoToStore(s.StoreId,StoreNavPages.PullPayments);
|
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||||
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
||||||
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
||||||
s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true);
|
s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), true);
|
||||||
@ -1715,7 +1715,7 @@ namespace BTCPayServer.Tests
|
|||||||
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
|
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
|
||||||
s.Driver.FindElement(By.LinkText("View")).Click();
|
s.Driver.FindElement(By.LinkText("View")).Click();
|
||||||
s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click();
|
s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click();
|
||||||
var lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http"));
|
var lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http"));
|
||||||
s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click();
|
s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click();
|
||||||
var info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient));
|
var info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient));
|
||||||
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
@ -1723,7 +1723,7 @@ namespace BTCPayServer.Tests
|
|||||||
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(info.BalanceCheck, s.Server.PayTester.HttpClient));
|
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(info.BalanceCheck, s.Server.PayTester.HttpClient));
|
||||||
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
Assert.Equal(info.CurrentBalance, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.CurrentBalance, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
|
|
||||||
var bolt2 = (await s.Server.CustomerLightningD.CreateInvoice(
|
var bolt2 = (await s.Server.CustomerLightningD.CreateInvoice(
|
||||||
new LightMoney(0.0000001m, LightMoneyUnit.BTC),
|
new LightMoney(0.0000001m, LightMoneyUnit.BTC),
|
||||||
$"LNurl w payout test {DateTime.UtcNow.Ticks}",
|
$"LNurl w payout test {DateTime.UtcNow.Ticks}",
|
||||||
@ -1733,12 +1733,12 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
s.Driver.Navigate().Refresh();
|
s.Driver.Navigate().Refresh();
|
||||||
Assert.Contains(bolt2.BOLT11, s.Driver.PageSource);
|
Assert.Contains(bolt2.BOLT11, s.Driver.PageSource);
|
||||||
|
|
||||||
Assert.Contains(PayoutState.Completed.GetStateString(), s.Driver.PageSource);
|
Assert.Contains(PayoutState.Completed.GetStateString(), s.Driver.PageSource);
|
||||||
Assert.Equal( LightningInvoiceStatus.Paid, (await s.Server.CustomerLightningD.GetInvoice(bolt2.Id)).Status );
|
Assert.Equal(LightningInvoiceStatus.Paid, (await s.Server.CustomerLightningD.GetInvoice(bolt2.Id)).Status);
|
||||||
});
|
});
|
||||||
|
|
||||||
s.GoToStore(s.StoreId,StoreNavPages.PullPayments);
|
s.GoToStore(s.StoreId, StoreNavPages.PullPayments);
|
||||||
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
s.Driver.FindElement(By.Id("NewPullPayment")).Click();
|
||||||
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
||||||
s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), false);
|
s.Driver.SetCheckbox(By.Id("AutoApproveClaims"), false);
|
||||||
@ -1749,8 +1749,8 @@ namespace BTCPayServer.Tests
|
|||||||
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
|
s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success);
|
||||||
s.Driver.FindElement(By.LinkText("View")).Click();
|
s.Driver.FindElement(By.LinkText("View")).Click();
|
||||||
s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click();
|
s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click();
|
||||||
lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http"));
|
lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http"));
|
||||||
|
|
||||||
s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click();
|
s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click();
|
||||||
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient));
|
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient));
|
||||||
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
@ -1758,7 +1758,7 @@ namespace BTCPayServer.Tests
|
|||||||
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(info.BalanceCheck, s.Server.PayTester.HttpClient));
|
info = Assert.IsType<LNURLWithdrawRequest>(await LNURL.LNURL.FetchInformation(info.BalanceCheck, s.Server.PayTester.HttpClient));
|
||||||
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.MaxWithdrawable, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
Assert.Equal(info.CurrentBalance, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
Assert.Equal(info.CurrentBalance, new LightMoney(0.0000001m, LightMoneyUnit.BTC));
|
||||||
|
|
||||||
bolt2 = (await s.Server.CustomerLightningD.CreateInvoice(
|
bolt2 = (await s.Server.CustomerLightningD.CreateInvoice(
|
||||||
new LightMoney(0.0000001m, LightMoneyUnit.BTC),
|
new LightMoney(0.0000001m, LightMoneyUnit.BTC),
|
||||||
$"LNurl w payout test {DateTime.UtcNow.Ticks}",
|
$"LNurl w payout test {DateTime.UtcNow.Ticks}",
|
||||||
@ -1768,7 +1768,7 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
s.Driver.Navigate().Refresh();
|
s.Driver.Navigate().Refresh();
|
||||||
Assert.Contains(bolt2.BOLT11, s.Driver.PageSource);
|
Assert.Contains(bolt2.BOLT11, s.Driver.PageSource);
|
||||||
|
|
||||||
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
|
Assert.Contains(PayoutState.AwaitingApproval.GetStateString(), s.Driver.PageSource);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1867,7 +1867,8 @@ namespace BTCPayServer.Tests
|
|||||||
});
|
});
|
||||||
var greenfield = await s.AsTestAccount().CreateClient();
|
var greenfield = await s.AsTestAccount().CreateClient();
|
||||||
var paymentMethods = await greenfield.GetInvoicePaymentMethods(s.StoreId, i);
|
var paymentMethods = await greenfield.GetInvoicePaymentMethods(s.StoreId, i);
|
||||||
Assert.Single(paymentMethods, p => {
|
Assert.Single(paymentMethods, p =>
|
||||||
|
{
|
||||||
return p.AdditionalData["providedComment"].Value<string>() == "lol2";
|
return p.AdditionalData["providedComment"].Value<string>() == "lol2";
|
||||||
});
|
});
|
||||||
// Standard invoice test
|
// Standard invoice test
|
||||||
@ -1977,12 +1978,12 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
s.Driver.FindElement(By.Id("Name")).SendKeys("PP1");
|
||||||
s.Driver.FindElement(By.Id("Amount")).Clear();
|
s.Driver.FindElement(By.Id("Amount")).Clear();
|
||||||
s.Driver.FindElement(By.Id("Amount")).SendKeys("0.0000001");
|
s.Driver.FindElement(By.Id("Amount")).SendKeys("0.0000001");
|
||||||
|
|
||||||
var currencyInput = s.Driver.FindElement(By.Id("Currency"));
|
var currencyInput = s.Driver.FindElement(By.Id("Currency"));
|
||||||
Assert.Equal("USD", currencyInput.GetAttribute("value"));
|
Assert.Equal("USD", currencyInput.GetAttribute("value"));
|
||||||
currencyInput.Clear();
|
currencyInput.Clear();
|
||||||
currencyInput.SendKeys("BTC");
|
currencyInput.SendKeys("BTC");
|
||||||
|
|
||||||
s.Driver.FindElement(By.Id("Create")).Click();
|
s.Driver.FindElement(By.Id("Create")).Click();
|
||||||
s.Driver.FindElement(By.LinkText("View")).Click();
|
s.Driver.FindElement(By.LinkText("View")).Click();
|
||||||
s.Driver.FindElement(By.Id("Destination")).SendKeys(lnurl);
|
s.Driver.FindElement(By.Id("Destination")).SendKeys(lnurl);
|
||||||
@ -2124,7 +2125,7 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Selenium", "Selenium")]
|
[Trait("Selenium", "Selenium")]
|
||||||
public async Task CanUseLNURLAuth()
|
public async Task CanUseLNURLAuth()
|
||||||
@ -2138,32 +2139,32 @@ retry:
|
|||||||
.FindElement(By.CssSelector($"option[value='{(int)Fido2Credential.CredentialType.LNURLAuth}']")).Click();
|
.FindElement(By.CssSelector($"option[value='{(int)Fido2Credential.CredentialType.LNURLAuth}']")).Click();
|
||||||
s.Driver.FindElement(By.Id("btn-add")).Click();
|
s.Driver.FindElement(By.Id("btn-add")).Click();
|
||||||
var links = s.Driver.FindElements(By.CssSelector(".tab-content a")).Select(element => element.GetAttribute("href"));
|
var links = s.Driver.FindElements(By.CssSelector(".tab-content a")).Select(element => element.GetAttribute("href"));
|
||||||
Assert.Equal(2,links.Count());
|
Assert.Equal(2, links.Count());
|
||||||
Uri prevEndpoint = null;
|
Uri prevEndpoint = null;
|
||||||
foreach (string link in links)
|
foreach (string link in links)
|
||||||
{
|
{
|
||||||
var endpoint = LNURL.LNURL.Parse(link, out var tag);
|
var endpoint = LNURL.LNURL.Parse(link, out var tag);
|
||||||
Assert.Equal("login",tag);
|
Assert.Equal("login", tag);
|
||||||
if(endpoint.Scheme != "https")
|
if (endpoint.Scheme != "https")
|
||||||
prevEndpoint = endpoint;
|
prevEndpoint = endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
var linkingKey = new Key();
|
var linkingKey = new Key();
|
||||||
var request = Assert.IsType<LNAuthRequest>(await LNURL.LNURL.FetchInformation(prevEndpoint, null));
|
var request = Assert.IsType<LNAuthRequest>(await LNURL.LNURL.FetchInformation(prevEndpoint, null));
|
||||||
_ = await request.SendChallenge(linkingKey, new HttpClient());
|
_ = await request.SendChallenge(linkingKey, new HttpClient());
|
||||||
TestUtils.Eventually(() => s.FindAlertMessage());
|
TestUtils.Eventually(() => s.FindAlertMessage());
|
||||||
|
|
||||||
s.Logout();
|
s.Logout();
|
||||||
s.LogIn(user, "123456");
|
s.LogIn(user, "123456");
|
||||||
var section = s.Driver.FindElement(By.Id("lnurlauth-section"));
|
var section = s.Driver.FindElement(By.Id("lnurlauth-section"));
|
||||||
links = section.FindElements(By.CssSelector(".tab-content a")).Select(element => element.GetAttribute("href"));
|
links = section.FindElements(By.CssSelector(".tab-content a")).Select(element => element.GetAttribute("href"));
|
||||||
Assert.Equal(2,links.Count());
|
Assert.Equal(2, links.Count());
|
||||||
prevEndpoint = null;
|
prevEndpoint = null;
|
||||||
foreach (string link in links)
|
foreach (string link in links)
|
||||||
{
|
{
|
||||||
var endpoint = LNURL.LNURL.Parse(link, out var tag);
|
var endpoint = LNURL.LNURL.Parse(link, out var tag);
|
||||||
Assert.Equal("login",tag);
|
Assert.Equal("login", tag);
|
||||||
if(endpoint.Scheme != "https")
|
if (endpoint.Scheme != "https")
|
||||||
prevEndpoint = endpoint;
|
prevEndpoint = endpoint;
|
||||||
}
|
}
|
||||||
request = Assert.IsType<LNAuthRequest>(await LNURL.LNURL.FetchInformation(prevEndpoint, null));
|
request = Assert.IsType<LNAuthRequest>(await LNURL.LNURL.FetchInformation(prevEndpoint, null));
|
||||||
@ -2173,7 +2174,7 @@ retry:
|
|||||||
Assert.Equal(s.Driver.Url, s.ServerUri.ToString());
|
Assert.Equal(s.Driver.Url, s.ServerUri.ToString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CanBrowseContent(SeleniumTester s)
|
private static void CanBrowseContent(SeleniumTester s)
|
||||||
{
|
{
|
||||||
s.Driver.FindElement(By.ClassName("delivery-content")).Click();
|
s.Driver.FindElement(By.ClassName("delivery-content")).Click();
|
||||||
|
@ -254,7 +254,7 @@ namespace BTCPayServer.Tests
|
|||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Email
|
public string Email
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -75,7 +75,7 @@ namespace BTCPayServer.Tests
|
|||||||
public async Task CanQueryDirectProviders()
|
public async Task CanQueryDirectProviders()
|
||||||
{
|
{
|
||||||
// TODO: Check once in a while whether or not they are working again
|
// TODO: Check once in a while whether or not they are working again
|
||||||
string[] brokenShitcoinCasinos = {};
|
string[] brokenShitcoinCasinos = { };
|
||||||
var skipped = 0;
|
var skipped = 0;
|
||||||
var factory = FastTests.CreateBTCPayRateFactory();
|
var factory = FastTests.CreateBTCPayRateFactory();
|
||||||
var directlySupported = factory.GetSupportedExchanges().Where(s => s.Source == RateSource.Direct)
|
var directlySupported = factory.GetSupportedExchanges().Where(s => s.Source == RateSource.Direct)
|
||||||
@ -95,7 +95,7 @@ namespace BTCPayServer.Tests
|
|||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestLogs.LogInformation($"Testing {name}");
|
TestLogs.LogInformation($"Testing {name}");
|
||||||
|
|
||||||
result.Fetcher.InvalidateCache();
|
result.Fetcher.InvalidateCache();
|
||||||
@ -175,7 +175,7 @@ namespace BTCPayServer.Tests
|
|||||||
var p = new KrakenExchangeRateProvider();
|
var p = new KrakenExchangeRateProvider();
|
||||||
var rates = await p.GetRatesAsync(default);
|
var rates = await p.GetRatesAsync(default);
|
||||||
Assert.Contains(rates, e => e.CurrencyPair == new CurrencyPair("XMR", "BTC") && e.BidAsk.Bid < 1.0m);
|
Assert.Contains(rates, e => e.CurrencyPair == new CurrencyPair("XMR", "BTC") && e.BidAsk.Bid < 1.0m);
|
||||||
|
|
||||||
// Check we didn't skip too many exchanges
|
// Check we didn't skip too many exchanges
|
||||||
Assert.InRange(skipped, 0, 3);
|
Assert.InRange(skipped, 0, 3);
|
||||||
}
|
}
|
||||||
@ -225,7 +225,7 @@ namespace BTCPayServer.Tests
|
|||||||
{
|
{
|
||||||
var uri = new Uri(url);
|
var uri = new Uri(url);
|
||||||
int retryLeft = 3;
|
int retryLeft = 3;
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
using var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||||
@ -350,7 +350,7 @@ namespace BTCPayServer.Tests
|
|||||||
expected = (await (await client.GetAsync($"https://unpkg.com/@chenfengyuan/vue-qrcode@{version}/dist/vue-qrcode.min.js")).Content.ReadAsStringAsync()).Trim();
|
expected = (await (await client.GetAsync($"https://unpkg.com/@chenfengyuan/vue-qrcode@{version}/dist/vue-qrcode.min.js")).Content.ReadAsStringAsync()).Trim();
|
||||||
Assert.Equal(expected, actual);
|
Assert.Equal(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetFileContent(params string[] path)
|
string GetFileContent(params string[] path)
|
||||||
{
|
{
|
||||||
var l = path.ToList();
|
var l = path.ToList();
|
||||||
|
@ -189,7 +189,7 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
Assert.Equal(description, json["components"]["securitySchemes"]["API_Key"]["description"].Value<string>());
|
Assert.Equal(description, json["components"]["securitySchemes"]["API_Key"]["description"].Value<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Integration", "Integration")]
|
[Trait("Integration", "Integration")]
|
||||||
public async void CanStoreArbitrarySettingsWithStore()
|
public async void CanStoreArbitrarySettingsWithStore()
|
||||||
@ -199,11 +199,11 @@ namespace BTCPayServer.Tests
|
|||||||
var user = tester.NewAccount();
|
var user = tester.NewAccount();
|
||||||
await user.GrantAccessAsync();
|
await user.GrantAccessAsync();
|
||||||
var settingsRepo = tester.PayTester.ServiceProvider.GetRequiredService<IStoreRepository>();
|
var settingsRepo = tester.PayTester.ServiceProvider.GetRequiredService<IStoreRepository>();
|
||||||
var arbValue = await settingsRepo.GetSettingAsync<string>(user.StoreId,"arbitrary");
|
var arbValue = await settingsRepo.GetSettingAsync<string>(user.StoreId, "arbitrary");
|
||||||
Assert.Null(arbValue);
|
Assert.Null(arbValue);
|
||||||
await settingsRepo.UpdateSetting(user.StoreId, "arbitrary", "saved");
|
await settingsRepo.UpdateSetting(user.StoreId, "arbitrary", "saved");
|
||||||
|
|
||||||
arbValue = await settingsRepo.GetSettingAsync<string>(user.StoreId,"arbitrary");
|
arbValue = await settingsRepo.GetSettingAsync<string>(user.StoreId, "arbitrary");
|
||||||
Assert.Equal("saved", arbValue);
|
Assert.Equal("saved", arbValue);
|
||||||
|
|
||||||
await settingsRepo.UpdateSetting<TestData>(user.StoreId, "arbitrary", new TestData() { Name = "hello" });
|
await settingsRepo.UpdateSetting<TestData>(user.StoreId, "arbitrary", new TestData() { Name = "hello" });
|
||||||
@ -1934,8 +1934,8 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Contains($",orderId,{invoice.Id},", paidresult.Content);
|
Assert.Contains($",orderId,{invoice.Id},", paidresult.Content);
|
||||||
Assert.Contains($",On-Chain,BTC,0.0991,0.0001,5000.0", paidresult.Content);
|
Assert.Contains($",On-Chain,BTC,0.0991,0.0001,5000.0", paidresult.Content);
|
||||||
Assert.Contains($",USD,5.00", paidresult.Content); // Seems hacky but some plateform does not render this decimal the same
|
Assert.Contains($",USD,5.00", paidresult.Content); // Seems hacky but some plateform does not render this decimal the same
|
||||||
Assert.Contains("0,,\"Some \"\", description\",New (paidPartial),new,paidPartial",
|
Assert.Contains("0,,\"Some \"\", description\",New (paidPartial),new,paidPartial",
|
||||||
paidresult.Content);
|
paidresult.Content);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2157,7 +2157,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal("paidPartial", localInvoice.ExceptionStatus.ToString());
|
Assert.Equal("paidPartial", localInvoice.ExceptionStatus.ToString());
|
||||||
Assert.Equal(1, localInvoice.CryptoInfo[0].TxCount);
|
Assert.Equal(1, localInvoice.CryptoInfo[0].TxCount);
|
||||||
Assert.NotEqual(localInvoice.BitcoinAddress, invoice.BitcoinAddress); //New address
|
Assert.NotEqual(localInvoice.BitcoinAddress, invoice.BitcoinAddress); //New address
|
||||||
Assert.True(IsMapped(invoice, ctx));
|
Assert.True(IsMapped(invoice, ctx));
|
||||||
Assert.True(IsMapped(localInvoice, ctx));
|
Assert.True(IsMapped(localInvoice, ctx));
|
||||||
|
|
||||||
invoiceEntity = repo.GetInvoice(invoice.Id, true).GetAwaiter().GetResult();
|
invoiceEntity = repo.GetInvoice(invoice.Id, true).GetAwaiter().GetResult();
|
||||||
@ -2175,7 +2175,7 @@ namespace BTCPayServer.Tests
|
|||||||
Assert.Equal(firstPayment + secondPayment, localInvoice.BtcPaid);
|
Assert.Equal(firstPayment + secondPayment, localInvoice.BtcPaid);
|
||||||
Assert.Equal(Money.Zero, localInvoice.BtcDue);
|
Assert.Equal(Money.Zero, localInvoice.BtcDue);
|
||||||
Assert.Equal(localInvoice.BitcoinAddress, invoiceAddress.ToString()); //no new address generated
|
Assert.Equal(localInvoice.BitcoinAddress, invoiceAddress.ToString()); //no new address generated
|
||||||
Assert.True(IsMapped(localInvoice, ctx));
|
Assert.True(IsMapped(localInvoice, ctx));
|
||||||
Assert.False((bool)((JValue)localInvoice.ExceptionStatus).Value);
|
Assert.False((bool)((JValue)localInvoice.ExceptionStatus).Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -26,9 +26,11 @@ public class AppSales : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(AppSalesViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(AppSalesViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.App == null) throw new ArgumentNullException(nameof(vm.App));
|
if (vm.App == null)
|
||||||
if (vm.InitialRendering) return View(vm);
|
throw new ArgumentNullException(nameof(vm.App));
|
||||||
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
var stats = await _appService.GetSalesStats(vm.App);
|
var stats = await _appService.GetSalesStats(vm.App);
|
||||||
|
|
||||||
vm.SalesCount = stats.SalesCount;
|
vm.SalesCount = stats.SalesCount;
|
||||||
|
@ -20,13 +20,15 @@ public class AppTopItems : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(AppTopItemsViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(AppTopItemsViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.App == null) throw new ArgumentNullException(nameof(vm.App));
|
if (vm.App == null)
|
||||||
if (vm.InitialRendering) return View(vm);
|
throw new ArgumentNullException(nameof(vm.App));
|
||||||
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
var entries = Enum.Parse<AppType>(vm.App.AppType) == AppType.Crowdfund
|
var entries = Enum.Parse<AppType>(vm.App.AppType) == AppType.Crowdfund
|
||||||
? await _appService.GetPerkStats(vm.App)
|
? await _appService.GetPerkStats(vm.App)
|
||||||
: await _appService.GetItemStats(vm.App);
|
: await _appService.GetItemStats(vm.App);
|
||||||
|
|
||||||
vm.Entries = entries.ToList();
|
vm.Entries = entries.ToList();
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
|
@ -76,7 +76,7 @@ namespace BTCPayServer.Components.MainNav
|
|||||||
AppName = a.AppName,
|
AppName = a.AppName,
|
||||||
AppType = Enum.Parse<AppType>(a.AppType)
|
AppType = Enum.Parse<AppType>(a.AppType)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
if (PoliciesSettings.Experimental)
|
if (PoliciesSettings.Experimental)
|
||||||
{
|
{
|
||||||
// Custodian Accounts
|
// Custodian Accounts
|
||||||
|
@ -47,26 +47,29 @@ public class StoreLightningBalance : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(StoreLightningBalanceViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(StoreLightningBalanceViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.Store == null) throw new ArgumentNullException(nameof(vm.Store));
|
if (vm.Store == null)
|
||||||
if (vm.CryptoCode == null) throw new ArgumentNullException(nameof(vm.CryptoCode));
|
throw new ArgumentNullException(nameof(vm.Store));
|
||||||
|
if (vm.CryptoCode == null)
|
||||||
|
throw new ArgumentNullException(nameof(vm.CryptoCode));
|
||||||
|
|
||||||
vm.DefaultCurrency = vm.Store.GetStoreBlob().DefaultCurrency;
|
vm.DefaultCurrency = vm.Store.GetStoreBlob().DefaultCurrency;
|
||||||
vm.CurrencyData = _currencies.GetCurrencyData(vm.DefaultCurrency, true);
|
vm.CurrencyData = _currencies.GetCurrencyData(vm.DefaultCurrency, true);
|
||||||
|
|
||||||
if (vm.InitialRendering) return View(vm);
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var lightningClient = GetLightningClient(vm.Store, vm.CryptoCode);
|
var lightningClient = GetLightningClient(vm.Store, vm.CryptoCode);
|
||||||
var balance = await lightningClient.GetBalance();
|
var balance = await lightningClient.GetBalance();
|
||||||
vm.Balance = balance;
|
vm.Balance = balance;
|
||||||
vm.TotalOnchain = balance.OnchainBalance != null
|
vm.TotalOnchain = balance.OnchainBalance != null
|
||||||
? (balance.OnchainBalance.Confirmed?? 0L) + (balance.OnchainBalance.Reserved ?? 0L) +
|
? (balance.OnchainBalance.Confirmed ?? 0L) + (balance.OnchainBalance.Reserved ?? 0L) +
|
||||||
(balance.OnchainBalance.Unconfirmed ?? 0L)
|
(balance.OnchainBalance.Unconfirmed ?? 0L)
|
||||||
: null;
|
: null;
|
||||||
vm.TotalOffchain = balance.OffchainBalance != null
|
vm.TotalOffchain = balance.OffchainBalance != null
|
||||||
? (balance.OffchainBalance.Opening?? 0) + (balance.OffchainBalance.Local?? 0) +
|
? (balance.OffchainBalance.Opening ?? 0) + (balance.OffchainBalance.Local ?? 0) +
|
||||||
(balance.OffchainBalance.Closing?? 0)
|
(balance.OffchainBalance.Closing ?? 0)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
catch (NotSupportedException)
|
catch (NotSupportedException)
|
||||||
@ -81,7 +84,7 @@ public class StoreLightningBalance : ViewComponent
|
|||||||
}
|
}
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILightningClient GetLightningClient(StoreData store, string cryptoCode)
|
private ILightningClient GetLightningClient(StoreData store, string cryptoCode)
|
||||||
{
|
{
|
||||||
var network = _networkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
var network = _networkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||||
@ -89,9 +92,10 @@ public class StoreLightningBalance : ViewComponent
|
|||||||
var existing = store.GetSupportedPaymentMethods(_networkProvider)
|
var existing = store.GetSupportedPaymentMethods(_networkProvider)
|
||||||
.OfType<LightningSupportedPaymentMethod>()
|
.OfType<LightningSupportedPaymentMethod>()
|
||||||
.FirstOrDefault(d => d.PaymentId == id);
|
.FirstOrDefault(d => d.PaymentId == id);
|
||||||
if (existing == null) return null;
|
if (existing == null)
|
||||||
|
return null;
|
||||||
if (existing.GetExternalLightningUrl() is {} connectionString)
|
|
||||||
|
if (existing.GetExternalLightningUrl() is { } connectionString)
|
||||||
{
|
{
|
||||||
return _lightningClientFactory.Create(connectionString, network);
|
return _lightningClientFactory.Create(connectionString, network);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,14 @@ public class StoreLightningServices : ViewComponent
|
|||||||
|
|
||||||
public IViewComponentResult Invoke(StoreLightningServicesViewModel vm)
|
public IViewComponentResult Invoke(StoreLightningServicesViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.Store == null) throw new ArgumentNullException(nameof(vm.Store));
|
if (vm.Store == null)
|
||||||
if (vm.CryptoCode == null) throw new ArgumentNullException(nameof(vm.CryptoCode));
|
throw new ArgumentNullException(nameof(vm.Store));
|
||||||
if (vm.LightningNodeType != LightningNodeType.Internal) return View(vm);
|
if (vm.CryptoCode == null)
|
||||||
if (!User.IsInRole(Roles.ServerAdmin)) return View(vm);
|
throw new ArgumentNullException(nameof(vm.CryptoCode));
|
||||||
|
if (vm.LightningNodeType != LightningNodeType.Internal)
|
||||||
|
return View(vm);
|
||||||
|
if (!User.IsInRole(Roles.ServerAdmin))
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
var services = _externalServiceOptions.Value.ExternalServices.ToList()
|
var services = _externalServiceOptions.Value.ExternalServices.ToList()
|
||||||
.Where(service => ExternalServices.LightningServiceTypes.Contains(service.Type))
|
.Where(service => ExternalServices.LightningServiceTypes.Contains(service.Type))
|
||||||
@ -62,7 +66,7 @@ public class StoreLightningServices : ViewComponent
|
|||||||
})
|
})
|
||||||
.Select(t => t.Result)
|
.Select(t => t.Result)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// other services
|
// other services
|
||||||
foreach ((string key, Uri value) in _externalServiceOptions.Value.OtherExternalServices)
|
foreach ((string key, Uri value) in _externalServiceOptions.Value.OtherExternalServices)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Dapper;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -9,6 +8,7 @@ using BTCPayServer.Data;
|
|||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
|
using Dapper;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -41,13 +41,16 @@ public class StoreNumbers : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(StoreNumbersViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(StoreNumbersViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.Store == null) throw new ArgumentNullException(nameof(vm.Store));
|
if (vm.Store == null)
|
||||||
if (vm.CryptoCode == null) throw new ArgumentNullException(nameof(vm.CryptoCode));
|
throw new ArgumentNullException(nameof(vm.Store));
|
||||||
|
if (vm.CryptoCode == null)
|
||||||
|
throw new ArgumentNullException(nameof(vm.CryptoCode));
|
||||||
|
|
||||||
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode);
|
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode);
|
||||||
|
|
||||||
if (vm.InitialRendering) return View(vm);
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
await using var ctx = _dbContextFactory.CreateContext();
|
await using var ctx = _dbContextFactory.CreateContext();
|
||||||
var payoutsCount = await ctx.Payouts
|
var payoutsCount = await ctx.Payouts
|
||||||
.Where(p => p.PullPaymentData.StoreId == vm.Store.Id && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingApproval)
|
.Where(p => p.PullPaymentData.StoreId == vm.Store.Id && !p.PullPaymentData.Archived && p.State == PayoutState.AwaitingApproval)
|
||||||
@ -55,7 +58,7 @@ public class StoreNumbers : ViewComponent
|
|||||||
var refundsCount = await ctx.Invoices
|
var refundsCount = await ctx.Invoices
|
||||||
.Where(i => i.StoreData.Id == vm.Store.Id && !i.Archived && i.CurrentRefundId != null)
|
.Where(i => i.StoreData.Id == vm.Store.Id && !i.Archived && i.CurrentRefundId != null)
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
|
|
||||||
var derivation = vm.Store.GetDerivationSchemeSettings(_networkProvider, vm.CryptoCode);
|
var derivation = vm.Store.GetDerivationSchemeSettings(_networkProvider, vm.CryptoCode);
|
||||||
int? transactionsCount = null;
|
int? transactionsCount = null;
|
||||||
if (derivation != null && _nbxConnectionFactory.Available)
|
if (derivation != null && _nbxConnectionFactory.Available)
|
||||||
|
@ -35,31 +35,34 @@ public class StoreRecentInvoices : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(StoreRecentInvoicesViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(StoreRecentInvoicesViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.Store == null) throw new ArgumentNullException(nameof(vm.Store));
|
if (vm.Store == null)
|
||||||
if (vm.CryptoCode == null) throw new ArgumentNullException(nameof(vm.CryptoCode));
|
throw new ArgumentNullException(nameof(vm.Store));
|
||||||
if (vm.InitialRendering) return View(vm);
|
if (vm.CryptoCode == null)
|
||||||
|
throw new ArgumentNullException(nameof(vm.CryptoCode));
|
||||||
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
var userId = _userManager.GetUserId(UserClaimsPrincipal);
|
var userId = _userManager.GetUserId(UserClaimsPrincipal);
|
||||||
var invoiceEntities = await _invoiceRepo.GetInvoices(new InvoiceQuery
|
var invoiceEntities = await _invoiceRepo.GetInvoices(new InvoiceQuery
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
StoreId = new [] { vm.Store.Id },
|
StoreId = new[] { vm.Store.Id },
|
||||||
IncludeArchived = false,
|
IncludeArchived = false,
|
||||||
IncludeRefunds = true,
|
IncludeRefunds = true,
|
||||||
Take = 5
|
Take = 5
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.Invoices = (from invoice in invoiceEntities
|
vm.Invoices = (from invoice in invoiceEntities
|
||||||
let state = invoice.GetInvoiceState()
|
let state = invoice.GetInvoiceState()
|
||||||
select new StoreRecentInvoiceViewModel
|
select new StoreRecentInvoiceViewModel
|
||||||
{
|
{
|
||||||
Date = invoice.InvoiceTime,
|
Date = invoice.InvoiceTime,
|
||||||
Status = state,
|
Status = state,
|
||||||
HasRefund = invoice.Refunds.Any(),
|
HasRefund = invoice.Refunds.Any(),
|
||||||
InvoiceId = invoice.Id,
|
InvoiceId = invoice.Id,
|
||||||
OrderId = invoice.Metadata.OrderId ?? string.Empty,
|
OrderId = invoice.Metadata.OrderId ?? string.Empty,
|
||||||
AmountCurrency = _currencyNameTable.DisplayFormatCurrency(invoice.Price, invoice.Currency),
|
AmountCurrency = _currencyNameTable.DisplayFormatCurrency(invoice.Price, invoice.Currency),
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Abstractions.Extensions;
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services;
|
|
||||||
using BTCPayServer.Models.StoreViewModels;
|
using BTCPayServer.Models.StoreViewModels;
|
||||||
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using Dapper;
|
|
||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
|
using Dapper;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NBXplorer.Client;
|
|
||||||
using static BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
using NBXplorer.Client;
|
||||||
|
using static BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel;
|
||||||
|
|
||||||
namespace BTCPayServer.Components.StoreRecentTransactions;
|
namespace BTCPayServer.Components.StoreRecentTransactions;
|
||||||
|
|
||||||
@ -35,13 +35,16 @@ public class StoreRecentTransactions : ViewComponent
|
|||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(StoreRecentTransactionsViewModel vm)
|
public async Task<IViewComponentResult> InvokeAsync(StoreRecentTransactionsViewModel vm)
|
||||||
{
|
{
|
||||||
if (vm.Store == null) throw new ArgumentNullException(nameof(vm.Store));
|
if (vm.Store == null)
|
||||||
if (vm.CryptoCode == null) throw new ArgumentNullException(nameof(vm.CryptoCode));
|
throw new ArgumentNullException(nameof(vm.Store));
|
||||||
|
if (vm.CryptoCode == null)
|
||||||
|
throw new ArgumentNullException(nameof(vm.CryptoCode));
|
||||||
|
|
||||||
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode);
|
vm.WalletId = new WalletId(vm.Store.Id, vm.CryptoCode);
|
||||||
|
|
||||||
if (vm.InitialRendering) return View(vm);
|
if (vm.InitialRendering)
|
||||||
|
return View(vm);
|
||||||
|
|
||||||
var derivationSettings = vm.Store.GetDerivationSchemeSettings(NetworkProvider, vm.CryptoCode);
|
var derivationSettings = vm.Store.GetDerivationSchemeSettings(NetworkProvider, vm.CryptoCode);
|
||||||
var transactions = new List<StoreRecentTransactionViewModel>();
|
var transactions = new List<StoreRecentTransactionViewModel>();
|
||||||
if (derivationSettings?.AccountDerivation is not null)
|
if (derivationSettings?.AccountDerivation is not null)
|
||||||
@ -63,7 +66,7 @@ public class StoreRecentTransactions : ViewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm.Transactions = transactions;
|
vm.Transactions = transactions;
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class StoreWalletBalance : ViewComponent
|
|||||||
public StoreWalletBalance(
|
public StoreWalletBalance(
|
||||||
StoreRepository storeRepo,
|
StoreRepository storeRepo,
|
||||||
CurrencyNameTable currencies,
|
CurrencyNameTable currencies,
|
||||||
WalletHistogramService walletHistogramService,
|
WalletHistogramService walletHistogramService,
|
||||||
BTCPayWalletProvider walletProvider,
|
BTCPayWalletProvider walletProvider,
|
||||||
BTCPayNetworkProvider networkProvider)
|
BTCPayNetworkProvider networkProvider)
|
||||||
{
|
{
|
||||||
@ -50,7 +50,7 @@ public class StoreWalletBalance : ViewComponent
|
|||||||
var walletId = new WalletId(store.Id, cryptoCode);
|
var walletId = new WalletId(store.Id, cryptoCode);
|
||||||
var data = await _walletHistogramService.GetHistogram(store, walletId, DefaultType);
|
var data = await _walletHistogramService.GetHistogram(store, walletId, DefaultType);
|
||||||
var defaultCurrency = store.GetStoreBlob().DefaultCurrency;
|
var defaultCurrency = store.GetStoreBlob().DefaultCurrency;
|
||||||
|
|
||||||
var vm = new StoreWalletBalanceViewModel
|
var vm = new StoreWalletBalanceViewModel
|
||||||
{
|
{
|
||||||
Store = store,
|
Store = store,
|
||||||
@ -69,7 +69,7 @@ public class StoreWalletBalance : ViewComponent
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using CancellationTokenSource cts = new (TimeSpan.FromSeconds(3));
|
using CancellationTokenSource cts = new(TimeSpan.FromSeconds(3));
|
||||||
var wallet = _walletProvider.GetWallet(_networkProvider.DefaultNetwork);
|
var wallet = _walletProvider.GetWallet(_networkProvider.DefaultNetwork);
|
||||||
var derivation = store.GetDerivationSchemeSettings(_networkProvider, walletId.CryptoCode);
|
var derivation = store.GetDerivationSchemeSettings(_networkProvider, walletId.CryptoCode);
|
||||||
if (derivation is not null)
|
if (derivation is not null)
|
||||||
|
@ -42,7 +42,7 @@ namespace BTCPayServer.Components.WalletNav
|
|||||||
var wallet = _walletProvider.GetWallet(network);
|
var wallet = _walletProvider.GetWallet(network);
|
||||||
var derivation = store.GetDerivationSchemeSettings(_networkProvider, walletId.CryptoCode);
|
var derivation = store.GetDerivationSchemeSettings(_networkProvider, walletId.CryptoCode);
|
||||||
var balance = await _walletsController.GetBalanceString(wallet, derivation?.AccountDerivation);
|
var balance = await _walletsController.GetBalanceString(wallet, derivation?.AccountDerivation);
|
||||||
|
|
||||||
var vm = new WalletNavViewModel
|
var vm = new WalletNavViewModel
|
||||||
{
|
{
|
||||||
WalletId = walletId,
|
WalletId = walletId,
|
||||||
|
@ -97,7 +97,7 @@ namespace BTCPayServer.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectionString.CookieFilePath = null;
|
connectionString.CookieFilePath = null;
|
||||||
|
|
||||||
if (serviceType == ExternalServiceTypes.RTL || serviceType == ExternalServiceTypes.Configurator ||
|
if (serviceType == ExternalServiceTypes.RTL || serviceType == ExternalServiceTypes.Configurator ||
|
||||||
serviceType == ExternalServiceTypes.ThunderHub || serviceType == ExternalServiceTypes.Torq)
|
serviceType == ExternalServiceTypes.ThunderHub || serviceType == ExternalServiceTypes.Torq)
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ namespace BTCPayServer.Configuration
|
|||||||
&&
|
&&
|
||||||
o.ServiceName.Equals(serviceName, StringComparison.OrdinalIgnoreCase));
|
o.ServiceName.Equals(serviceName, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly ExternalServiceTypes[] LightningServiceTypes =
|
public static readonly ExternalServiceTypes[] LightningServiceTypes =
|
||||||
{
|
{
|
||||||
ExternalServiceTypes.Spark,
|
ExternalServiceTypes.Spark,
|
||||||
@ -100,7 +100,7 @@ namespace BTCPayServer.Configuration
|
|||||||
ExternalServiceTypes.ThunderHub,
|
ExternalServiceTypes.ThunderHub,
|
||||||
ExternalServiceTypes.Torq
|
ExternalServiceTypes.Torq
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly string[] LightningServiceNames =
|
public static readonly string[] LightningServiceNames =
|
||||||
{
|
{
|
||||||
"Lightning Terminal"
|
"Lightning Terminal"
|
||||||
@ -114,7 +114,7 @@ namespace BTCPayServer.Configuration
|
|||||||
public ExternalConnectionString ConnectionString { get; set; }
|
public ExternalConnectionString ConnectionString { get; set; }
|
||||||
public string CryptoCode { get; set; }
|
public string CryptoCode { get; set; }
|
||||||
public string ServiceName { get; set; }
|
public string ServiceName { get; set; }
|
||||||
|
|
||||||
public async Task<string> GetLink(Uri absoluteUriNoPathBase, ChainName networkType)
|
public async Task<string> GetLink(Uri absoluteUriNoPathBase, ChainName networkType)
|
||||||
{
|
{
|
||||||
var connectionString = await ConnectionString.Expand(absoluteUriNoPathBase, Type, networkType);
|
var connectionString = await ConnectionString.Expand(absoluteUriNoPathBase, Type, networkType);
|
||||||
|
@ -25,7 +25,7 @@ namespace BTCPayServer.Controllers
|
|||||||
[Authorize(Policy = ServerPolicies.CanGetRates.Key, AuthenticationSchemes = AuthenticationSchemes.Bitpay)]
|
[Authorize(Policy = ServerPolicies.CanGetRates.Key, AuthenticationSchemes = AuthenticationSchemes.Bitpay)]
|
||||||
public class BitpayRateController : Controller
|
public class BitpayRateController : Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
readonly RateFetcher _rateProviderFactory;
|
readonly RateFetcher _rateProviderFactory;
|
||||||
readonly BTCPayNetworkProvider _networkProvider;
|
readonly BTCPayNetworkProvider _networkProvider;
|
||||||
readonly CurrencyNameTable _currencyNameTable;
|
readonly CurrencyNameTable _currencyNameTable;
|
||||||
@ -67,7 +67,7 @@ namespace BTCPayServer.Controllers
|
|||||||
public async Task<IActionResult> GetCurrencyPairRate(string baseCurrency, string currency, CancellationToken cancellationToken)
|
public async Task<IActionResult> GetCurrencyPairRate(string baseCurrency, string currency, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await GetRates2($"{baseCurrency}_{currency}", null, cancellationToken);
|
var result = await GetRates2($"{baseCurrency}_{currency}", null, cancellationToken);
|
||||||
return (result as JsonResult)?.Value is not Rate[] rates
|
return (result as JsonResult)?.Value is not Rate[] rates
|
||||||
? result
|
? result
|
||||||
: Json(new DataWrapper<Rate>(rates.First()));
|
: Json(new DataWrapper<Rate>(rates.First()));
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
[JsonProperty(PropertyName = "name")]
|
[JsonProperty(PropertyName = "name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "cryptoCode")]
|
[JsonProperty(PropertyName = "cryptoCode")]
|
||||||
public string CryptoCode { get; set; }
|
public string CryptoCode { get; set; }
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
[JsonProperty(PropertyName = "code")]
|
[JsonProperty(PropertyName = "code")]
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "rate")]
|
[JsonProperty(PropertyName = "rate")]
|
||||||
public decimal Value { get; set; }
|
public decimal Value { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Abstractions.Constants;
|
using BTCPayServer.Abstractions.Constants;
|
||||||
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using BTCPayServer.Services.Rates;
|
using BTCPayServer.Services.Rates;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using BTCPayServer.Abstractions.Extensions;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@ -86,7 +86,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return validationResult;
|
return validationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
var appData = new AppData
|
var appData = new AppData
|
||||||
{
|
{
|
||||||
StoreDataId = storeId,
|
StoreDataId = storeId,
|
||||||
@ -112,7 +112,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
}
|
}
|
||||||
|
|
||||||
var settings = app.GetSettings<PointOfSaleSettings>();
|
var settings = app.GetSettings<PointOfSaleSettings>();
|
||||||
|
|
||||||
// This is not obvious but we must have a non-null currency or else request validation may work incorrectly
|
// This is not obvious but we must have a non-null currency or else request validation may work incorrectly
|
||||||
request.Currency = request.Currency ?? settings.Currency;
|
request.Currency = request.Currency ?? settings.Currency;
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
app.Name = request.AppName;
|
app.Name = request.AppName;
|
||||||
app.SetSettings(ToPointOfSaleSettings(request));
|
app.SetSettings(ToPointOfSaleSettings(request));
|
||||||
|
|
||||||
await _appService.UpdateOrCreateApp(app);
|
await _appService.UpdateOrCreateApp(app);
|
||||||
|
|
||||||
return Ok(ToPointOfSaleModel(app));
|
return Ok(ToPointOfSaleModel(app));
|
||||||
@ -152,7 +152,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return AppNotFound();
|
return AppNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(ToModel(app));
|
return Ok(ToModel(app));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return AppNotFound();
|
return AppNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _appService.DeleteApp(app);
|
await _appService.DeleteApp(app);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
@ -281,7 +281,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
ModelState.AddModelError(nameof(request.Template), "Invalid template");
|
ModelState.AddModelError(nameof(request.Template), "Invalid template");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
validationResult = this.CreateValidationError(ModelState);
|
validationResult = this.CreateValidationError(ModelState);
|
||||||
@ -304,7 +304,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
private string[]? ValidateStringArray(string[]? arr)
|
private string[]? ValidateStringArray(string[]? arr)
|
||||||
{
|
{
|
||||||
if (arr == null || !arr.Any())
|
if (arr == null || !arr.Any())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -359,7 +359,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
ModelState.AddModelError(nameof(request.EndDate), "End date cannot be before start date");
|
ModelState.AddModelError(nameof(request.EndDate), "End date cannot be before start date");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
validationResult = this.CreateValidationError(ModelState);
|
validationResult = this.CreateValidationError(ModelState);
|
||||||
|
@ -91,7 +91,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
var custodianAccount = await ToModel(custodianAccountData, assetBalances, cancellationToken);
|
var custodianAccount = await ToModel(custodianAccountData, assetBalances, cancellationToken);
|
||||||
return Ok(custodianAccount);
|
return Ok(custodianAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [HttpGet("~/api/v1/stores/{storeId}/custodian-accounts/{accountId}/config")]
|
// [HttpGet("~/api/v1/stores/{storeId}/custodian-accounts/{accountId}/config")]
|
||||||
// [Authorize(Policy = Policies.CanManageCustodianAccounts,
|
// [Authorize(Policy = Policies.CanManageCustodianAccounts,
|
||||||
// AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
// AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
@ -276,7 +276,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
}
|
}
|
||||||
catch (CustodianApiException e)
|
catch (CustodianApiException e)
|
||||||
{
|
{
|
||||||
return this.CreateAPIError(e.HttpStatus, e.Code,
|
return this.CreateAPIError(e.HttpStatus, e.Code,
|
||||||
e.Message);
|
e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ using BTCPayServer.Client.Models;
|
|||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
using BTCPayServer.Payments;
|
using BTCPayServer.Payments;
|
||||||
|
using BTCPayServer.Rating;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using BTCPayServer.Services.Rates;
|
using BTCPayServer.Services.Rates;
|
||||||
using BTCPayServer.Rating;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -425,21 +425,22 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
createPullPayment.Amount = cryptoPaid.RoundToSignificant(paymentMethodDivisibility);
|
createPullPayment.Amount = cryptoPaid.RoundToSignificant(paymentMethodDivisibility);
|
||||||
createPullPayment.AutoApproveClaims = true;
|
createPullPayment.AutoApproveClaims = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefundVariant.CurrentRate:
|
case RefundVariant.CurrentRate:
|
||||||
createPullPayment.Currency = invoicePaymentMethod.GetId().CryptoCode;
|
createPullPayment.Currency = invoicePaymentMethod.GetId().CryptoCode;
|
||||||
createPullPayment.Amount = Math.Round(paidCurrency / rateResult.BidAsk.Bid, paymentMethodDivisibility);
|
createPullPayment.Amount = Math.Round(paidCurrency / rateResult.BidAsk.Bid, paymentMethodDivisibility);
|
||||||
createPullPayment.AutoApproveClaims = true;
|
createPullPayment.AutoApproveClaims = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefundVariant.Fiat:
|
case RefundVariant.Fiat:
|
||||||
createPullPayment.Currency = invoice.Currency;
|
createPullPayment.Currency = invoice.Currency;
|
||||||
createPullPayment.Amount = paidCurrency;
|
createPullPayment.Amount = paidCurrency;
|
||||||
createPullPayment.AutoApproveClaims = false;
|
createPullPayment.AutoApproveClaims = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefundVariant.Custom:
|
case RefundVariant.Custom:
|
||||||
if (request.CustomAmount is null || (request.CustomAmount is decimal v && v <= 0)) {
|
if (request.CustomAmount is null || (request.CustomAmount is decimal v && v <= 0))
|
||||||
|
{
|
||||||
this.ModelState.AddModelError(nameof(request.CustomAmount), "Amount must be greater than 0");
|
this.ModelState.AddModelError(nameof(request.CustomAmount), "Amount must be greater than 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,14 +467,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
createPullPayment.Amount = request.CustomAmount.Value;
|
createPullPayment.Amount = request.CustomAmount.Value;
|
||||||
createPullPayment.AutoApproveClaims = paymentMethodId.CryptoCode == request.CustomCurrency;
|
createPullPayment.AutoApproveClaims = paymentMethodId.CryptoCode == request.CustomCurrency;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ModelState.AddModelError(nameof(request.RefundVariant), "Please select a valid refund option");
|
ModelState.AddModelError(nameof(request.RefundVariant), "Please select a valid refund option");
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ppId = await _pullPaymentService.CreatePullPayment(createPullPayment);
|
var ppId = await _pullPaymentService.CreatePullPayment(createPullPayment);
|
||||||
|
|
||||||
await using var ctx = _dbContextFactory.CreateContext();
|
await using var ctx = _dbContextFactory.CreateContext();
|
||||||
(await ctx.Invoices.FindAsync(new[] { invoice.Id }, cancellationToken))!.CurrentRefundId = ppId;
|
(await ctx.Invoices.FindAsync(new[] { invoice.Id }, cancellationToken))!.CurrentRefundId = ppId;
|
||||||
ctx.Refunds.Add(new RefundData
|
ctx.Refunds.Add(new RefundData
|
||||||
@ -599,7 +600,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
Amount = entity.Price,
|
Amount = entity.Price,
|
||||||
Type = entity.Type,
|
Type = entity.Type,
|
||||||
Id = entity.Id,
|
Id = entity.Id,
|
||||||
CheckoutLink = request is null? null: linkGenerator.CheckoutLink(entity.Id, request.Scheme, request.Host, request.PathBase),
|
CheckoutLink = request is null ? null : linkGenerator.CheckoutLink(entity.Id, request.Scheme, request.Host, request.PathBase),
|
||||||
Status = entity.Status.ToModernStatus(),
|
Status = entity.Status.ToModernStatus(),
|
||||||
AdditionalStatus = entity.ExceptionStatus,
|
AdditionalStatus = entity.ExceptionStatus,
|
||||||
Currency = entity.Currency,
|
Currency = entity.Currency,
|
||||||
|
@ -40,7 +40,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
_lightningClientFactory = lightningClientFactory;
|
_lightningClientFactory = lightningClientFactory;
|
||||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = Policies.CanUseLightningNodeInStore,
|
[Authorize(Policy = Policies.CanUseLightningNodeInStore,
|
||||||
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
[HttpGet("~/api/v1/stores/{storeId}/lightning/{cryptoCode}/info")]
|
[HttpGet("~/api/v1/stores/{storeId}/lightning/{cryptoCode}/info")]
|
||||||
@ -135,13 +135,13 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
throw ErrorCryptoCodeNotFound();
|
throw ErrorCryptoCodeNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var store = HttpContext.GetStoreData();
|
var store = HttpContext.GetStoreData();
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
throw new JsonHttpException(StoreNotFound());
|
throw new JsonHttpException(StoreNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
||||||
var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider)
|
var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider)
|
||||||
.OfType<LightningSupportedPaymentMethod>()
|
.OfType<LightningSupportedPaymentMethod>()
|
||||||
@ -164,7 +164,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
}
|
}
|
||||||
throw ErrorLightningNodeNotConfiguredForStore();
|
throw ErrorLightningNodeNotConfiguredForStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IActionResult StoreNotFound()
|
private IActionResult StoreNotFound()
|
||||||
{
|
{
|
||||||
return this.CreateAPIError(404, "store-not-found", "The store was not found");
|
return this.CreateAPIError(404, "store-not-found", "The store was not found");
|
||||||
|
@ -23,7 +23,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
// Do not mark handled, it is possible filters above have better errors
|
// Do not mark handled, it is possible filters above have better errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class GreenfieldLightningNodeApiController : Controller
|
public abstract class GreenfieldLightningNodeApiController : Controller
|
||||||
{
|
{
|
||||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||||
@ -209,7 +209,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
var lightningClient = await GetLightningClient(cryptoCode, true);
|
var lightningClient = await GetLightningClient(cryptoCode, true);
|
||||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||||
BOLT11PaymentRequest bolt11 = null;
|
BOLT11PaymentRequest bolt11 = null;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(lightningInvoice.BOLT11) ||
|
if (string.IsNullOrEmpty(lightningInvoice.BOLT11) ||
|
||||||
!BOLT11PaymentRequest.TryParse(lightningInvoice.BOLT11, out bolt11, network.NBitcoinNetwork))
|
!BOLT11PaymentRequest.TryParse(lightningInvoice.BOLT11, out bolt11, network.NBitcoinNetwork))
|
||||||
{
|
{
|
||||||
@ -220,7 +220,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
var param = lightningInvoice.MaxFeeFlat != null || lightningInvoice.MaxFeePercent != null
|
var param = lightningInvoice.MaxFeeFlat != null || lightningInvoice.MaxFeePercent != null
|
||||||
|| lightningInvoice.Amount != null || lightningInvoice.SendTimeout != null
|
|| lightningInvoice.Amount != null || lightningInvoice.SendTimeout != null
|
||||||
? new PayInvoiceParams
|
? new PayInvoiceParams
|
||||||
@ -232,12 +232,12 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
var result = await lightningClient.Pay(lightningInvoice.BOLT11, param, cancellationToken);
|
var result = await lightningClient.Pay(lightningInvoice.BOLT11, param, cancellationToken);
|
||||||
|
|
||||||
if (result.Result is PayResult.Ok or PayResult.Unknown && bolt11?.PaymentHash is not null)
|
if (result.Result is PayResult.Ok or PayResult.Unknown && bolt11?.PaymentHash is not null)
|
||||||
{
|
{
|
||||||
// get a new instance of the LN client, because the old one might have disposed its HTTPClient
|
// get a new instance of the LN client, because the old one might have disposed its HTTPClient
|
||||||
lightningClient = await GetLightningClient(cryptoCode, true);
|
lightningClient = await GetLightningClient(cryptoCode, true);
|
||||||
|
|
||||||
var paymentHash = bolt11.PaymentHash.ToString();
|
var paymentHash = bolt11.PaymentHash.ToString();
|
||||||
var payment = await lightningClient.GetPayment(paymentHash, cancellationToken);
|
var payment = await lightningClient.GetPayment(paymentHash, cancellationToken);
|
||||||
var data = new LightningPaymentData
|
var data = new LightningPaymentData
|
||||||
@ -253,7 +253,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
};
|
};
|
||||||
return result.Result is PayResult.Ok ? Ok(data) : Accepted(data);
|
return result.Result is PayResult.Ok ? Ok(data) : Accepted(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.Result switch
|
return result.Result switch
|
||||||
{
|
{
|
||||||
PayResult.CouldNotFindRoute => this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer"),
|
PayResult.CouldNotFindRoute => this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer"),
|
||||||
@ -265,7 +265,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
PayResult.Ok => Ok(new LightningPaymentData
|
PayResult.Ok => Ok(new LightningPaymentData
|
||||||
{
|
{
|
||||||
Status = LightningPaymentStatus.Complete,
|
Status = LightningPaymentStatus.Complete,
|
||||||
TotalAmount = result.Details?.TotalAmount,
|
TotalAmount = result.Details?.TotalAmount,
|
||||||
FeeAmount = result.Details?.FeeAmount
|
FeeAmount = result.Details?.FeeAmount
|
||||||
}),
|
}),
|
||||||
_ => throw new NotSupportedException("Unsupported PayResult")
|
_ => throw new NotSupportedException("Unsupported PayResult")
|
||||||
@ -308,14 +308,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Description ??= "";
|
request.Description ??= "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var param = new CreateInvoiceParams(request.Amount, request.Description, request.Expiry)
|
var param = new CreateInvoiceParams(request.Amount, request.Description, request.Expiry)
|
||||||
{
|
{
|
||||||
PrivateRouteHints = request.PrivateRouteHints,
|
PrivateRouteHints = request.PrivateRouteHints,
|
||||||
DescriptionHashOnly = request.DescriptionHashOnly
|
DescriptionHashOnly = request.DescriptionHashOnly
|
||||||
};
|
};
|
||||||
var invoice = await lightningClient.CreateInvoice(param, cancellationToken);
|
var invoice = await lightningClient.CreateInvoice(param, cancellationToken);
|
||||||
return Ok(ToModel(invoice));
|
return Ok(ToModel(invoice));
|
||||||
|
@ -20,7 +20,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
private readonly IEnumerable<IPayoutProcessorFactory> _factories;
|
private readonly IEnumerable<IPayoutProcessorFactory> _factories;
|
||||||
|
|
||||||
public GreenfieldPayoutProcessorsController(IEnumerable<IPayoutProcessorFactory>factories)
|
public GreenfieldPayoutProcessorsController(IEnumerable<IPayoutProcessorFactory> factories)
|
||||||
{
|
{
|
||||||
_factories = factories;
|
_factories = factories;
|
||||||
}
|
}
|
||||||
@ -39,5 +39,5 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -199,10 +199,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
var pp = await _pullPaymentService.GetPullPayment(pullPaymentId, true);
|
var pp = await _pullPaymentService.GetPullPayment(pullPaymentId, true);
|
||||||
if (pp is null)
|
if (pp is null)
|
||||||
return PullPaymentNotFound();
|
return PullPaymentNotFound();
|
||||||
|
|
||||||
var payouts =await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
var payouts = await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
||||||
{
|
{
|
||||||
PullPayments = new[] {pullPaymentId},
|
PullPayments = new[] { pullPaymentId },
|
||||||
States = GetStateFilter(includeCancelled)
|
States = GetStateFilter(includeCancelled)
|
||||||
});
|
});
|
||||||
return base.Ok(payouts
|
return base.Ok(payouts
|
||||||
@ -219,10 +219,11 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
var payout = (await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
var payout = (await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
||||||
{
|
{
|
||||||
PullPayments = new[] {pullPaymentId}, PayoutIds = new[] {payoutId}
|
PullPayments = new[] { pullPaymentId },
|
||||||
|
PayoutIds = new[] { payoutId }
|
||||||
})).FirstOrDefault();
|
})).FirstOrDefault();
|
||||||
|
|
||||||
|
|
||||||
if (payout is null)
|
if (payout is null)
|
||||||
return PayoutNotFound();
|
return PayoutNotFound();
|
||||||
return base.Ok(ToModel(payout));
|
return base.Ok(ToModel(payout));
|
||||||
@ -291,17 +292,17 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
ModelState.AddModelError(nameof(request.Amount), $"Amount too small (should be at least {ppBlob.MinimumClaim})");
|
ModelState.AddModelError(nameof(request.Amount), $"Amount too small (should be at least {ppBlob.MinimumClaim})");
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
}
|
}
|
||||||
var result = await _pullPaymentService.Claim(new ClaimRequest()
|
var result = await _pullPaymentService.Claim(new ClaimRequest()
|
||||||
{
|
{
|
||||||
Destination = destination.destination,
|
Destination = destination.destination,
|
||||||
PullPaymentId = pullPaymentId,
|
PullPaymentId = pullPaymentId,
|
||||||
Value = request.Amount,
|
Value = request.Amount,
|
||||||
PaymentMethodId = paymentMethodId,
|
PaymentMethodId = paymentMethodId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return HandleClaimResult(result);
|
return HandleClaimResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("~/api/v1/stores/{storeId}/payouts")]
|
[HttpPost("~/api/v1/stores/{storeId}/payouts")]
|
||||||
[Authorize(Policy = Policies.CanManagePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanManagePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
public async Task<IActionResult> CreatePayoutThroughStore(string storeId, CreatePayoutThroughStoreRequest request)
|
public async Task<IActionResult> CreatePayoutThroughStore(string storeId, CreatePayoutThroughStoreRequest request)
|
||||||
@ -413,11 +414,11 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
var payouts = await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
var payouts = await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
||||||
{
|
{
|
||||||
Stores = new[] {storeId},
|
Stores = new[] { storeId },
|
||||||
States = GetStateFilter(includeCancelled)
|
States = GetStateFilter(includeCancelled)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return base.Ok(payouts
|
return base.Ok(payouts
|
||||||
.Select(ToModel).ToArray());
|
.Select(ToModel).ToArray());
|
||||||
}
|
}
|
||||||
@ -426,7 +427,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
[Authorize(Policy = Policies.CanManagePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanManagePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
public async Task<IActionResult> CancelPayout(string storeId, string payoutId)
|
public async Task<IActionResult> CancelPayout(string storeId, string payoutId)
|
||||||
{
|
{
|
||||||
var res= await _pullPaymentService.Cancel(new PullPaymentHostedService.CancelRequest(new[] { payoutId }, new []{storeId}));
|
var res = await _pullPaymentService.Cancel(new PullPaymentHostedService.CancelRequest(new[] { payoutId }, new[] { storeId }));
|
||||||
return MapResult(res.First().Value);
|
return MapResult(res.First().Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,14 +531,15 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
var payout = (await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
var payout = (await _pullPaymentService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
|
||||||
{
|
{
|
||||||
Stores = new[] {storeId}, PayoutIds = new[] {payoutId}
|
Stores = new[] { storeId },
|
||||||
|
PayoutIds = new[] { payoutId }
|
||||||
})).FirstOrDefault();
|
})).FirstOrDefault();
|
||||||
|
|
||||||
if (payout is null)
|
if (payout is null)
|
||||||
return PayoutNotFound();
|
return PayoutNotFound();
|
||||||
return base.Ok(ToModel(payout));
|
return base.Ok(ToModel(payout));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IActionResult MapResult(MarkPayoutRequest.PayoutPaidResult result)
|
private IActionResult MapResult(MarkPayoutRequest.PayoutPaidResult result)
|
||||||
{
|
{
|
||||||
var errorMessage = MarkPayoutRequest.GetErrorMessage(result);
|
var errorMessage = MarkPayoutRequest.GetErrorMessage(result);
|
||||||
|
@ -42,9 +42,9 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
await _payoutProcessorService.GetProcessors(
|
await _payoutProcessorService.GetProcessors(
|
||||||
new PayoutProcessorService.PayoutProcessorQuery()
|
new PayoutProcessorService.PayoutProcessorQuery()
|
||||||
{
|
{
|
||||||
Stores = new[] {storeId},
|
Stores = new[] { storeId },
|
||||||
Processors = new[] {LightningAutomatedPayoutSenderFactory.ProcessorName},
|
Processors = new[] { LightningAutomatedPayoutSenderFactory.ProcessorName },
|
||||||
PaymentMethods = paymentMethod is null ? null : new[] {paymentMethod}
|
PaymentMethods = paymentMethod is null ? null : new[] { paymentMethod }
|
||||||
});
|
});
|
||||||
|
|
||||||
return Ok(configured.Select(ToModel).ToArray());
|
return Ok(configured.Select(ToModel).ToArray());
|
||||||
@ -61,7 +61,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
private static AutomatedPayoutBlob FromModel(LightningAutomatedPayoutSettings data)
|
private static AutomatedPayoutBlob FromModel(LightningAutomatedPayoutSettings data)
|
||||||
{
|
{
|
||||||
return new AutomatedPayoutBlob() {Interval = data.IntervalSeconds};
|
return new AutomatedPayoutBlob() { Interval = data.IntervalSeconds };
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
@ -75,9 +75,9 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
(await _payoutProcessorService.GetProcessors(
|
(await _payoutProcessorService.GetProcessors(
|
||||||
new PayoutProcessorService.PayoutProcessorQuery()
|
new PayoutProcessorService.PayoutProcessorQuery()
|
||||||
{
|
{
|
||||||
Stores = new[] {storeId},
|
Stores = new[] { storeId },
|
||||||
Processors = new[] {LightningAutomatedPayoutSenderFactory.ProcessorName},
|
Processors = new[] { LightningAutomatedPayoutSenderFactory.ProcessorName },
|
||||||
PaymentMethods = new[] {paymentMethod}
|
PaymentMethods = new[] { paymentMethod }
|
||||||
}))
|
}))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
activeProcessor ??= new PayoutProcessorData();
|
activeProcessor ??= new PayoutProcessorData();
|
||||||
@ -88,7 +88,9 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
var tcs = new TaskCompletionSource();
|
var tcs = new TaskCompletionSource();
|
||||||
_eventAggregator.Publish(new PayoutProcessorUpdated()
|
_eventAggregator.Publish(new PayoutProcessorUpdated()
|
||||||
{
|
{
|
||||||
Data = activeProcessor, Id = activeProcessor.Id, Processed = tcs
|
Data = activeProcessor,
|
||||||
|
Id = activeProcessor.Id,
|
||||||
|
Processed = tcs
|
||||||
});
|
});
|
||||||
await tcs.Task;
|
await tcs.Task;
|
||||||
return Ok(ToModel(activeProcessor));
|
return Ok(ToModel(activeProcessor));
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user