Compare commits
1 Commits
v1.7.6
...
pr-no-rece
Author | SHA1 | Date | |
---|---|---|---|
d18246bfbe |
@ -11,14 +11,10 @@ insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
space_before_self_closing = true
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[swagger*.json]
|
||||
indent_size = 4
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
# New line preferences
|
||||
@ -71,7 +67,7 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
||||
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.capitalization = camel_case
|
||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||
|
||||
# Code style defaults
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -298,4 +298,3 @@ Packed Plugins
|
||||
Plugins/packed
|
||||
|
||||
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
||||
BTCPayServer/appsettings.dev.json
|
@ -14,8 +14,8 @@
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<method v="2">
|
||||
<option name="Build" default="false" projectName="BTCPayServer.Plugins.Test" projectPath="C:\Git\btcpayserver\Plugins\BTCPayServer.Plugins.Test\BTCPayServer.Plugins.Test.csproj" />
|
||||
<option name="Build" default="false" projectName="BTCPayServer.Plugins.Test" projectPath="C:\Git\btcpayserver\BTCPayServer.Plugins.Test\BTCPayServer.Plugins.Test.csproj" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
</component>
|
@ -1,18 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Abstractions
|
||||
{
|
||||
public class CamelCaseSerializerSettings
|
||||
{
|
||||
static CamelCaseSerializerSettings()
|
||||
{
|
||||
Settings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
Serializer = JsonSerializer.Create(Settings);
|
||||
}
|
||||
public static readonly JsonSerializerSettings Settings;
|
||||
public static readonly JsonSerializer Serializer;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface IScopeProvider
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin;
|
||||
|
||||
|
@ -9,7 +9,7 @@ public class 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;
|
||||
ToAsset = toAsset;
|
||||
|
@ -2,7 +2,10 @@ namespace BTCPayServer.Abstractions.Custodians;
|
||||
|
||||
public class AssetBalancesUnavailableException : CustodianApiException
|
||||
{
|
||||
|
||||
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
namespace BTCPayServer.Abstractions.Custodians;
|
||||
public class CustodianApiException : Exception
|
||||
{
|
||||
public class CustodianApiException: Exception {
|
||||
public int HttpStatus { get; }
|
||||
public string Code { get; }
|
||||
|
||||
@ -10,8 +9,7 @@ public class CustodianApiException : Exception
|
||||
HttpStatus = httpStatus;
|
||||
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,8 +1,9 @@
|
||||
namespace BTCPayServer.Abstractions.Custodians;
|
||||
|
||||
public class CustodianFeatureNotImplementedException : CustodianApiException
|
||||
public class CustodianFeatureNotImplementedException: CustodianApiException
|
||||
{
|
||||
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
namespace BTCPayServer.Abstractions.Custodians;
|
||||
|
||||
public class InsufficientFundsException : CustodianApiException
|
||||
{
|
||||
{
|
||||
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ public class TradeNotFoundException : CustodianApiException
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace BTCPayServer.Abstractions.Custodians;
|
||||
|
||||
public class WrongTradingPairException : CustodianApiException
|
||||
public class WrongTradingPairException: CustodianApiException
|
||||
{
|
||||
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}.")
|
||||
|
@ -9,16 +9,18 @@ namespace BTCPayServer.Abstractions.Custodians;
|
||||
|
||||
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",...]
|
||||
*/
|
||||
public List<AssetPairData> GetTradableAssetPairs();
|
||||
|
||||
|
||||
/**
|
||||
* Execute a market order right now.
|
||||
*/
|
||||
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||
|
||||
|
||||
/**
|
||||
* Get the details about a previous market trade.
|
||||
*/
|
||||
|
@ -12,7 +12,7 @@ public interface ICustodian
|
||||
* Get the unique code that identifies this custodian.
|
||||
*/
|
||||
string Code { get; }
|
||||
|
||||
|
||||
string Name { get; }
|
||||
|
||||
/**
|
||||
|
@ -30,12 +30,12 @@ public static class GreenfieldExtensions
|
||||
{
|
||||
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
||||
}
|
||||
|
||||
|
||||
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
||||
{
|
||||
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
||||
}
|
||||
|
||||
|
||||
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
||||
{
|
||||
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
||||
|
@ -11,7 +11,7 @@ public static class HttpRequestExtensions
|
||||
return false;
|
||||
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
public static string GetAbsoluteRoot(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
|
@ -6,6 +6,7 @@ namespace BTCPayServer.Abstractions.Extensions;
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
|
||||
public static bool IsValidFileName(this string fileName)
|
||||
{
|
||||
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
||||
@ -40,4 +41,5 @@ public static class StringExtensions
|
||||
return str.Substring(0, str.Length - 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
||||
{
|
||||
return IsActiveCategory(viewData, category.ToString(), id);
|
||||
}
|
||||
|
||||
|
||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
||||
@ -77,7 +77,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
||||
? ActivePageClass
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
||||
@ -126,7 +126,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
||||
{
|
||||
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.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||
}
|
||||
|
@ -17,16 +17,16 @@ public class AlertMessage
|
||||
Danger,
|
||||
Info
|
||||
}
|
||||
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public AlertMessageType Type;
|
||||
|
||||
|
||||
// The translated message to be shown to the user
|
||||
public string Message;
|
||||
|
||||
public AlertMessage()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public AlertMessage(AlertMessageType type, string message)
|
||||
|
@ -1,64 +1,35 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class Field
|
||||
public abstract class Field
|
||||
{
|
||||
public static Field Create(string label, string name, string value, bool required, string helpText, string type = "text")
|
||||
{
|
||||
return new Field()
|
||||
{
|
||||
Label = label,
|
||||
Name = name,
|
||||
Value = value,
|
||||
OriginalValue = value,
|
||||
Required = required,
|
||||
HelpText = helpText,
|
||||
Type = type
|
||||
};
|
||||
}
|
||||
// The name of the HTML5 node. Should be used as the key for the posted data.
|
||||
public string Name;
|
||||
|
||||
public bool Hidden;
|
||||
|
||||
// HTML5 compatible type string like "text", "textarea", "email", "password", etc. Each type is a class and may contain more fields (i.e. "select" would have options).
|
||||
public string Type;
|
||||
|
||||
public static Field CreateFieldset()
|
||||
{
|
||||
return new Field() { Type = "fieldset" };
|
||||
}
|
||||
|
||||
|
||||
// The name of the HTML5 node. Should be used as the key for the posted data.
|
||||
public string Name;
|
||||
|
||||
// The translated label of the field.
|
||||
public string Label;
|
||||
|
||||
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
|
||||
// If this is the first the user sees the form, then value and original value are the same. Value changes as the user starts interacting with the form.
|
||||
public string Value;
|
||||
|
||||
public bool Required;
|
||||
|
||||
// The translated label of the field.
|
||||
public string Label;
|
||||
|
||||
// The original value is the value that is currently saved in the backend. A "reset" button can be used to revert back to this. Should only be set from the constructor.
|
||||
public string OriginalValue;
|
||||
|
||||
// A useful note shown below the field or via a tooltip / info icon. Should be translated for the user.
|
||||
public string HelpText;
|
||||
|
||||
[JsonExtensionData] public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
public List<Field> Fields { get; set; } = new();
|
||||
|
||||
|
||||
// The field is considered "valid" if there are no validation errors
|
||||
public List<string> ValidationErrors = new List<string>();
|
||||
|
||||
public virtual bool IsValid()
|
||||
public bool Required = false;
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
return ValidationErrors.Count == 0 && Fields.All(field => field.IsValid());
|
||||
return ValidationErrors.Count == 0;
|
||||
}
|
||||
}
|
||||
|
14
BTCPayServer.Abstractions/Form/Fieldset.cs
Normal file
14
BTCPayServer.Abstractions/Form/Fieldset.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class Fieldset
|
||||
{
|
||||
public Fieldset()
|
||||
{
|
||||
this.Fields = new List<Field>();
|
||||
}
|
||||
|
||||
public string Label { get; set; }
|
||||
public List<Field> Fields { get; set; }
|
||||
}
|
@ -1,157 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class Form
|
||||
{
|
||||
#nullable enable
|
||||
public static Form Parse(string str)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(str);
|
||||
return JObject.Parse(str).ToObject<Form>(CamelCaseSerializerSettings.Serializer) ?? throw new InvalidOperationException("Impossible to deserialize Form");
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return JObject.FromObject(this, CamelCaseSerializerSettings.Serializer).ToString(Newtonsoft.Json.Formatting.Indented);
|
||||
}
|
||||
#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...
|
||||
public List<AlertMessage> TopMessages { get; set; } = new();
|
||||
|
||||
|
||||
// Groups of fields in the form
|
||||
public List<Field> Fields { get; set; } = new();
|
||||
public List<Fieldset> Fieldsets { get; set; } = new();
|
||||
|
||||
|
||||
// Are all the fields valid in the form?
|
||||
public bool IsValid()
|
||||
{
|
||||
return Fields.Select(f => f.IsValid()).All(o => o);
|
||||
foreach (var fieldset in Fieldsets)
|
||||
{
|
||||
foreach (var field in fieldset.Fields)
|
||||
{
|
||||
if (!field.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Field GetFieldByName(string name)
|
||||
{
|
||||
return GetFieldByName(name, Fields, null);
|
||||
}
|
||||
|
||||
private static Field GetFieldByName(string name, List<Field> fields, string prefix)
|
||||
{
|
||||
prefix ??= string.Empty;
|
||||
foreach (var field in fields)
|
||||
foreach (var fieldset in Fieldsets)
|
||||
{
|
||||
var currentPrefix = prefix;
|
||||
if (!string.IsNullOrEmpty(field.Name))
|
||||
foreach (var field in fieldset.Fields)
|
||||
{
|
||||
|
||||
currentPrefix = $"{prefix}{field.Name}";
|
||||
if (currentPrefix.Equals(name, StringComparison.InvariantCultureIgnoreCase))
|
||||
if (name.Equals(field.Name))
|
||||
{
|
||||
return field;
|
||||
}
|
||||
|
||||
currentPrefix += "_";
|
||||
}
|
||||
|
||||
var subFieldResult = GetFieldByName(name, field.Fields, currentPrefix);
|
||||
if (subFieldResult is not null)
|
||||
{
|
||||
return subFieldResult;
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<string> GetAllNames()
|
||||
{
|
||||
return GetAllNames(Fields);
|
||||
}
|
||||
|
||||
private static List<string> GetAllNames(List<Field> fields)
|
||||
{
|
||||
var names = new List<string>();
|
||||
|
||||
foreach (var field in fields)
|
||||
foreach (var fieldset in Fieldsets)
|
||||
{
|
||||
string prefix = string.Empty;
|
||||
if (!string.IsNullOrEmpty(field.Name))
|
||||
foreach (var field in fieldset.Fields)
|
||||
{
|
||||
names.Add(field.Name);
|
||||
prefix = $"{field.Name}_";
|
||||
}
|
||||
|
||||
if (field.Fields.Any())
|
||||
{
|
||||
names.AddRange(GetAllNames(field.Fields).Select(s => $"{prefix}{s}"));
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
public void ApplyValuesFromOtherForm(Form form)
|
||||
{
|
||||
foreach (var fieldset in Fields)
|
||||
{
|
||||
foreach (var field in fieldset.Fields)
|
||||
{
|
||||
field.Value = form
|
||||
.GetFieldByName(
|
||||
$"{(string.IsNullOrEmpty(fieldset.Name) ? string.Empty : fieldset.Name + "_")}{field.Name}")
|
||||
?.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyValuesFromForm(IFormCollection form)
|
||||
{
|
||||
var names = GetAllNames();
|
||||
foreach (var name in names)
|
||||
{
|
||||
var field = GetFieldByName(name);
|
||||
if (field is null || !form.TryGetValue(name, out var val))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
field.Value = val;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetValues()
|
||||
{
|
||||
return GetValues(Fields);
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> GetValues(List<Field> fields)
|
||||
{
|
||||
var result = new Dictionary<string, object>();
|
||||
foreach (Field field in fields)
|
||||
{
|
||||
var name = field.Name ?? string.Empty;
|
||||
if (field.Fields.Any())
|
||||
{
|
||||
var values = GetValues(fields);
|
||||
values.Remove(string.Empty, out var keylessValue);
|
||||
|
||||
result.TryAdd(name, values);
|
||||
|
||||
if (keylessValue is not Dictionary<string, object> dict)
|
||||
continue;
|
||||
foreach (KeyValuePair<string, object> keyValuePair in dict)
|
||||
{
|
||||
result.TryAdd(keyValuePair.Key, keyValuePair.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.TryAdd(name, field.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
19
BTCPayServer.Abstractions/Form/TextField.cs
Normal file
19
BTCPayServer.Abstractions/Form/TextField.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class TextField : Field
|
||||
{
|
||||
public TextField(string label, string name, string value, bool required, string helpText)
|
||||
{
|
||||
this.Label = label;
|
||||
this.Name = name;
|
||||
this.Value = value;
|
||||
this.OriginalValue = value;
|
||||
this.Required = required;
|
||||
this.HelpText = helpText;
|
||||
this.Type = "text";
|
||||
}
|
||||
|
||||
// TODO JSON parsing from string to objects again probably won't work out of the box because of the different field types.
|
||||
|
||||
|
||||
}
|
@ -8,52 +8,18 @@ namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public abstract class BaseBTCPayServerPlugin : IBTCPayServerPlugin
|
||||
{
|
||||
public virtual string Identifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly.GetName().Name;
|
||||
}
|
||||
}
|
||||
public virtual string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyProductAttribute>()?
|
||||
.Product ?? "???";
|
||||
}
|
||||
}
|
||||
public abstract string Identifier { get; }
|
||||
public abstract string Name { get; }
|
||||
|
||||
public virtual Version Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetVersion(GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
||||
.InformationalVersion) ??
|
||||
Assembly.GetAssembly(GetType())?.GetName()?.Version ??
|
||||
new Version(1, 0, 0, 0);
|
||||
return Assembly.GetAssembly(GetType())?.GetName().Version ?? new Version(1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static Version GetVersion(string informationalVersion)
|
||||
{
|
||||
if (informationalVersion is null)
|
||||
return null;
|
||||
Version.TryParse(informationalVersion, out var r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public virtual string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyDescriptionAttribute>()?
|
||||
.Description ?? string.Empty;
|
||||
}
|
||||
}
|
||||
public abstract string Description { get; }
|
||||
public bool SystemPlugin { get; set; }
|
||||
public virtual IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = Array.Empty<IBTCPayServerPlugin.PluginDependency>();
|
||||
|
||||
|
@ -8,7 +8,7 @@ public class AuthorizationFilterHandle
|
||||
public AuthorizationHandlerContext Context { get; }
|
||||
public PolicyRequirement Requirement { get; }
|
||||
public HttpContext HttpContext { get; }
|
||||
public bool Success { get; private set; }
|
||||
public bool Success { get; private set; }
|
||||
|
||||
public AuthorizationFilterHandle(
|
||||
AuthorizationHandlerContext context,
|
||||
|
@ -1,12 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
@ -15,7 +8,7 @@ namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
// Make sure that <svg><use href=/ are correctly working if rootpath is present
|
||||
[HtmlTargetElement("use", Attributes = "href")]
|
||||
public class SVGUse : UrlResolutionTagHelper2
|
||||
public class SVGUse : UrlResolutionTagHelper
|
||||
{
|
||||
private readonly IFileVersionProvider _fileVersionProvider;
|
||||
|
||||
@ -28,6 +21,5 @@ public class SVGUse : UrlResolutionTagHelper2
|
||||
var attr = output.Attributes["href"].Value.ToString();
|
||||
attr = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, attr);
|
||||
output.Attributes.SetAttribute("href", attr);
|
||||
base.Process(context, output);
|
||||
}
|
||||
}
|
||||
|
@ -1,314 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers
|
||||
{
|
||||
// A copy of https://github.com/dotnet/aspnetcore/blob/39f0e0b8f40b4754418f81aef0de58a9204a1fe5/src/Mvc/Mvc.Razor/src/TagHelpers/UrlResolutionTagHelper.cs
|
||||
// slightly modified to also work on use tag.
|
||||
public class UrlResolutionTagHelper2 : TagHelper
|
||||
{
|
||||
// Valid whitespace characters defined by the HTML5 spec.
|
||||
private static readonly char[] ValidAttributeWhitespaceChars =
|
||||
new[] { '\t', '\n', '\u000C', '\r', ' ' };
|
||||
private static readonly Dictionary<string, string[]> ElementAttributeLookups =
|
||||
new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "use", new[] { "href" } },
|
||||
{ "a", new[] { "href" } },
|
||||
{ "applet", new[] { "archive" } },
|
||||
{ "area", new[] { "href" } },
|
||||
{ "audio", new[] { "src" } },
|
||||
{ "base", new[] { "href" } },
|
||||
{ "blockquote", new[] { "cite" } },
|
||||
{ "button", new[] { "formaction" } },
|
||||
{ "del", new[] { "cite" } },
|
||||
{ "embed", new[] { "src" } },
|
||||
{ "form", new[] { "action" } },
|
||||
{ "html", new[] { "manifest" } },
|
||||
{ "iframe", new[] { "src" } },
|
||||
{ "img", new[] { "src", "srcset" } },
|
||||
{ "input", new[] { "src", "formaction" } },
|
||||
{ "ins", new[] { "cite" } },
|
||||
{ "link", new[] { "href" } },
|
||||
{ "menuitem", new[] { "icon" } },
|
||||
{ "object", new[] { "archive", "data" } },
|
||||
{ "q", new[] { "cite" } },
|
||||
{ "script", new[] { "src" } },
|
||||
{ "source", new[] { "src", "srcset" } },
|
||||
{ "track", new[] { "src" } },
|
||||
{ "video", new[] { "poster", "src" } },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="UrlResolutionTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="urlHelperFactory">The <see cref="IUrlHelperFactory"/>.</param>
|
||||
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/>.</param>
|
||||
public UrlResolutionTagHelper2(IUrlHelperFactory urlHelperFactory, HtmlEncoder htmlEncoder)
|
||||
{
|
||||
UrlHelperFactory = urlHelperFactory;
|
||||
HtmlEncoder = htmlEncoder;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Order => -1000 - 999;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IUrlHelperFactory"/>.
|
||||
/// </summary>
|
||||
protected IUrlHelperFactory UrlHelperFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HtmlEncoder"/>.
|
||||
/// </summary>
|
||||
protected HtmlEncoder HtmlEncoder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ViewContext"/>.
|
||||
/// </summary>
|
||||
[HtmlAttributeNotBound]
|
||||
[ViewContext]
|
||||
public ViewContext ViewContext { get; set; } = default!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
ArgumentNullException.ThrowIfNull(output);
|
||||
|
||||
if (output.TagName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ElementAttributeLookups.TryGetValue(output.TagName, out var attributeNames))
|
||||
{
|
||||
for (var i = 0; i < attributeNames.Length; i++)
|
||||
{
|
||||
ProcessUrlAttribute(attributeNames[i], output);
|
||||
}
|
||||
}
|
||||
|
||||
// itemid can be present on any HTML element.
|
||||
ProcessUrlAttribute("itemid", output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves and updates URL values starting with '~/' (relative to the application's 'webroot' setting) for
|
||||
/// <paramref name="output"/>'s <see cref="TagHelperOutput.Attributes"/> whose
|
||||
/// <see cref="TagHelperAttribute.Name"/> is <paramref name="attributeName"/>.
|
||||
/// </summary>
|
||||
/// <param name="attributeName">The attribute name used to lookup values to resolve.</param>
|
||||
/// <param name="output">The <see cref="TagHelperOutput"/>.</param>
|
||||
protected void ProcessUrlAttribute(string attributeName, TagHelperOutput output)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(attributeName);
|
||||
ArgumentNullException.ThrowIfNull(output);
|
||||
|
||||
var attributes = output.Attributes;
|
||||
// Read interface .Count once rather than per iteration
|
||||
var attributesCount = attributes.Count;
|
||||
for (var i = 0; i < attributesCount; i++)
|
||||
{
|
||||
var attribute = attributes[i];
|
||||
if (!string.Equals(attribute.Name, attributeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attribute.Value is string stringValue)
|
||||
{
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out string? resolvedUrl))
|
||||
{
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attribute.Value is IHtmlContent htmlContent)
|
||||
{
|
||||
var htmlString = htmlContent as HtmlString;
|
||||
if (htmlString != null)
|
||||
{
|
||||
// No need for a StringWriter in this case.
|
||||
stringValue = htmlString.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
htmlContent.WriteTo(writer, HtmlEncoder);
|
||||
stringValue = writer.ToString();
|
||||
}
|
||||
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out IHtmlContent? resolvedUrl))
|
||||
{
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
else if (htmlString == null)
|
||||
{
|
||||
// Not a ~/ URL. Just avoid re-encoding the attribute value later.
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
new HtmlString(stringValue),
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve the given <paramref name="url"/> value relative to the application's 'webroot' setting.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to resolve.</param>
|
||||
/// <param name="resolvedUrl">Absolute URL beginning with the application's virtual root. <c>null</c> if
|
||||
/// <paramref name="url"/> could not be resolved.</param>
|
||||
/// <returns><c>true</c> if the <paramref name="url"/> could be resolved; <c>false</c> otherwise.</returns>
|
||||
protected bool TryResolveUrl(string url, out string? resolvedUrl)
|
||||
{
|
||||
resolvedUrl = null;
|
||||
var start = FindRelativeStart(url);
|
||||
if (start == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var trimmedUrl = CreateTrimmedString(url, start);
|
||||
|
||||
var urlHelper = UrlHelperFactory.GetUrlHelper(ViewContext);
|
||||
resolvedUrl = urlHelper.Content(trimmedUrl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve the given <paramref name="url"/> value relative to the application's 'webroot' setting.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to resolve.</param>
|
||||
/// <param name="resolvedUrl">
|
||||
/// Absolute URL beginning with the application's virtual root. <c>null</c> if <paramref name="url"/> could
|
||||
/// not be resolved.
|
||||
/// </param>
|
||||
/// <returns><c>true</c> if the <paramref name="url"/> could be resolved; <c>false</c> otherwise.</returns>
|
||||
protected bool TryResolveUrl(string url, [NotNullWhen(true)] out IHtmlContent? resolvedUrl)
|
||||
{
|
||||
resolvedUrl = null;
|
||||
var start = FindRelativeStart(url);
|
||||
if (start == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var trimmedUrl = CreateTrimmedString(url, start);
|
||||
|
||||
var urlHelper = UrlHelperFactory.GetUrlHelper(ViewContext);
|
||||
var appRelativeUrl = urlHelper.Content(trimmedUrl);
|
||||
var postTildeSlashUrlValue = trimmedUrl.Substring(2);
|
||||
|
||||
if (!appRelativeUrl.EndsWith(postTildeSlashUrlValue, StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
resolvedUrl = new EncodeFirstSegmentContent(
|
||||
appRelativeUrl,
|
||||
appRelativeUrl.Length - postTildeSlashUrlValue.Length,
|
||||
postTildeSlashUrlValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int FindRelativeStart(string url)
|
||||
{
|
||||
if (url == null || url.Length < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var maxTestLength = url.Length - 2;
|
||||
|
||||
var start = 0;
|
||||
for (; start < url.Length; start++)
|
||||
{
|
||||
if (start > maxTestLength)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!IsCharWhitespace(url[start]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Before doing more work, ensure that the URL we're looking at is app-relative.
|
||||
if (url[start] != '~' || url[start + 1] != '/')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
private static string CreateTrimmedString(string input, int start)
|
||||
{
|
||||
var end = input.Length - 1;
|
||||
for (; end >= start; end--)
|
||||
{
|
||||
if (!IsCharWhitespace(input[end]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var len = end - start + 1;
|
||||
|
||||
// Substring returns same string if start == 0 && len == Length
|
||||
return input.Substring(start, len);
|
||||
}
|
||||
|
||||
private static bool IsCharWhitespace(char ch)
|
||||
{
|
||||
return ValidAttributeWhitespaceChars.AsSpan().IndexOf(ch) != -1;
|
||||
}
|
||||
|
||||
private sealed class EncodeFirstSegmentContent : IHtmlContent
|
||||
{
|
||||
private readonly string _firstSegment;
|
||||
private readonly int _firstSegmentLength;
|
||||
private readonly string _secondSegment;
|
||||
|
||||
public EncodeFirstSegmentContent(string firstSegment, int firstSegmentLength, string secondSegment)
|
||||
{
|
||||
_firstSegment = firstSegment;
|
||||
_firstSegmentLength = firstSegmentLength;
|
||||
_secondSegment = secondSegment;
|
||||
}
|
||||
|
||||
public void WriteTo(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
encoder.Encode(writer, _firstSegment, 0, _firstSegmentLength);
|
||||
writer.Write(_secondSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
<RepositoryType>git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Version Condition=" '$(Version)' == '' ">1.7.2</Version>
|
||||
<Version Condition=" '$(Version)' == '' ">1.7.0</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
@ -28,8 +28,8 @@
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.21" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.24" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.15" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.14" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -19,7 +19,7 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<PointOfSaleAppData>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
@ -51,44 +51,6 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<AppDataBase[]> GetAllApps(string storeId, CancellationToken token = default)
|
||||
{
|
||||
if (storeId == null)
|
||||
throw new ArgumentNullException(nameof(storeId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/apps",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<AppDataBase[]> GetAllApps(CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<AppDataBase[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/pos/{appId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<PointOfSaleAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null)
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/apps/crowdfund/{appId}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<CrowdfundAppData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteApp(string appId, 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)
|
||||
{
|
||||
|
||||
|
||||
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
||||
//return await HandleResponse<ApplicationUserData>(response);
|
||||
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);
|
||||
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);
|
||||
return await HandleResponse<WithdrawalResponseData>(response);
|
||||
|
@ -128,18 +128,5 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> RefundInvoice(
|
||||
string storeId,
|
||||
string invoiceId,
|
||||
RefundInvoiceRequest request,
|
||||
CancellationToken token = default
|
||||
)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
return await HandleResponse<PullPaymentData>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeInformationData>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
@ -95,7 +95,7 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
@ -113,24 +113,6 @@ namespace BTCPayServer.Client
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload), token);
|
||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||
return await HandleResponse<LightningPaymentData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
|
@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningNodeInformationData>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
@ -97,7 +97,7 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningInvoiceData>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
@ -115,24 +115,6 @@ namespace BTCPayServer.Client
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload), token);
|
||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload), token);
|
||||
return await HandleResponse<LightningPaymentData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||
|
@ -1,48 +0,0 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client
|
||||
{
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningAddressData[]>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Get), token);
|
||||
return await HandleResponse<LightningAddressData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Delete), token);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
||||
string username, LightningAddressData data,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}",
|
||||
method: HttpMethod.Post, bodyPayload: data), token);
|
||||
|
||||
return await HandleResponse<LightningAddressData>(response);
|
||||
}
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ namespace BTCPayServer.Client
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
var response =
|
||||
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);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||
@ -47,7 +47,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
var response =
|
||||
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);
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||
@ -55,7 +55,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
var response =
|
||||
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);
|
||||
}
|
||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||
@ -65,7 +65,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
var response =
|
||||
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);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||
@ -75,7 +75,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
var response =
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
query.Add(nameof(statusFilter), statusFilter);
|
||||
}
|
||||
if (labelFilter != null)
|
||||
{
|
||||
if (labelFilter != null) {
|
||||
query.Add(nameof(labelFilter), labelFilter);
|
||||
}
|
||||
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);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
}
|
||||
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);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
}
|
||||
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);
|
||||
return await HandleResponse<PayoutData>(response);
|
||||
}
|
||||
}
|
||||
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);
|
||||
@ -97,15 +97,5 @@ namespace BTCPayServer.Client
|
||||
method: HttpMethod.Post, bodyPayload: request), cancellationToken);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest(
|
||||
$"/api/v1/pull-payments/{pullPaymentId}/lnurl",
|
||||
method: HttpMethod.Get), cancellationToken);
|
||||
return await HandleResponse<PullPaymentLNURL>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -37,28 +37,17 @@ namespace BTCPayServer.Client
|
||||
return await HandleResponse<StoreRateConfiguration>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
||||
public virtual async Task<List<StoreRatePreviewResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
||||
StoreRateConfiguration request,
|
||||
string[] currencyPair,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
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),
|
||||
token);
|
||||
return await HandleResponse<List<StoreRateResult>>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates",
|
||||
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||
method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<List<StoreRateResult>>(response);
|
||||
return await HandleResponse<List<StoreRatePreviewResult>>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,15 +33,14 @@ namespace BTCPayServer.Client
|
||||
return await HandleResponse<ApplicationUserData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||
public virtual async Task LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
return await HandleResponse<ApplicationUserData[]>(response);
|
||||
|
@ -8,7 +8,7 @@ public class AssetPairData
|
||||
public AssetPairData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
|
||||
{
|
||||
AssetBought = assetBought;
|
||||
@ -25,7 +25,7 @@ public class AssetPairData
|
||||
[JsonProperty]
|
||||
public decimal MinimumTradeQty { set; get; }
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return AssetBought + "/" + AssetSold;
|
||||
|
@ -37,7 +37,7 @@ namespace BTCPayServer.Client.Models
|
||||
public string RedirectUrl { get; set; } = null;
|
||||
public bool? RedirectAutomatically { get; set; } = null;
|
||||
public bool? RequiresRefundEmail { get; set; } = null;
|
||||
public string FormId { get; set; } = null;
|
||||
public string CheckoutFormId { get; set; } = null;
|
||||
public string EmbeddedCSS { get; set; } = null;
|
||||
public CheckoutType? CheckoutType { get; set; } = null;
|
||||
}
|
||||
|
@ -11,18 +11,19 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
|
||||
{
|
||||
Amount = amount;
|
||||
Description = description;
|
||||
Expiry = expiry;
|
||||
}
|
||||
|
||||
|
||||
[JsonConverter(typeof(JsonConverters.LightMoneyJsonConverter))]
|
||||
public LightMoney Amount { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool DescriptionHashOnly { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.UInt256JsonConverter))]
|
||||
public uint256 DescriptionHash { get; set; }
|
||||
[JsonConverter(typeof(JsonConverters.TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan Expiry { get; set; }
|
||||
public bool PrivateRouteHints { get; set; }
|
||||
|
@ -5,11 +5,11 @@ namespace BTCPayServer.Client.Models
|
||||
public abstract class CustodianAccountBaseData
|
||||
{
|
||||
public string CustodianCode { get; set; }
|
||||
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
public string StoreId { get; set; }
|
||||
|
||||
|
||||
public JObject Config { get; set; }
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,13 @@ using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class CustodianAccountResponse : CustodianAccountData
|
||||
public class CustodianAccountResponse: CustodianAccountData
|
||||
{
|
||||
public IDictionary<string, decimal> AssetBalances { get; set; }
|
||||
|
||||
public CustodianAccountResponse()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,5 +9,5 @@ public class CustodianData
|
||||
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
|
||||
public string[] WithdrawablePaymentMethods { get; set; }
|
||||
public string[] DepositablePaymentMethods { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ public class DepositAddressData
|
||||
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
|
||||
// */
|
||||
// public string Type { get; set; }
|
||||
|
||||
|
||||
/**
|
||||
* Format depends hugely on the type.
|
||||
*/
|
||||
public string Address { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ namespace BTCPayServer.Client.Models
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public bool? RequiresRefundEmail { get; set; } = null;
|
||||
public string DefaultLanguage { get; set; }
|
||||
[JsonProperty("checkoutFormId")]
|
||||
public string CheckoutFormId { get; set; }
|
||||
public CheckoutType? CheckoutType { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class LightningAddressData
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string CurrencyCode { get; set; }
|
||||
public decimal? Min { get; set; }
|
||||
public decimal? Max { get; set; }
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models;
|
||||
public class LightningAutomatedPayoutSettings
|
||||
{
|
||||
public string PaymentMethod { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan IntervalSeconds { get; set; }
|
||||
}
|
||||
|
@ -16,15 +16,9 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
[JsonProperty("BOLT11")]
|
||||
public string BOLT11 { get; set; }
|
||||
|
||||
public string PaymentHash { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Preimage { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset ExpiresAt { get; set; }
|
||||
|
||||
|
@ -9,10 +9,10 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
[JsonProperty("onchain")]
|
||||
public OnchainBalanceData OnchainBalance { get; set; }
|
||||
|
||||
|
||||
[JsonProperty("offchain")]
|
||||
public OffchainBalanceData OffchainBalance { get; set; }
|
||||
|
||||
|
||||
public LightningNodeBalanceData()
|
||||
{
|
||||
}
|
||||
@ -31,7 +31,7 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||
public Money Unconfirmed { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||
public Money Reserved { get; set; }
|
||||
}
|
||||
@ -40,13 +40,13 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Opening { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Local { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Remote { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Closing { get; set; }
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
[JsonProperty("BOLT11")]
|
||||
public string BOLT11 { get; set; }
|
||||
|
||||
|
||||
public string Preimage { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney TotalAmount { get; set; }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace BTCPayServer.Client;
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public class LockUserRequest
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ public class MarketTradeResponseData
|
||||
public string TradeId { get; }
|
||||
|
||||
public string AccountId { get; }
|
||||
|
||||
|
||||
public string CustodianCode { get; }
|
||||
|
||||
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 Newtonsoft.Json;
|
||||
|
||||
@ -7,9 +7,9 @@ namespace BTCPayServer.Client.Models;
|
||||
public class OnChainAutomatedPayoutSettings
|
||||
{
|
||||
public string PaymentMethod { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
public TimeSpan IntervalSeconds { get; set; }
|
||||
|
||||
public int? FeeBlockTarget { get; set; }
|
||||
public int? FeeBlockTarget { get; set; }
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
[JsonConverter(typeof(NodeUriJsonConverter))]
|
||||
[JsonProperty("nodeURI")]
|
||||
public BTCPayServer.Lightning.NodeInfo NodeURI { get; set; }
|
||||
public NodeInfo NodeURI { get; set; }
|
||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||
public Money ChannelAmount { get; set; }
|
||||
|
||||
|
@ -11,13 +11,13 @@ namespace BTCPayServer.Client.Models
|
||||
{
|
||||
[JsonProperty("BOLT11")]
|
||||
public string BOLT11 { get; set; }
|
||||
|
||||
|
||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||
public float? MaxFeePercent { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||
public Money MaxFeeFlat { get; set; }
|
||||
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney Amount { get; set; }
|
||||
|
||||
|
@ -24,9 +24,5 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
|
||||
public string FormId { get; set; }
|
||||
|
||||
public JObject FormResponse { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace BTCPayServer.Client.Models
|
||||
public DateTimeOffset CreatedTime { get; set; }
|
||||
public string Id { get; set; }
|
||||
public bool Archived { get; set; }
|
||||
|
||||
public enum PaymentRequestStatus
|
||||
{
|
||||
Pending = 0,
|
||||
|
@ -12,56 +12,14 @@ namespace BTCPayServer.Client.Models
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class PointOfSaleAppData : AppDataBase
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string DefaultView { get; set; }
|
||||
public bool ShowCustomAmount { get; set; }
|
||||
public bool ShowDiscount { get; set; }
|
||||
public bool EnableTips { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public object Items { get; set; }
|
||||
public string FixedAmountPayButtonText { get; set; }
|
||||
public string CustomAmountPayButtonText { get; set; }
|
||||
public string TipText { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
public string NotificationUrl { get; set; }
|
||||
public string RedirectUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string EmbeddedCSS { get; set; }
|
||||
public bool? RedirectAutomatically { get; set; }
|
||||
public bool? RequiresRefundEmail { get; set; }
|
||||
// We can add POS specific things here later
|
||||
}
|
||||
|
||||
public class CrowdfundAppData : AppDataBase
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool EnforceTargetAmount { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? StartDate { get; set; }
|
||||
public string TargetCurrency { get; set; }
|
||||
public string Description { get; set; }
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? EndDate { get; set; }
|
||||
public decimal? TargetAmount { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
public string MainImageUrl { get; set; }
|
||||
public string EmbeddedCSS { get; set; }
|
||||
public string NotificationUrl { get; set; }
|
||||
public string Tagline { get; set; }
|
||||
public object Perks { get; set; }
|
||||
public bool DisqusEnabled { get; set; }
|
||||
public string DisqusShortname { get; set; }
|
||||
public bool SoundsEnabled { get; set; }
|
||||
public bool AnimationsEnabled { get; set; }
|
||||
public int ResetEveryAmount { get; set; }
|
||||
public string ResetEvery { get; set; }
|
||||
public bool DisplayPerksValue { get; set; }
|
||||
public bool DisplayPerksRanking { get; set; }
|
||||
public bool SortPerksByPopularity { get; set; }
|
||||
public string[] Sounds { get; set; }
|
||||
public string[] AnimationColors { get; set; }
|
||||
// We can add Crowdfund specific things here later
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class PullPaymentLNURL
|
||||
{
|
||||
public string LNURLBech32 { get; set; }
|
||||
public string LNURLUri { get; set; }
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
namespace BTCPayServer.Client.Models;
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class RateSource
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#nullable enable
|
||||
using BTCPayServer.JsonConverters;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public enum RefundVariant
|
||||
{
|
||||
RateThen,
|
||||
CurrentRate,
|
||||
Fiat,
|
||||
Custom
|
||||
}
|
||||
|
||||
public class RefundInvoiceRequest
|
||||
{
|
||||
public string? Name { get; set; } = null;
|
||||
public string? PaymentMethod { get; set; }
|
||||
public string? Description { get; set; } = null;
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public RefundVariant? RefundVariant { get; set; }
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal? CustomAmount { get; set; }
|
||||
public string? CustomCurrency { get; set; }
|
||||
}
|
||||
}
|
@ -20,10 +20,6 @@ namespace BTCPayServer.Client.Models
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan InvoiceExpiration { get; set; } = TimeSpan.FromMinutes(15);
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan DisplayExpirationTimer { get; set; } = TimeSpan.FromMinutes(5);
|
||||
|
||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan MonitoringExpiration { get; set; } = TimeSpan.FromMinutes(60);
|
||||
@ -35,6 +31,8 @@ namespace BTCPayServer.Client.Models
|
||||
public bool AnyoneCanCreateInvoice { get; set; }
|
||||
public string DefaultCurrency { get; set; }
|
||||
public bool RequiresRefundEmail { get; set; }
|
||||
|
||||
public string CheckoutFormId { get; set; }
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public CheckoutType CheckoutType { get; set; }
|
||||
public bool LightningAmountInSatoshi { get; set; }
|
||||
@ -64,7 +62,7 @@ namespace BTCPayServer.Client.Models
|
||||
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
|
||||
|
||||
public bool PayJoinEnabled { get; set; }
|
||||
|
||||
|
||||
public InvoiceData.ReceiptOptions Receipt { get; set; }
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class StoreUserData
|
||||
{
|
||||
/// <summary>
|
||||
|
10
BTCPayServer.Client/Models/StoreRatePreviewResult.cs
Normal file
10
BTCPayServer.Client/Models/StoreRatePreviewResult.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class StoreRatePreviewResult
|
||||
{
|
||||
public string CurrencyPair { get; set; }
|
||||
public decimal? Rate { get; set; }
|
||||
public List<string> Errors { get; set; }
|
||||
}
|
@ -1,13 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models;
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class StoreRateResult
|
||||
{
|
||||
public string CurrencyPair { get; set; }
|
||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||
public decimal? Rate { get; set; }
|
||||
public List<string> Errors { get; set; }
|
||||
}
|
||||
public decimal Rate { get; set; }
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
@ -16,7 +19,6 @@ namespace BTCPayServer.Client.Models
|
||||
|
||||
[JsonProperty(Order = 1)] public string StoreId { get; set; }
|
||||
[JsonProperty(Order = 2)] public string InvoiceId { get; set; }
|
||||
[JsonProperty(Order = 3)] public JObject Metadata { get; set; }
|
||||
}
|
||||
|
||||
public class WebhookInvoiceSettledEvent : WebhookInvoiceEvent
|
||||
|
@ -6,9 +6,7 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
public class Policies
|
||||
{
|
||||
public const string CanViewLightningInvoiceInternalNode = "btcpay.server.canviewlightninginvoiceinternalnode";
|
||||
public const string CanCreateLightningInvoiceInternalNode = "btcpay.server.cancreatelightninginvoiceinternalnode";
|
||||
public const string CanViewLightningInvoiceInStore = "btcpay.store.canviewlightninginvoice";
|
||||
public const string CanCreateLightningInvoiceInStore = "btcpay.store.cancreatelightninginvoice";
|
||||
public const string CanUseInternalLightningNode = "btcpay.server.canuseinternallightningnode";
|
||||
public const string CanUseLightningNodeInStore = "btcpay.store.canuselightningnode";
|
||||
@ -30,8 +28,6 @@ namespace BTCPayServer.Client
|
||||
public const string CanCreateUser = "btcpay.server.cancreateuser";
|
||||
public const string CanDeleteUser = "btcpay.user.candeleteuser";
|
||||
public const string CanManagePullPayments = "btcpay.store.canmanagepullpayments";
|
||||
public const string CanCreatePullPayments = "btcpay.store.cancreatepullpayments";
|
||||
public const string CanCreateNonApprovedPullPayments = "btcpay.store.cancreatenonapprovedpullpayments";
|
||||
public const string CanViewCustodianAccounts = "btcpay.store.canviewcustodianaccounts";
|
||||
public const string CanManageCustodianAccounts = "btcpay.store.canmanagecustodianaccounts";
|
||||
public const string CanDepositToCustodianAccounts = "btcpay.store.candeposittocustodianaccount";
|
||||
@ -60,14 +56,10 @@ namespace BTCPayServer.Client
|
||||
yield return CanViewNotificationsForUser;
|
||||
yield return Unrestricted;
|
||||
yield return CanUseInternalLightningNode;
|
||||
yield return CanViewLightningInvoiceInternalNode;
|
||||
yield return CanCreateLightningInvoiceInternalNode;
|
||||
yield return CanUseLightningNodeInStore;
|
||||
yield return CanViewLightningInvoiceInStore;
|
||||
yield return CanCreateLightningInvoiceInStore;
|
||||
yield return CanManagePullPayments;
|
||||
yield return CanCreatePullPayments;
|
||||
yield return CanCreateNonApprovedPullPayments;
|
||||
yield return CanViewCustodianAccounts;
|
||||
yield return CanManageCustodianAccounts;
|
||||
yield return CanDepositToCustodianAccounts;
|
||||
@ -99,11 +91,6 @@ namespace BTCPayServer.Client
|
||||
}
|
||||
public class Permission
|
||||
{
|
||||
static Permission()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public static Permission Create(string policy, string scope = null)
|
||||
{
|
||||
if (TryCreatePermission(policy, scope, out var r))
|
||||
@ -188,55 +175,37 @@ namespace BTCPayServer.Client
|
||||
|
||||
private bool ContainsPolicy(string subpolicy)
|
||||
{
|
||||
return ContainsPolicy(Policy, subpolicy);
|
||||
}
|
||||
|
||||
private static bool ContainsPolicy(string policy, string subpolicy)
|
||||
{
|
||||
if (policy == Policies.Unrestricted)
|
||||
if (this.Policy == Policies.Unrestricted)
|
||||
return true;
|
||||
if (policy == subpolicy)
|
||||
if (this.Policy == subpolicy)
|
||||
return true;
|
||||
if (!PolicyMap.TryGetValue(policy, out var subPolicies)) return false;
|
||||
return subPolicies.Contains(subpolicy) || subPolicies.Any(s => ContainsPolicy(s, subpolicy));
|
||||
}
|
||||
|
||||
private static Dictionary<string, HashSet<string>> PolicyMap = new();
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
PolicyHasChild(Policies.CanModifyStoreSettings,
|
||||
Policies.CanManageCustodianAccounts, Policies.CanManagePullPayments, Policies.CanModifyInvoices, Policies.CanViewStoreSettings, Policies.CanModifyStoreWebhooks, Policies.CanModifyPaymentRequests );
|
||||
|
||||
PolicyHasChild(Policies.CanManagePullPayments, Policies.CanCreatePullPayments );
|
||||
PolicyHasChild(Policies.CanCreatePullPayments, Policies.CanCreateNonApprovedPullPayments );
|
||||
PolicyHasChild(Policies.CanModifyPaymentRequests, Policies.CanViewPaymentRequests );
|
||||
PolicyHasChild(Policies.CanModifyProfile, Policies.CanViewProfile );
|
||||
PolicyHasChild(Policies.CanUseLightningNodeInStore, Policies.CanViewLightningInvoiceInStore, Policies.CanCreateLightningInvoiceInStore );
|
||||
PolicyHasChild(Policies.CanManageNotificationsForUser, Policies.CanViewNotificationsForUser );
|
||||
PolicyHasChild(Policies.CanModifyServerSettings, Policies.CanUseInternalLightningNode );
|
||||
PolicyHasChild(Policies.CanUseInternalLightningNode, Policies.CanCreateLightningInvoiceInternalNode,Policies.CanViewLightningInvoiceInternalNode );
|
||||
PolicyHasChild(Policies.CanManageCustodianAccounts, Policies.CanViewCustodianAccounts );
|
||||
PolicyHasChild(Policies.CanModifyInvoices, Policies.CanViewInvoices, Policies.CanCreateInvoice );
|
||||
PolicyHasChild(Policies.CanViewStoreSettings, Policies.CanViewInvoices, Policies.CanViewPaymentRequests );
|
||||
|
||||
}
|
||||
|
||||
private static void PolicyHasChild(string policy, params string[] subPolicies)
|
||||
{
|
||||
if (PolicyMap.TryGetValue(policy, out var existingSubPolicies))
|
||||
switch (subpolicy)
|
||||
{
|
||||
foreach (string subPolicy in subPolicies)
|
||||
{
|
||||
existingSubPolicies.Add(subPolicy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PolicyMap.Add(policy,subPolicies.ToHashSet());
|
||||
case Policies.CanViewInvoices when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanViewInvoices when this.Policy == Policies.CanModifyInvoices:
|
||||
case Policies.CanModifyStoreWebhooks when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanViewInvoices when this.Policy == Policies.CanViewStoreSettings:
|
||||
case Policies.CanViewStoreSettings when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanCreateInvoice when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanModifyInvoices when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanViewProfile when this.Policy == Policies.CanModifyProfile:
|
||||
case Policies.CanModifyPaymentRequests when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanViewPaymentRequests when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanManagePullPayments when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanViewPaymentRequests when this.Policy == Policies.CanViewStoreSettings:
|
||||
case Policies.CanViewPaymentRequests when this.Policy == Policies.CanModifyPaymentRequests:
|
||||
case Policies.CanCreateLightningInvoiceInternalNode when this.Policy == Policies.CanUseInternalLightningNode:
|
||||
case Policies.CanCreateLightningInvoiceInStore when this.Policy == Policies.CanUseLightningNodeInStore:
|
||||
case Policies.CanViewNotificationsForUser when this.Policy == Policies.CanManageNotificationsForUser:
|
||||
case Policies.CanUseInternalLightningNode when this.Policy == Policies.CanModifyServerSettings:
|
||||
case Policies.CanViewCustodianAccounts when this.Policy == Policies.CanManageCustodianAccounts:
|
||||
case Policies.CanViewCustodianAccounts when this.Policy == Policies.CanModifyStoreSettings:
|
||||
case Policies.CanManageCustodianAccounts when this.Policy == Policies.CanModifyStoreSettings:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string Scope { get; }
|
||||
public string Policy { get; }
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.2.3" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="2.0.1" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="4.2.1" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Altcoins)' != 'true'">
|
||||
<Compile Remove="Altcoins\**\*.cs"></Compile>
|
||||
|
@ -23,7 +23,7 @@ namespace BTCPayServer
|
||||
internal Task ProcessTask;
|
||||
public async Task Process(CancellationToken cancellationToken)
|
||||
{
|
||||
retry:
|
||||
retry:
|
||||
while (Chan.Reader.TryRead(out var item))
|
||||
{
|
||||
await item(cancellationToken);
|
||||
@ -52,7 +52,7 @@ retry:
|
||||
{
|
||||
lock (_Queues)
|
||||
{
|
||||
retry:
|
||||
retry:
|
||||
if (stopped)
|
||||
return;
|
||||
Cleanup();
|
||||
|
@ -67,7 +67,7 @@ namespace BTCPayServer.Data
|
||||
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
||||
public DbSet<WebhookDeliveryData> WebhookDeliveries { 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; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
@ -105,10 +105,10 @@ namespace BTCPayServer.Data
|
||||
//PlannedTransaction.OnModelCreating(builder);
|
||||
PullPaymentData.OnModelCreating(builder);
|
||||
RefundData.OnModelCreating(builder);
|
||||
SettingData.OnModelCreating(builder, Database);
|
||||
//SettingData.OnModelCreating(builder);
|
||||
StoreSettingData.OnModelCreating(builder, Database);
|
||||
StoreWebhookData.OnModelCreating(builder);
|
||||
StoreData.OnModelCreating(builder, Database);
|
||||
//StoreData.OnModelCreating(builder);
|
||||
U2FDevice.OnModelCreating(builder);
|
||||
Fido2Credential.OnModelCreating(builder);
|
||||
BTCPayServer.Data.UserStore.OnModelCreating(builder);
|
||||
|
@ -14,28 +14,28 @@ public class CustodianAccountData
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string StoreId { get; set; }
|
||||
|
||||
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string CustodianCode { get; set; }
|
||||
|
||||
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public byte[] Blob { get; set; }
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public StoreData StoreData { get; set; }
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<CustodianAccountData>()
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(i => i.CustodianAccounts)
|
||||
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
builder.Entity<APIKeyData>()
|
||||
.HasIndex(o => o.StoreId);
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data.Data;
|
||||
|
||||
public class FormData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Config { get; set; }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BTCPayServer.Data;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BTCPayServer.Data.Data;
|
||||
@ -11,9 +11,9 @@ public class PayoutProcessorData
|
||||
public StoreData Store { get; set; }
|
||||
public string PaymentMethod { get; set; }
|
||||
public string Processor { get; set; }
|
||||
|
||||
|
||||
public byte[] Blob { get; set; }
|
||||
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
public class SettingData
|
||||
@ -8,15 +5,5 @@ namespace BTCPayServer.Data
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<SettingData>()
|
||||
.Property(o => o.Value)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using PayoutProcessorData = BTCPayServer.Data.Data.PayoutProcessorData;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
@ -25,6 +23,7 @@ namespace BTCPayServer.Data
|
||||
[Obsolete("Use GetDerivationStrategies instead")]
|
||||
public string DerivationStrategy { get; set; }
|
||||
|
||||
[Obsolete("Use GetDerivationStrategies instead")]
|
||||
public string DerivationStrategies { get; set; }
|
||||
|
||||
public string StoreName { get; set; }
|
||||
@ -37,7 +36,7 @@ namespace BTCPayServer.Data
|
||||
|
||||
[NotMapped] public string Role { get; set; }
|
||||
|
||||
public string StoreBlob { get; set; }
|
||||
public byte[] StoreBlob { get; set; }
|
||||
|
||||
[Obsolete("Use GetDefaultPaymentId instead")]
|
||||
public string DefaultCrypto { get; set; }
|
||||
@ -49,19 +48,5 @@ namespace BTCPayServer.Data
|
||||
public IEnumerable<PayoutData> Payouts { get; set; }
|
||||
public IEnumerable<CustodianAccountData> CustodianAccounts { get; set; }
|
||||
public IEnumerable<StoreSettingData> Settings { get; set; }
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
if (databaseFacade.IsNpgsql())
|
||||
{
|
||||
builder.Entity<StoreData>()
|
||||
.Property(o => o.StoreBlob)
|
||||
.HasColumnType("JSONB");
|
||||
|
||||
builder.Entity<StoreData>()
|
||||
.Property(o => o.DerivationStrategies)
|
||||
.HasColumnType("JSONB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public class StoreSettingData
|
||||
public string Value { get; set; }
|
||||
|
||||
public StoreData Store { get; set; }
|
||||
|
||||
|
||||
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
builder.Entity<StoreSettingData>().HasKey(data => new { data.StoreId, data.Name });
|
||||
|
@ -2,5 +2,5 @@ namespace BTCPayServer.Data;
|
||||
|
||||
public class TradeResultData
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,44 +21,42 @@ namespace BTCPayServer.Data
|
||||
public const string PayjoinExposed = "pj-exposed";
|
||||
public const string Payout = "payout";
|
||||
public const string PullPayment = "pull-payment";
|
||||
public const string Address = "address";
|
||||
public const string Utxo = "utxo";
|
||||
}
|
||||
public string WalletId { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Data { get; set; }
|
||||
|
||||
public List<WalletObjectLinkData> Bs { get; set; }
|
||||
public List<WalletObjectLinkData> As { get; set; }
|
||||
public List<WalletObjectLinkData> ChildLinks { get; set; }
|
||||
public List<WalletObjectLinkData> ParentLinks { get; set; }
|
||||
|
||||
public IEnumerable<(string type, string id, string linkdata, string objectdata)> GetLinks()
|
||||
{
|
||||
if (Bs is not null)
|
||||
foreach (var c in Bs)
|
||||
if (ChildLinks is not null)
|
||||
foreach (var c in ChildLinks)
|
||||
{
|
||||
yield return (c.BType, c.BId, c.Data, c.B?.Data);
|
||||
yield return (c.ChildType, c.ChildId, c.Data, c.Child?.Data);
|
||||
}
|
||||
if (As is not null)
|
||||
foreach (var c in As)
|
||||
if (ParentLinks is not null)
|
||||
foreach (var c in ParentLinks)
|
||||
{
|
||||
yield return (c.AType, c.AId, c.Data, c.A?.Data);
|
||||
yield return (c.ParentType, c.ParentId, c.Data, c.Parent?.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<WalletObjectData> GetNeighbours()
|
||||
{
|
||||
if (Bs != null)
|
||||
foreach (var c in Bs)
|
||||
if (ChildLinks != null)
|
||||
foreach (var c in ChildLinks)
|
||||
{
|
||||
if (c.B != null)
|
||||
yield return c.B;
|
||||
if (c.Child != null)
|
||||
yield return c.Child;
|
||||
}
|
||||
if (As != null)
|
||||
foreach (var c in As)
|
||||
if (ParentLinks != null)
|
||||
foreach (var c in ParentLinks)
|
||||
{
|
||||
if (c.A != null)
|
||||
yield return c.A;
|
||||
if (c.Parent != null)
|
||||
yield return c.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,14 @@ namespace BTCPayServer.Data
|
||||
public class WalletObjectLinkData
|
||||
{
|
||||
public string WalletId { get; set; }
|
||||
public string AType { get; set; }
|
||||
public string AId { get; set; }
|
||||
public string BType { get; set; }
|
||||
public string BId { get; set; }
|
||||
public string ParentType { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ChildType { get; set; }
|
||||
public string ChildId { get; set; }
|
||||
public string Data { get; set; }
|
||||
|
||||
public WalletObjectData A { get; set; }
|
||||
public WalletObjectData B { get; set; }
|
||||
public WalletObjectData Parent { get; set; }
|
||||
public WalletObjectData Child { get; set; }
|
||||
|
||||
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||
{
|
||||
@ -26,28 +26,28 @@ namespace BTCPayServer.Data
|
||||
new
|
||||
{
|
||||
o.WalletId,
|
||||
o.AType,
|
||||
o.AId,
|
||||
o.BType,
|
||||
o.BId,
|
||||
o.ParentType,
|
||||
o.ParentId,
|
||||
o.ChildType,
|
||||
o.ChildId,
|
||||
});
|
||||
builder.Entity<WalletObjectLinkData>().HasIndex(o => new
|
||||
{
|
||||
o.WalletId,
|
||||
o.BType,
|
||||
o.BId,
|
||||
o.ChildType,
|
||||
o.ChildId,
|
||||
});
|
||||
|
||||
builder.Entity<WalletObjectLinkData>()
|
||||
.HasOne(o => o.A)
|
||||
.WithMany(o => o.Bs)
|
||||
.HasForeignKey(o => new { o.WalletId, o.AType, o.AId })
|
||||
.HasOne(o => o.Parent)
|
||||
.WithMany(o => o.ChildLinks)
|
||||
.HasForeignKey(o => new { o.WalletId, o.ParentType, o.ParentId })
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.Entity<WalletObjectLinkData>()
|
||||
.HasOne(o => o.B)
|
||||
.WithMany(o => o.As)
|
||||
.HasForeignKey(o => new { o.WalletId, o.BType, o.BId })
|
||||
.HasOne(o => o.Child)
|
||||
.WithMany(o => o.ParentLinks)
|
||||
.HasForeignKey(o => new { o.WalletId, o.ChildType, o.ChildId })
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
if (databaseFacade.IsNpgsql())
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
|
@ -40,33 +40,33 @@ namespace BTCPayServer.Migrations
|
||||
columns: table => new
|
||||
{
|
||||
WalletId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
BType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
BId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ParentType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ParentId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ChildType = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ChildId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Data = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_WalletObjectLinks", x => new { x.WalletId, x.AType, x.AId, x.BType, x.BId });
|
||||
table.PrimaryKey("PK_WalletObjectLinks", x => new { x.WalletId, x.ParentType, x.ParentId, x.ChildType, x.ChildId });
|
||||
table.ForeignKey(
|
||||
name: "FK_WalletObjectLinks_WalletObjects_WalletId_BType_BId",
|
||||
columns: x => new { x.WalletId, x.BType, x.BId },
|
||||
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ChildType_ChildId",
|
||||
columns: x => new { x.WalletId, x.ChildType, x.ChildId },
|
||||
principalTable: "WalletObjects",
|
||||
principalColumns: new[] { "WalletId", "Type", "Id" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_WalletObjectLinks_WalletObjects_WalletId_AType_AId",
|
||||
columns: x => new { x.WalletId, x.AType, x.AId },
|
||||
name: "FK_WalletObjectLinks_WalletObjects_WalletId_ParentType_ParentId",
|
||||
columns: x => new { x.WalletId, x.ParentType, x.ParentId },
|
||||
principalTable: "WalletObjects",
|
||||
principalColumns: new[] { "WalletId", "Type", "Id" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_WalletObjectLinks_WalletId_BType_BId",
|
||||
name: "IX_WalletObjectLinks_WalletId_ChildType_ChildId",
|
||||
table: "WalletObjectLinks",
|
||||
columns: new[] { "WalletId", "BType", "BId" });
|
||||
columns: new[] { "WalletId", "ChildType", "ChildId" });
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
|
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20221128062447_jsonb")]
|
||||
public partial class jsonb : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.IsNpgsql())
|
||||
{
|
||||
migrationBuilder.Sql("ALTER TABLE \"Settings\" ALTER COLUMN \"Value\" TYPE JSONB USING \"Value\"::JSONB");
|
||||
migrationBuilder.Sql("ALTER TABLE \"Stores\" ALTER COLUMN \"StoreBlob\" TYPE JSONB USING regexp_replace(convert_from(\"StoreBlob\",'UTF8'), '\\\\u0000', '', 'g')::JSONB");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Not supported
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20230123062447_migrateoldratesource")]
|
||||
public partial class migrateoldratesource : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.IsNpgsql())
|
||||
{
|
||||
migrationBuilder.Sql("UPDATE \"Stores\" SET \"StoreBlob\"=jsonb_set(\"StoreBlob\", \'{preferredExchange}\', \'{\"oasis_trade\": \"oasisdev\", \"gdax\":\"coinbasepro\", \"coinaverage\":\"coingecko\"}\'::jsonb->(\"StoreBlob\"->>\'preferredExchange\')) WHERE \"StoreBlob\"->>\'preferredExchange\' = ANY (ARRAY[\'oasis_trade\', \'gdax\', \'coinaverage\']);");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Not supported
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20230130062447_jsonb2")]
|
||||
public partial class jsonb2 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.IsNpgsql())
|
||||
{
|
||||
migrationBuilder.Sql("ALTER TABLE \"Stores\" ALTER COLUMN \"DerivationStrategies\" TYPE JSONB USING \"DerivationStrategies\"::JSONB");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Not supported
|
||||
}
|
||||
}
|
||||
}
|
@ -872,24 +872,24 @@ namespace BTCPayServer.Migrations
|
||||
b.Property<string>("WalletId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AType")
|
||||
b.Property<string>("ParentType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AId")
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("BType")
|
||||
b.Property<string>("ChildType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("BId")
|
||||
b.Property<string>("ChildId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Data")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("WalletId", "AType", "AId", "BType", "BId");
|
||||
b.HasKey("WalletId", "ParentType", "ParentId", "ChildType", "ChildId");
|
||||
|
||||
b.HasIndex("WalletId", "BType", "BId");
|
||||
b.HasIndex("WalletId", "ChildType", "ChildId");
|
||||
|
||||
b.ToTable("WalletObjectLinks");
|
||||
});
|
||||
@ -1384,21 +1384,21 @@ namespace BTCPayServer.Migrations
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.WalletObjectLinkData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.WalletObjectData", "A")
|
||||
.WithMany("Bs")
|
||||
.HasForeignKey("WalletId", "AType", "AId")
|
||||
b.HasOne("BTCPayServer.Data.WalletObjectData", "Child")
|
||||
.WithMany("ParentLinks")
|
||||
.HasForeignKey("WalletId", "ChildType", "ChildId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("BTCPayServer.Data.WalletObjectData", "B")
|
||||
.WithMany("As")
|
||||
.HasForeignKey("WalletId", "BType", "BId")
|
||||
b.HasOne("BTCPayServer.Data.WalletObjectData", "Parent")
|
||||
.WithMany("ChildLinks")
|
||||
.HasForeignKey("WalletId", "ParentType", "ParentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("A");
|
||||
b.Navigation("Child");
|
||||
|
||||
b.Navigation("B");
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b =>
|
||||
@ -1545,9 +1545,9 @@ namespace BTCPayServer.Migrations
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.WalletObjectData", b =>
|
||||
{
|
||||
b.Navigation("As");
|
||||
b.Navigation("ChildLinks");
|
||||
|
||||
b.Navigation("Bs");
|
||||
b.Navigation("ParentLinks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.WebhookData", b =>
|
||||
|
@ -26,8 +26,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BTCPayServer.NETCore.Plugins.Mvc" Version="1.4.4" />
|
||||
<ProjectReference Include="..\BTCPayServer\BTCPayServer.csproj" />
|
||||
<PackageReference Include="McMaster.NETCore.Plugins.Mvc" Version="1.4.0" />
|
||||
<ProjectReference Include="..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />
|
||||
<None Include="icon.png" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -28,13 +28,13 @@ namespace BTCPayServer.PluginPacker
|
||||
var name = args[1];
|
||||
var outputDir = Path.Combine(args[2], name);
|
||||
var outputFile = Path.Combine(outputDir, name);
|
||||
var rootDLLPath = Path.GetFullPath(Path.Combine(directory, name + ".dll"));
|
||||
var rootDLLPath = Path.Combine(directory, name + ".dll");
|
||||
if (!File.Exists(rootDLLPath))
|
||||
{
|
||||
throw new Exception($"{rootDLLPath} could not be found");
|
||||
}
|
||||
|
||||
var plugin = PluginLoader.CreateFromAssemblyFile(rootDLLPath, false, new[] { typeof(IBTCPayServerPlugin) }, o => o.PreferSharedTypes = true);
|
||||
var plugin = PluginLoader.CreateFromAssemblyFile(rootDLLPath, false, new[] { typeof(IBTCPayServerPlugin) });
|
||||
var assembly = plugin.LoadAssembly(name);
|
||||
var extension = GetAllExtensionTypesFromAssembly(assembly).FirstOrDefault();
|
||||
if (extension is null)
|
||||
@ -57,8 +57,8 @@ namespace BTCPayServer.PluginPacker
|
||||
|
||||
var sha256sums = new StringBuilder();
|
||||
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(
|
||||
$"{Encoders.Hex.EncodeData(Hashes.SHA256(await File.ReadAllBytesAsync(outputFile + ".btcpay")))} {name}.btcpay");
|
||||
|
||||
@ -68,7 +68,7 @@ namespace BTCPayServer.PluginPacker
|
||||
File.Delete(sha256dirs);
|
||||
}
|
||||
await File.WriteAllTextAsync(sha256dirs, sha256sums.ToString());
|
||||
|
||||
|
||||
// try Windows executable first, fall back to macOS/Linux PowerShell
|
||||
try
|
||||
{
|
||||
@ -86,7 +86,7 @@ namespace BTCPayServer.PluginPacker
|
||||
$"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine($"Created {outputFile}.btcpay at {directory}");
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<ProjectReference Include="..\..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\BTCPayServer.Abstractions\BTCPayServer.Abstractions.csproj" />
|
||||
<EmbeddedResource Include="Resources\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user