Compare commits
341 Commits
price-sour
...
fix-array-
Author | SHA1 | Date | |
---|---|---|---|
|
8290a1606f | ||
|
eddd458744 | ||
|
439ea20a89 | ||
|
cec223c8e7 | ||
|
25cb188d00 | ||
|
31007a8d96 | ||
|
a4fa8db69b | ||
|
6193835ea1 | ||
|
0c78e9e4ac | ||
|
58c409e7fa | ||
|
9577eed524 | ||
|
76f32cd064 | ||
|
92d9c17095 | ||
|
b0396df33f | ||
|
c17572c76f | ||
|
5c91e072a6 | ||
|
4991d0f965 | ||
|
45b74e1ce5 | ||
|
ccb4b9a9ba | ||
|
dd635071d6 | ||
|
fe1448dfae | ||
|
56855bc54d | ||
|
b51fa8df5a | ||
|
3aa979cb11 | ||
|
c95f75bc6c | ||
|
b13a636f89 | ||
|
8de55cef31 | ||
|
cb781f42e3 | ||
|
b59292dc24 | ||
|
03b793d7e2 | ||
|
bee18d1cfb | ||
|
d8698181f4 | ||
|
47f5d97eaf | ||
|
cb3c5e56fd | ||
|
39b76c08de | ||
|
c3c8cc21ff | ||
|
6dba1b6d8b | ||
|
381fe70a79 | ||
|
feb927c2e4 | ||
|
e77bd4c188 | ||
|
43436fc49e | ||
|
d738f797ec | ||
|
b5de97f785 | ||
|
b0c1b0895d | ||
|
8e60932f81 | ||
|
7d14cd74f2 | ||
|
717f1610f5 | ||
|
f1abe6497f | ||
|
046129a57d | ||
|
90d300a490 | ||
|
a2d506c0db | ||
|
58748a24da | ||
|
639e8a4a1d | ||
|
48ebaf5c5a | ||
|
1aaccb1e6b | ||
|
f05a7f9f14 | ||
|
98ddb348b0 | ||
|
a4aa85ebab | ||
|
516efe56f4 | ||
|
a4d72d5bbc | ||
|
24b8ec16f1 | ||
|
ac25fef555 | ||
|
8302f082a2 | ||
|
7546ef7a8e | ||
|
f598c70a4f | ||
|
422da21de5 | ||
|
f530fb3241 | ||
|
5d39bb7466 | ||
|
041cba72b6 | ||
|
892b3e273f | ||
|
91faf5756d | ||
|
e239390ebf | ||
|
b24764d679 | ||
|
4d5a568fd7 | ||
|
5ab55e71e0 | ||
|
929d63ecf8 | ||
|
0ef7f3715f | ||
|
2298f3901a | ||
|
3005f1937a | ||
|
f48eec2e93 | ||
|
754d304e54 | ||
|
9b8d08a668 | ||
|
1b672a1ace | ||
|
60d6e98c67 | ||
|
11f05285a1 | ||
|
2bd1842da1 | ||
|
57544068e9 | ||
|
60cfea9f94 | ||
|
eece001376 | ||
|
98d8ef8e1a | ||
|
0e43042217 | ||
|
c8e6714207 | ||
|
824e779eb2 | ||
|
83ea898780 | ||
|
5af3233fd6 | ||
|
08ff2f3173 | ||
|
22657b66d7 | ||
|
8b6c7a6061 | ||
|
1f197f6688 | ||
|
1055e61bb4 | ||
|
7ad0aa82fc | ||
|
d3f5576570 | ||
|
45141d1391 | ||
|
de9ac9fd43 | ||
|
c53d5272d6 | ||
|
18c78192ec | ||
|
632d67eef4 | ||
|
c23aa48688 | ||
|
95f3e429b4 | ||
|
8635fcfe84 | ||
|
d861537d9a | ||
|
631ee99f60 | ||
|
ffa1441ccd | ||
|
2f3e947027 | ||
|
a62aecfdfe | ||
|
5f829c68f2 | ||
|
0290d74aeb | ||
|
f6bc16007d | ||
|
ad5752f09b | ||
|
55565f1718 | ||
|
5f96d17b8c | ||
|
fd22406e0a | ||
|
64fe542c1e | ||
|
fae1dc8dbb | ||
|
6f2b673021 | ||
|
b26679ca14 | ||
|
04ba1430ca | ||
|
53f3758abc | ||
|
c6742f5533 | ||
|
cb44591a47 | ||
|
e02abb509f | ||
|
eff6be9643 | ||
|
348dbd7107 | ||
|
f74ea14d8b | ||
|
a671632fde | ||
|
e344622c9e | ||
|
06d7483ca3 | ||
|
7fe041fc2c | ||
|
3f18e5476a | ||
|
2a31613fe8 | ||
|
ded0c8a3bc | ||
|
f3d9e07c5e | ||
|
eb3ba95114 | ||
|
7951dcada6 | ||
|
06951a39c6 | ||
|
abe29f21f0 | ||
|
f57eab3008 | ||
|
6d4b2348ac | ||
|
397ca6ef0c | ||
|
d6e5ee2851 | ||
|
98d62e826b | ||
|
7b5ce8f70c | ||
|
2010a9a458 | ||
|
f787058c17 | ||
|
87ccae0d90 | ||
|
07d95c6ed7 | ||
|
514823f7d2 | ||
|
fb4feb24f3 | ||
|
5caa0e0722 | ||
|
0406b420c8 | ||
|
9d72b9779e | ||
|
fdc47e4a38 | ||
|
0566e964c0 | ||
|
896fbf9a5c | ||
|
126c8c101e | ||
|
3cb7cc01e4 | ||
|
2b3d15bf45 | ||
|
4049bdadcb | ||
|
2042ba37d8 | ||
|
41a4ba62b0 | ||
|
21558d25b1 | ||
|
06622bfbfd | ||
|
16fd2e3938 | ||
|
040d7670ec | ||
|
23761eacc1 | ||
|
5790bed766 | ||
|
2f88da67e8 | ||
|
21091cbf1a | ||
|
808949a884 | ||
|
06334273dc | ||
|
5399c04dff | ||
|
cd051d4093 | ||
|
0ca6e8ccfb | ||
|
bd075919f3 | ||
|
c229425534 | ||
|
e89b1826ce | ||
|
4ef19e19cc | ||
|
ff58301729 | ||
|
4ae05272c3 | ||
|
d14dafc871 | ||
|
022a077726 | ||
|
d5bd86b07a | ||
|
66e1eee010 | ||
|
ddb125f458 | ||
|
e6a157a101 | ||
|
0a437fba6a | ||
|
39f2e80dc1 | ||
|
13f9eb0d18 | ||
|
575b829799 | ||
|
02e50fadae | ||
|
a02f191034 | ||
|
d73d0f178f | ||
|
d542a61f5a | ||
|
e0486aaa24 | ||
|
02bf76fb3c | ||
|
8a3ece4a70 | ||
|
c553dc02a9 | ||
|
ff71caa47e | ||
|
2bd8227e20 | ||
|
5c61de3ae9 | ||
|
cff46f2d59 | ||
|
bbbaacc350 | ||
|
60f84d5e30 | ||
|
5218aa3c43 | ||
|
4b2ea0c0c3 | ||
|
9b865ef849 | ||
|
9344113ae4 | ||
|
4448ac9d2a | ||
|
9aff143d40 | ||
|
fc14f418cb | ||
|
b99253ff47 | ||
|
9cb844cbbb | ||
|
285aedef2f | ||
|
5121d64022 | ||
|
8b80910d70 | ||
|
a5ff655eed | ||
|
cc9c63c33e | ||
|
87eef72289 | ||
|
8e8ba3d052 | ||
|
fea27b900c | ||
|
7ad91a76cd | ||
|
a62b674722 | ||
|
350f35b08d | ||
|
f405321abc | ||
|
0d077f6ce5 | ||
|
dffa6accb0 | ||
|
b5abcd5ae5 | ||
|
72a9e676c1 | ||
|
3658b396d3 | ||
|
537acab16d | ||
|
8c6fe91c71 | ||
|
3c344331af | ||
|
d14ce2a37f | ||
|
33d272d4b0 | ||
|
57f5c15670 | ||
|
487faa69c6 | ||
|
9148a1e564 | ||
|
4c3f5e1e1a | ||
|
b0bf0824dd | ||
|
dea5991e01 | ||
|
739932a280 | ||
|
1f8bc5b490 | ||
|
753ffd401b | ||
|
0d1bab45a0 | ||
|
17cc439de3 | ||
|
5d03e300fb | ||
|
a20408bed1 | ||
|
ed0ccd6f13 | ||
|
bb1138efb5 | ||
|
82b36aaca7 | ||
|
688044429e | ||
|
7bbfc8e6d4 | ||
|
85513aa5c3 | ||
|
67254cc30c | ||
|
b055844973 | ||
|
9ba03848f2 | ||
|
5b96ab89fd | ||
|
6a4d8f7404 | ||
|
219d03b8dd | ||
|
523654f2eb | ||
|
b9b8cb9f63 | ||
|
94f2cd4257 | ||
|
26248774c2 | ||
|
99299ba06f | ||
|
6e42eaa26c | ||
|
ae7b621e3d | ||
|
f2ced20c42 | ||
|
e4f256d5cd | ||
|
ca1dac4cc3 | ||
|
8fc2729fab | ||
|
24c19efd52 | ||
|
a3edd829a6 | ||
|
9ec475fa40 | ||
|
aad06c583e | ||
|
f821e35cb0 | ||
|
14313291d5 | ||
|
b818352a04 | ||
|
c0c34fbb41 | ||
|
b372dc21d6 | ||
|
3d576cd06b | ||
|
438dcc4c6f | ||
|
de4ac2c830 | ||
|
f46443a5e3 | ||
|
69e90b7ff1 | ||
|
5089ec9826 | ||
|
372df93c18 | ||
|
1d2ddeedde | ||
|
4df2f1f756 | ||
|
f10c1c4730 | ||
|
92b556e54f | ||
|
b46ae7a651 | ||
|
9f3a3c5f51 | ||
|
b5071237fd | ||
|
1d2bebf17a | ||
|
9086822b94 | ||
|
d90d3c5a0f | ||
|
a3203e5775 | ||
|
5f24b41250 | ||
|
b577c0adb7 | ||
|
a9ad0fde9e | ||
|
9974b6070e | ||
|
bd5e4f3d94 | ||
|
e0adb1133d | ||
|
3cdb4f5b2a | ||
|
248401f534 | ||
|
1228a06a90 | ||
|
b5cd215643 | ||
|
7604667b55 | ||
|
3a278d8079 | ||
|
adcc484528 | ||
|
798553e96a | ||
|
068b717a75 | ||
|
785cf597ad | ||
|
ee70fe85c0 | ||
|
2e31816979 | ||
|
e4237c9511 | ||
|
0bc6967dbc | ||
|
2301769419 | ||
|
42c5f732a2 | ||
|
2428b564fd | ||
|
bb0e96a163 | ||
|
bb733c5811 | ||
|
ffeaf55c4e | ||
|
a12bb1d9ce | ||
|
313f2a667e | ||
|
d5d0be5824 | ||
|
3fa28bb46d | ||
|
eb90fab640 | ||
|
099d65032a | ||
|
e96feb36cd | ||
|
eb6d01c21e |
@@ -11,10 +11,14 @@ insert_final_newline = true
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
space_before_self_closing = true
|
||||||
|
|
||||||
[*.json]
|
[*.json]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[swagger*.json]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
# C# files
|
# C# files
|
||||||
[*.cs]
|
[*.cs]
|
||||||
# New line preferences
|
# New line preferences
|
||||||
@@ -67,7 +71,7 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
|||||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
||||||
|
|
||||||
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
||||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||||
|
|
||||||
# Code style defaults
|
# Code style defaults
|
||||||
dotnet_sort_system_directives_first = true
|
dotnet_sort_system_directives_first = true
|
||||||
|
12
.github/ISSUE_TEMPLATE/config.yml
vendored
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,14 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 🚀 Discussions
|
- name: 💡 Request a feature
|
||||||
url: https://github.com/btcpayserver/btcpayserver/discussions
|
url: https://github.com/btcpayserver/btcpayserver/discussions/categories/ideas-feature-requests
|
||||||
about: Technical discussions, questions and feature requests
|
about: Submit a feature request or vote on ideas posted by others. Features with most upvotes become roadmap candidates
|
||||||
|
- name: 🧑💻 Ask a technical question
|
||||||
|
url: https://github.com/btcpayserver/btcpayserver/discussions/new?category=technical-support
|
||||||
|
about: If you're experiencing a technical problem post it to our community support forum
|
||||||
|
- name: 🔌 Report a problem with a plugin
|
||||||
|
url: https://github.com/btcpayserver/btcpayserver/discussions/new?category=plugins-integrations
|
||||||
|
about: Experiencing a problem with a third-party plugin? Post it here and we will tag their developers to assist
|
||||||
- name: 📝 Official Documentation
|
- name: 📝 Official Documentation
|
||||||
url: https://docs.btcpayserver.org
|
url: https://docs.btcpayserver.org
|
||||||
about: Check our documentation for answers to common questions
|
about: Check our documentation for answers to common questions
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -298,3 +298,4 @@ Packed Plugins
|
|||||||
Plugins/packed
|
Plugins/packed
|
||||||
|
|
||||||
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
||||||
|
BTCPayServer/appsettings.dev.json
|
@@ -1,21 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="Pack Test Plugin" type="DotNetProject" factoryName=".NET Project" singleton="false">
|
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/BTCPayServer.PluginPacker/bin/Debug/netcoreapp3.1/BTCPayServer.PluginPacker.dll" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="../../../../BTCPayServer.Plugins.Test\bin\Debug\netcoreapp3.1 BTCPayServer.Plugins.Test "../../../../Packed Plugins"" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/BTCPayServer.PluginPacker/bin/Debug/netcoreapp3.1" />
|
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/BTCPayServer.PluginPacker/BTCPayServer.PluginPacker.csproj" />
|
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
|
||||||
<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" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
@@ -1,3 +1,5 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace BTCPayServer.Configuration
|
namespace BTCPayServer.Configuration
|
||||||
{
|
{
|
||||||
public class DataDirectories
|
public class DataDirectories
|
||||||
@@ -7,5 +9,12 @@ namespace BTCPayServer.Configuration
|
|||||||
public string TempStorageDir { get; set; }
|
public string TempStorageDir { get; set; }
|
||||||
public string StorageDir { get; set; }
|
public string StorageDir { get; set; }
|
||||||
public string TempDir { get; set; }
|
public string TempDir { get; set; }
|
||||||
|
|
||||||
|
public string ToDatadirFullPath(string path)
|
||||||
|
{
|
||||||
|
if (Path.IsPathRooted(path))
|
||||||
|
return path;
|
||||||
|
return Path.Combine(DataDir, path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
@@ -19,6 +19,8 @@ namespace BTCPayServer.Abstractions.Contracts
|
|||||||
public class NotificationViewModel
|
public class NotificationViewModel
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
public string ActionLink { get; set; }
|
public string ActionLink { get; set; }
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
namespace BTCPayServer.Abstractions.Contracts;
|
namespace BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
public interface IScopeProvider
|
public interface IScopeProvider
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Contracts;
|
namespace BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ public class AssetQuoteResult
|
|||||||
|
|
||||||
public AssetQuoteResult() { }
|
public AssetQuoteResult() { }
|
||||||
|
|
||||||
public AssetQuoteResult(string fromAsset, string toAsset,decimal bid, decimal ask)
|
public AssetQuoteResult(string fromAsset, string toAsset, decimal bid, decimal ask)
|
||||||
{
|
{
|
||||||
FromAsset = fromAsset;
|
FromAsset = fromAsset;
|
||||||
ToAsset = toAsset;
|
ToAsset = toAsset;
|
||||||
|
@@ -2,10 +2,11 @@ namespace BTCPayServer.Abstractions.Custodians;
|
|||||||
|
|
||||||
public class AssetBalancesUnavailableException : CustodianApiException
|
public class AssetBalancesUnavailableException : CustodianApiException
|
||||||
{
|
{
|
||||||
|
|
||||||
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AssetBalancesUnavailableException(string errorMsg) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {errorMsg}")
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
public class CustodianApiException: Exception {
|
public class CustodianApiException : Exception
|
||||||
|
{
|
||||||
public int HttpStatus { get; }
|
public int HttpStatus { get; }
|
||||||
public string Code { get; }
|
public string Code { get; }
|
||||||
|
|
||||||
@@ -9,7 +10,8 @@ public class CustodianApiException: Exception {
|
|||||||
HttpStatus = httpStatus;
|
HttpStatus = httpStatus;
|
||||||
Code = code;
|
Code = code;
|
||||||
}
|
}
|
||||||
public CustodianApiException( int httpStatus, string code, string message) : this(httpStatus, code, message, null)
|
|
||||||
|
public CustodianApiException(int httpStatus, string code, string message) : this(httpStatus, code, message, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class CustodianFeatureNotImplementedException: CustodianApiException
|
public class CustodianFeatureNotImplementedException : CustodianApiException
|
||||||
{
|
{
|
||||||
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class InsufficientFundsException : CustodianApiException
|
public class InsufficientFundsException : CustodianApiException
|
||||||
{
|
{
|
||||||
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ public class TradeNotFoundException : CustodianApiException
|
|||||||
{
|
{
|
||||||
private string tradeId { get; }
|
private string tradeId { get; }
|
||||||
|
|
||||||
public TradeNotFoundException(string tradeId) : base(404,"trade-not-found","Could not find trade ID " + tradeId)
|
public TradeNotFoundException(string tradeId) : base(404, "trade-not-found", "Could not find trade ID " + tradeId)
|
||||||
{
|
{
|
||||||
this.tradeId = tradeId;
|
this.tradeId = tradeId;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
public class WrongTradingPairException: CustodianApiException
|
public class WrongTradingPairException : CustodianApiException
|
||||||
{
|
{
|
||||||
public const int HttpCode = 404;
|
public const int HttpCode = 404;
|
||||||
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
|
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Abstractions.Custodians.Client;
|
||||||
|
|
||||||
|
public class SimulateWithdrawalResult
|
||||||
|
{
|
||||||
|
public string PaymentMethod { get; }
|
||||||
|
public string Asset { get; }
|
||||||
|
public decimal MinQty { get; }
|
||||||
|
public decimal MaxQty { get; }
|
||||||
|
|
||||||
|
public List<LedgerEntryData> LedgerEntries { get; }
|
||||||
|
|
||||||
|
// Fee can be NULL if unknown.
|
||||||
|
public decimal? Fee { get; }
|
||||||
|
|
||||||
|
public SimulateWithdrawalResult(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries,
|
||||||
|
decimal minQty, decimal maxQty)
|
||||||
|
{
|
||||||
|
PaymentMethod = paymentMethod;
|
||||||
|
Asset = asset;
|
||||||
|
LedgerEntries = ledgerEntries;
|
||||||
|
MinQty = minQty;
|
||||||
|
MaxQty = maxQty;
|
||||||
|
}
|
||||||
|
}
|
@@ -9,18 +9,16 @@ namespace BTCPayServer.Abstractions.Custodians;
|
|||||||
|
|
||||||
public interface ICanTrade
|
public interface ICanTrade
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
|
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
|
||||||
*/
|
*/
|
||||||
public List<AssetPairData> GetTradableAssetPairs();
|
public List<AssetPairData> GetTradableAssetPairs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a market order right now.
|
* Execute a market order right now.
|
||||||
*/
|
*/
|
||||||
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the details about a previous market trade.
|
* Get the details about a previous market trade.
|
||||||
*/
|
*/
|
||||||
|
@@ -5,9 +5,14 @@ using Newtonsoft.Json.Linq;
|
|||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Custodians;
|
namespace BTCPayServer.Abstractions.Custodians;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for custodians that can move funds to the store wallet.
|
||||||
|
/// </summary>
|
||||||
public interface ICanWithdraw
|
public interface ICanWithdraw
|
||||||
{
|
{
|
||||||
public Task<WithdrawResult> WithdrawAsync(string paymentMethod, decimal amount, JObject config, CancellationToken cancellationToken);
|
public Task<WithdrawResult> WithdrawToStoreWalletAsync(string paymentMethod, decimal amount, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public Task<SimulateWithdrawalResult> SimulateWithdrawalAsync(string paymentMethod, decimal qty, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
public Task<WithdrawResult> GetWithdrawalInfoAsync(string paymentMethod, string withdrawalId, JObject config, CancellationToken cancellationToken);
|
public Task<WithdrawResult> GetWithdrawalInfoAsync(string paymentMethod, string withdrawalId, JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
#nullable enable
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -12,7 +13,7 @@ public interface ICustodian
|
|||||||
* Get the unique code that identifies this custodian.
|
* Get the unique code that identifies this custodian.
|
||||||
*/
|
*/
|
||||||
string Code { get; }
|
string Code { get; }
|
||||||
|
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,6 @@ public interface ICustodian
|
|||||||
*/
|
*/
|
||||||
Task<Dictionary<string, decimal>> GetAssetBalancesAsync(JObject config, CancellationToken cancellationToken);
|
Task<Dictionary<string, decimal>> GetAssetBalancesAsync(JObject config, CancellationToken cancellationToken);
|
||||||
|
|
||||||
public Task<Form.Form> GetConfigForm(JObject config, string locale,
|
public Task<Form.Form> GetConfigForm(JObject config, CancellationToken cancellationToken = default);
|
||||||
CancellationToken cancellationToken = default);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,10 @@ namespace BTCPayServer.Abstractions.Extensions;
|
|||||||
|
|
||||||
public static class GreenfieldExtensions
|
public static class GreenfieldExtensions
|
||||||
{
|
{
|
||||||
|
public static IActionResult UserNotFound(this ControllerBase ctrl)
|
||||||
|
{
|
||||||
|
return ctrl.CreateAPIError(404, "user-not-found", "The user was not found");
|
||||||
|
}
|
||||||
public static IActionResult CreateValidationError(this ControllerBase controller, ModelStateDictionary modelState)
|
public static IActionResult CreateValidationError(this ControllerBase controller, ModelStateDictionary modelState)
|
||||||
{
|
{
|
||||||
return controller.UnprocessableEntity(modelState.ToGreenfieldValidationError());
|
return controller.UnprocessableEntity(modelState.ToGreenfieldValidationError());
|
||||||
@@ -30,12 +34,12 @@ public static class GreenfieldExtensions
|
|||||||
{
|
{
|
||||||
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
||||||
{
|
{
|
||||||
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
||||||
{
|
{
|
||||||
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
||||||
|
@@ -11,7 +11,7 @@ public static class HttpRequestExtensions
|
|||||||
return false;
|
return false;
|
||||||
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAbsoluteRoot(this HttpRequest request)
|
public static string GetAbsoluteRoot(this HttpRequest request)
|
||||||
{
|
{
|
||||||
return string.Concat(
|
return string.Concat(
|
||||||
|
@@ -6,7 +6,6 @@ namespace BTCPayServer.Abstractions.Extensions;
|
|||||||
|
|
||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
{
|
{
|
||||||
|
|
||||||
public static bool IsValidFileName(this string fileName)
|
public static bool IsValidFileName(this string fileName)
|
||||||
{
|
{
|
||||||
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
||||||
@@ -41,5 +40,4 @@ public static class StringExtensions
|
|||||||
return str.Substring(0, str.Length - 1);
|
return str.Substring(0, str.Length - 1);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
{
|
{
|
||||||
return IsActiveCategory(viewData, category.ToString(), id);
|
return IsActiveCategory(viewData, category.ToString(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY))
|
||||||
@@ -77,7 +77,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
? ActivePageClass
|
? ActivePageClass
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||||
{
|
{
|
||||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY))
|
||||||
@@ -126,7 +126,7 @@ namespace BTCPayServer.Abstractions.Extensions
|
|||||||
{
|
{
|
||||||
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
||||||
}
|
}
|
||||||
return timeSpan.Days < 1
|
return timeSpan.Days < 1
|
||||||
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
|
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
|
||||||
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||||
}
|
}
|
||||||
|
@@ -17,16 +17,16 @@ public class AlertMessage
|
|||||||
Danger,
|
Danger,
|
||||||
Info
|
Info
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public AlertMessageType Type;
|
public AlertMessageType Type;
|
||||||
|
|
||||||
// The translated message to be shown to the user
|
// The translated message to be shown to the user
|
||||||
public string Message;
|
public string Message;
|
||||||
|
|
||||||
public AlertMessage()
|
public AlertMessage()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlertMessage(AlertMessageType type, string message)
|
public AlertMessage(AlertMessageType type, string message)
|
||||||
|
@@ -12,12 +12,12 @@ public class Field
|
|||||||
{
|
{
|
||||||
public static Field Create(string label, string name, string value, bool required, string helpText, string type = "text")
|
public static Field Create(string label, string name, string value, bool required, string helpText, string type = "text")
|
||||||
{
|
{
|
||||||
return new Field()
|
return new Field
|
||||||
{
|
{
|
||||||
Label = label,
|
Label = label,
|
||||||
Name = name,
|
Name = name,
|
||||||
Value = value,
|
Value = value,
|
||||||
OriginalValue = value,
|
OriginalValue = value,
|
||||||
Required = required,
|
Required = required,
|
||||||
HelpText = helpText,
|
HelpText = helpText,
|
||||||
Type = type
|
Type = type
|
||||||
@@ -26,14 +26,14 @@ public class Field
|
|||||||
// The name of the HTML5 node. Should be used as the key for the posted data.
|
// The name of the HTML5 node. Should be used as the key for the posted data.
|
||||||
public string Name;
|
public string Name;
|
||||||
|
|
||||||
public bool Hidden;
|
public bool Constant;
|
||||||
|
|
||||||
// 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).
|
// HTML5 compatible type string like "text", "textarea", "email", "password", etc.
|
||||||
public string Type;
|
public string Type;
|
||||||
|
|
||||||
public static Field CreateFieldset()
|
public static Field CreateFieldset()
|
||||||
{
|
{
|
||||||
return new Field() { Type = "fieldset" };
|
return new Field { Type = "fieldset" };
|
||||||
}
|
}
|
||||||
|
|
||||||
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
|
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
|
||||||
@@ -55,7 +55,7 @@ public class Field
|
|||||||
public List<Field> Fields { get; set; } = new();
|
public List<Field> Fields { get; set; } = new();
|
||||||
|
|
||||||
// The field is considered "valid" if there are no validation errors
|
// The field is considered "valid" if there are no validation errors
|
||||||
public List<string> ValidationErrors = new List<string>();
|
public List<string> ValidationErrors = new();
|
||||||
|
|
||||||
public virtual bool IsValid()
|
public virtual bool IsValid()
|
||||||
{
|
{
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql.Internal.TypeHandlers.GeometricHandlers;
|
||||||
|
|
||||||
namespace BTCPayServer.Abstractions.Form;
|
namespace BTCPayServer.Abstractions.Form;
|
||||||
|
|
||||||
@@ -20,137 +22,120 @@ public class Form
|
|||||||
return JObject.FromObject(this, CamelCaseSerializerSettings.Serializer).ToString(Newtonsoft.Json.Formatting.Indented);
|
return JObject.FromObject(this, CamelCaseSerializerSettings.Serializer).ToString(Newtonsoft.Json.Formatting.Indented);
|
||||||
}
|
}
|
||||||
#nullable restore
|
#nullable restore
|
||||||
|
|
||||||
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
|
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
|
||||||
public List<AlertMessage> TopMessages { get; set; } = new();
|
public List<AlertMessage> TopMessages { get; set; } = new();
|
||||||
|
|
||||||
// Groups of fields in the form
|
// Groups of fields in the form
|
||||||
public List<Field> Fields { get; set; } = new();
|
public List<Field> Fields { get; set; } = new();
|
||||||
|
|
||||||
// Are all the fields valid in the form?
|
// Are all the fields valid in the form?
|
||||||
public bool IsValid()
|
public bool IsValid()
|
||||||
{
|
{
|
||||||
|
if (TopMessages?.Any(t => t.Type == AlertMessage.AlertMessageType.Danger) is true)
|
||||||
|
return false;
|
||||||
return Fields.Select(f => f.IsValid()).All(o => o);
|
return Fields.Select(f => f.IsValid()).All(o => o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field GetFieldByName(string name)
|
public Field GetFieldByFullName(string fullName)
|
||||||
{
|
{
|
||||||
return GetFieldByName(name, Fields, null);
|
foreach (var f in GetAllFields())
|
||||||
}
|
|
||||||
|
|
||||||
private static Field GetFieldByName(string name, List<Field> fields, string prefix)
|
|
||||||
{
|
|
||||||
prefix ??= string.Empty;
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
{
|
||||||
var currentPrefix = prefix;
|
if (f.FullName == fullName)
|
||||||
if (!string.IsNullOrEmpty(field.Name))
|
return f.Field;
|
||||||
{
|
|
||||||
|
|
||||||
currentPrefix = $"{prefix}{field.Name}";
|
|
||||||
if (currentPrefix.Equals(name, StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPrefix += "_";
|
|
||||||
}
|
|
||||||
|
|
||||||
var subFieldResult = GetFieldByName(name, field.Fields, currentPrefix);
|
|
||||||
if (subFieldResult is not null)
|
|
||||||
{
|
|
||||||
return subFieldResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> GetAllNames()
|
public IEnumerable<(string FullName, List<string> Path, Field Field)> GetAllFields()
|
||||||
{
|
{
|
||||||
return GetAllNames(Fields);
|
HashSet<string> nameReturned = new();
|
||||||
}
|
foreach (var f in GetAllFieldsCore(new List<string>(), Fields))
|
||||||
|
|
||||||
private static List<string> GetAllNames(List<Field> fields)
|
|
||||||
{
|
|
||||||
var names = new List<string>();
|
|
||||||
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
{
|
||||||
string prefix = string.Empty;
|
var fullName = string.Join('_', f.Path.Where(s => !string.IsNullOrEmpty(s)));
|
||||||
if (!string.IsNullOrEmpty(field.Name))
|
if (!nameReturned.Add(fullName))
|
||||||
{
|
continue;
|
||||||
names.Add(field.Name);
|
yield return (fullName, f.Path, f.Field);
|
||||||
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)
|
public bool ValidateFieldNames(out List<string> errors)
|
||||||
{
|
{
|
||||||
var names = GetAllNames();
|
errors = new List<string>();
|
||||||
foreach (var name in names)
|
HashSet<string> nameReturned = new();
|
||||||
|
foreach (var f in GetAllFieldsCore(new List<string>(), Fields))
|
||||||
{
|
{
|
||||||
var field = GetFieldByName(name);
|
var fullName = string.Join('_', f.Path.Where(s => !string.IsNullOrEmpty(s)));
|
||||||
if (field is null || !form.TryGetValue(name, out var val))
|
if (!nameReturned.Add(fullName))
|
||||||
{
|
{
|
||||||
|
errors.Add($"Form contains duplicate field names '{fullName}'");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
field.Value = val;
|
|
||||||
}
|
}
|
||||||
|
return errors.Count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, object> GetValues()
|
IEnumerable<(List<string> Path, Field Field)> GetAllFieldsCore(List<string> path, List<Field> fields)
|
||||||
{
|
{
|
||||||
return GetValues(Fields);
|
foreach (var field in 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;
|
List<string> thisPath = new(path.Count + 1);
|
||||||
if (field.Fields.Any())
|
thisPath.AddRange(path);
|
||||||
|
if (!string.IsNullOrEmpty(field.Name))
|
||||||
{
|
{
|
||||||
var values = GetValues(fields);
|
thisPath.Add(field.Name);
|
||||||
values.Remove(string.Empty, out var keylessValue);
|
yield return (thisPath, field);
|
||||||
|
}
|
||||||
result.TryAdd(name, values);
|
|
||||||
|
|
||||||
if (keylessValue is not Dictionary<string, object> dict) continue;
|
foreach (var child in field.Fields)
|
||||||
foreach (KeyValuePair<string,object> keyValuePair in dict)
|
{
|
||||||
|
if (field.Constant)
|
||||||
|
child.Constant = true;
|
||||||
|
foreach (var descendant in GetAllFieldsCore(thisPath, field.Fields))
|
||||||
{
|
{
|
||||||
result.TryAdd(keyValuePair.Key, keyValuePair.Value);
|
yield return descendant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyValuesFromForm(IEnumerable<KeyValuePair<string, StringValues>> form)
|
||||||
|
{
|
||||||
|
var values = form.GroupBy(f => f.Key, f => f.Value).ToDictionary(g => g.Key, g => g.First());
|
||||||
|
foreach (var f in GetAllFields())
|
||||||
|
{
|
||||||
|
if (f.Field.Constant || !values.TryGetValue(f.FullName, out var val))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
f.Field.Value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValues(JObject values)
|
||||||
|
{
|
||||||
|
var fields = GetAllFields().ToDictionary(k => k.FullName, k => k.Field);
|
||||||
|
SetValues(fields, new List<string>(), values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValues(Dictionary<string, Field> fields, List<string> path, JObject values)
|
||||||
|
{
|
||||||
|
foreach (var prop in values.Properties())
|
||||||
|
{
|
||||||
|
List<string> propPath = new List<string>(path.Count + 1);
|
||||||
|
propPath.AddRange(path);
|
||||||
|
propPath.Add(prop.Name);
|
||||||
|
if (prop.Value.Type == JTokenType.Object)
|
||||||
{
|
{
|
||||||
result.TryAdd(name, field.Value);
|
SetValues(fields, propPath, (JObject)prop.Value);
|
||||||
|
}
|
||||||
|
else if (prop.Value.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
var fullName = string.Join('_', propPath.Where(s => !string.IsNullOrEmpty(s)));
|
||||||
|
if (fields.TryGetValue(fullName, out var f) && !f.Constant)
|
||||||
|
f.Value = prop.Value.Value<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -8,18 +8,52 @@ namespace BTCPayServer.Abstractions.Models
|
|||||||
{
|
{
|
||||||
public abstract class BaseBTCPayServerPlugin : IBTCPayServerPlugin
|
public abstract class BaseBTCPayServerPlugin : IBTCPayServerPlugin
|
||||||
{
|
{
|
||||||
public abstract string Identifier { get; }
|
public virtual string Identifier
|
||||||
public abstract string Name { get; }
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetType().GetTypeInfo().Assembly.GetName().Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public virtual string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetType().GetTypeInfo().Assembly
|
||||||
|
.GetCustomAttribute<AssemblyProductAttribute>()?
|
||||||
|
.Product ?? "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Version Version
|
public virtual Version Version
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Assembly.GetAssembly(GetType())?.GetName().Version ?? new Version(1, 0, 0, 0);
|
return GetVersion(GetType().GetTypeInfo().Assembly
|
||||||
|
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
||||||
|
.InformationalVersion) ??
|
||||||
|
Assembly.GetAssembly(GetType())?.GetName()?.Version ??
|
||||||
|
new Version(1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract string Description { get; }
|
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 bool SystemPlugin { get; set; }
|
public bool SystemPlugin { get; set; }
|
||||||
public virtual IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = Array.Empty<IBTCPayServerPlugin.PluginDependency>();
|
public virtual IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = Array.Empty<IBTCPayServerPlugin.PluginDependency>();
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ public class AuthorizationFilterHandle
|
|||||||
public AuthorizationHandlerContext Context { get; }
|
public AuthorizationHandlerContext Context { get; }
|
||||||
public PolicyRequirement Requirement { get; }
|
public PolicyRequirement Requirement { get; }
|
||||||
public HttpContext HttpContext { get; }
|
public HttpContext HttpContext { get; }
|
||||||
public bool Success { get; private set; }
|
public bool Success { get; private set; }
|
||||||
|
|
||||||
public AuthorizationFilterHandle(
|
public AuthorizationFilterHandle(
|
||||||
AuthorizationHandlerContext context,
|
AuthorizationHandlerContext context,
|
||||||
|
@@ -114,6 +114,11 @@ namespace BTCPayServer.Security
|
|||||||
_Policies.Add(policy);
|
_Policies.Add(policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UnsafeEval()
|
||||||
|
{
|
||||||
|
Add("script-src", "'unsafe-eval'");
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<ConsentSecurityPolicy> Rules => _Policies;
|
public IEnumerable<ConsentSecurityPolicy> Rules => _Policies;
|
||||||
public bool HasRules => _Policies.Count != 0;
|
public bool HasRules => _Policies.Count != 0;
|
||||||
|
|
||||||
|
@@ -23,11 +23,20 @@ public class SVGUse : UrlResolutionTagHelper2
|
|||||||
{
|
{
|
||||||
_fileVersionProvider = fileVersionProvider;
|
_fileVersionProvider = fileVersionProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||||
{
|
{
|
||||||
var attr = output.Attributes["href"].Value.ToString();
|
var attr = output.Attributes["href"].Value.ToString();
|
||||||
attr = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, attr);
|
var symbolIndex = attr!.IndexOf("#", StringComparison.InvariantCulture);
|
||||||
|
var start = attr.IndexOf("~", StringComparison.InvariantCulture) + 1;
|
||||||
|
var length = (symbolIndex != -1 ? symbolIndex : attr.Length) - start;
|
||||||
|
var filePath = attr.Substring(start, length);
|
||||||
|
if (!string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
var versioned = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, filePath);
|
||||||
|
attr = attr.Replace(filePath, versioned);
|
||||||
|
}
|
||||||
output.Attributes.SetAttribute("href", attr);
|
output.Attributes.SetAttribute("href", attr);
|
||||||
base.Process(context, output);
|
base.Process(context, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,8 @@
|
|||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.19" />
|
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.21" />
|
||||||
<PackageReference Include="NBitcoin" Version="7.0.23" />
|
<PackageReference Include="NBitcoin" Version="7.0.24" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -22,6 +23,15 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<ApiKeyData>(response);
|
return await HandleResponse<ApiKeyData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (request == null)
|
||||||
|
throw new ArgumentNullException(nameof(request));
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys",
|
||||||
|
bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<ApiKeyData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete), token);
|
||||||
@@ -35,5 +45,14 @@ namespace BTCPayServer.Client
|
|||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
|
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (apikey == null)
|
||||||
|
throw new ArgumentNullException(nameof(apikey));
|
||||||
|
if (userId is null)
|
||||||
|
throw new ArgumentNullException(nameof(userId));
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete), token);
|
||||||
|
await HandleResponse(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Post), token);
|
method: HttpMethod.Post), token);
|
||||||
return await HandleResponse<PointOfSaleAppData>(response);
|
return await HandleResponse<PointOfSaleAppData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||||
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
CreateCrowdfundAppRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -52,6 +52,44 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<AppDataBase>(response);
|
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)
|
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (appId == null)
|
if (appId == null)
|
||||||
|
@@ -50,7 +50,7 @@ namespace BTCPayServer.Client
|
|||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<DepositAddressData> GetDepositAddress(string storeId, string accountId, string paymentMethod, CancellationToken token = default)
|
public virtual async Task<DepositAddressData> GetCustodianAccountDepositAddress(string storeId, string accountId, string paymentMethod, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/addresses/{paymentMethod}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/addresses/{paymentMethod}"), token);
|
||||||
return await HandleResponse<DepositAddressData>(response);
|
return await HandleResponse<DepositAddressData>(response);
|
||||||
@@ -58,7 +58,6 @@ namespace BTCPayServer.Client
|
|||||||
|
|
||||||
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
|
public virtual async Task<MarketTradeResponseData> MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
|
||||||
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
//var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/users", null, request, HttpMethod.Post), token);
|
||||||
//return await HandleResponse<ApplicationUserData>(response);
|
//return await HandleResponse<ApplicationUserData>(response);
|
||||||
var internalRequest = CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", null,
|
var internalRequest = CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", null,
|
||||||
@@ -67,13 +66,13 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<MarketTradeResponseData>(response);
|
return await HandleResponse<MarketTradeResponseData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<MarketTradeResponseData> GetTradeInfo(string storeId, string accountId, string tradeId, CancellationToken token = default)
|
public virtual async Task<MarketTradeResponseData> GetCustodianAccountTradeInfo(string storeId, string accountId, string tradeId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/{tradeId}", method: HttpMethod.Get), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/{tradeId}", method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<MarketTradeResponseData>(response);
|
return await HandleResponse<MarketTradeResponseData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<TradeQuoteResponseData> GetTradeQuote(string storeId, string accountId, string fromAsset, string toAsset, CancellationToken token = default)
|
public virtual async Task<TradeQuoteResponseData> GetCustodianAccountTradeQuote(string storeId, string accountId, string fromAsset, string toAsset, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var queryPayload = new Dictionary<string, object>();
|
var queryPayload = new Dictionary<string, object>();
|
||||||
queryPayload.Add("fromAsset", fromAsset);
|
queryPayload.Add("fromAsset", fromAsset);
|
||||||
@@ -81,14 +80,20 @@ namespace BTCPayServer.Client
|
|||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
|
||||||
return await HandleResponse<TradeQuoteResponseData>(response);
|
return await HandleResponse<TradeQuoteResponseData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<WithdrawalResponseData> CreateWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
public virtual async Task<WithdrawalResponseData> CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals", bodyPayload: request, method: HttpMethod.Post), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
return await HandleResponse<WithdrawalResponseData>(response);
|
return await HandleResponse<WithdrawalResponseData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<WithdrawalResponseData> GetWithdrawalInfo(string storeId, string accountId, string paymentMethod, string withdrawalId, CancellationToken token = default)
|
public virtual async Task<WithdrawalSimulationResponseData> SimulateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/simulation", bodyPayload: request, method: HttpMethod.Post), token);
|
||||||
|
return await HandleResponse<WithdrawalSimulationResponseData>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<WithdrawalResponseData> GetCustodianAccountWithdrawalInfo(string storeId, string accountId, string paymentMethod, string withdrawalId, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/{paymentMethod}/{withdrawalId}", method: HttpMethod.Get), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/{paymentMethod}/{withdrawalId}", method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<WithdrawalResponseData>(response);
|
return await HandleResponse<WithdrawalResponseData>(response);
|
||||||
|
@@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningNodeInformationData>(response);
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -95,7 +95,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningInvoiceData>(response);
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -114,6 +114,24 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
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,
|
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
@@ -17,7 +17,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningNodeInformationData>(response);
|
return await HandleResponse<LightningNodeInformationData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Get), token);
|
method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<LightningInvoiceData>(response);
|
return await HandleResponse<LightningInvoiceData>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@@ -116,6 +116,24 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<LightningInvoiceData[]>(response);
|
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,
|
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
48
BTCPayServer.Client/BTCPayServerClient.LightningAddresses.cs
Normal file
48
BTCPayServer.Client/BTCPayServerClient.LightningAddresses.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
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);
|
parameters.Add("includeNeighbourData", v);
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method:HttpMethod.Get), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", parameters, method: HttpMethod.Get), token);
|
||||||
return await HandleResponse<OnChainWalletObjectData[]>(response);
|
return await HandleResponse<OnChainWalletObjectData[]>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||||
@@ -47,7 +47,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method:HttpMethod.Delete), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}", method: HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||||
@@ -55,7 +55,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method:HttpMethod.Post, bodyPayload: request), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects", method: HttpMethod.Post, bodyPayload: request), token);
|
||||||
return await HandleResponse<OnChainWalletObjectData>(response);
|
return await HandleResponse<OnChainWalletObjectData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||||
@@ -65,7 +65,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method:HttpMethod.Post, bodyPayload: request), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links", method: HttpMethod.Post, bodyPayload: request), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||||
@@ -75,7 +75,7 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response =
|
var response =
|
||||||
await _httpClient.SendAsync(
|
await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method:HttpMethod.Delete), token);
|
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", method: HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -63,7 +63,8 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
query.Add(nameof(statusFilter), statusFilter);
|
query.Add(nameof(statusFilter), statusFilter);
|
||||||
}
|
}
|
||||||
if (labelFilter != null) {
|
if (labelFilter != null)
|
||||||
|
{
|
||||||
query.Add(nameof(labelFilter), labelFilter);
|
query.Add(nameof(labelFilter), labelFilter);
|
||||||
}
|
}
|
||||||
var response =
|
var response =
|
||||||
|
@@ -52,17 +52,17 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts/{payoutId}", method: HttpMethod.Get), cancellationToken);
|
||||||
return await HandleResponse<PayoutData>(response);
|
return await HandleResponse<PayoutData>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
|
||||||
@@ -97,5 +97,15 @@ namespace BTCPayServer.Client
|
|||||||
method: HttpMethod.Post, bodyPayload: request), cancellationToken);
|
method: HttpMethod.Post, bodyPayload: request), cancellationToken);
|
||||||
await HandleResponse(response);
|
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 partial class BTCPayServerClient
|
||||||
{
|
{
|
||||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
|
||||||
@@ -20,28 +20,28 @@ namespace BTCPayServer.Client
|
|||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod,LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}",null, request, HttpMethod.Put ), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
|
||||||
}
|
}
|
||||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod,OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}",null, request, HttpMethod.Put ), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", null, request, HttpMethod.Put), token);
|
||||||
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}"), token);
|
||||||
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,17 +37,28 @@ namespace BTCPayServer.Client
|
|||||||
return await HandleResponse<StoreRateConfiguration>(response);
|
return await HandleResponse<StoreRateConfiguration>(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<StoreRatePreviewResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId,
|
||||||
StoreRateConfiguration request,
|
StoreRateConfiguration request,
|
||||||
string[] currencyPair,
|
string[] currencyPair,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
using var response = await _httpClient.SendAsync(
|
using var response = await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
|
CreateHttpRequest($"api/v1/stores/{storeId}/rates/configuration/preview", bodyPayload: request,
|
||||||
queryPayload: new Dictionary<string, object>() {{"currencyPair", currencyPair}},
|
queryPayload: new Dictionary<string, object>() { { "currencyPair", currencyPair } },
|
||||||
method: HttpMethod.Post),
|
method: HttpMethod.Post),
|
||||||
token);
|
token);
|
||||||
return await HandleResponse<List<StoreRatePreviewResult>>(response);
|
return await HandleResponse<List<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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,12 +36,12 @@ namespace BTCPayServer.Client
|
|||||||
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
public virtual async Task<bool> LockUser(string idOrEmail, bool locked, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
|
||||||
new LockUserRequest {Locked = locked}, HttpMethod.Post), token);
|
new LockUserRequest { Locked = locked }, HttpMethod.Post), token);
|
||||||
await HandleResponse(response);
|
await HandleResponse(response);
|
||||||
return response.IsSuccessStatusCode;
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<ApplicationUserData[]> GetUsers( CancellationToken token = default)
|
public virtual async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/", null, HttpMethod.Get), token);
|
||||||
return await HandleResponse<ApplicationUserData[]>(response);
|
return await HandleResponse<ApplicationUserData[]>(response);
|
||||||
|
@@ -30,9 +30,9 @@ namespace BTCPayServer.JsonConverters
|
|||||||
case JTokenType.Integer:
|
case JTokenType.Integer:
|
||||||
case JTokenType.String:
|
case JTokenType.String:
|
||||||
if (objectType == typeof(decimal) || objectType == typeof(decimal?))
|
if (objectType == typeof(decimal) || objectType == typeof(decimal?))
|
||||||
return decimal.Parse(token.ToString(), CultureInfo.InvariantCulture);
|
return decimal.Parse(token.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||||
if (objectType == typeof(double) || objectType == typeof(double?))
|
if (objectType == typeof(double) || objectType == typeof(double?))
|
||||||
return double.Parse(token.ToString(), CultureInfo.InvariantCulture);
|
return double.Parse(token.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||||
throw new JsonSerializationException("Unexpected object type: " + objectType);
|
throw new JsonSerializationException("Unexpected object type: " + objectType);
|
||||||
case JTokenType.Null when objectType == typeof(decimal?) || objectType == typeof(double?):
|
case JTokenType.Null when objectType == typeof(decimal?) || objectType == typeof(double?):
|
||||||
return null;
|
return null;
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.Lightning;
|
||||||
|
using NBitcoin.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.JsonConverters
|
||||||
|
{
|
||||||
|
public class TradeQuantityJsonConverter : JsonConverter<TradeQuantity>
|
||||||
|
{
|
||||||
|
public override TradeQuantity ReadJson(JsonReader reader, Type objectType, TradeQuantity existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
JToken token = JToken.Load(reader);
|
||||||
|
switch (token.Type)
|
||||||
|
{
|
||||||
|
case JTokenType.Float:
|
||||||
|
case JTokenType.Integer:
|
||||||
|
case JTokenType.String:
|
||||||
|
if (TradeQuantity.TryParse(token.ToString(), out var q))
|
||||||
|
return q;
|
||||||
|
break;
|
||||||
|
case JTokenType.Null:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new JsonObjectException("Invalid TradeQuantity, expected string. Expected: \"1.50\" or \"50%\"", reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, TradeQuantity value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value is not null)
|
||||||
|
writer.WriteValue(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -8,7 +8,7 @@ public class AssetPairData
|
|||||||
public AssetPairData()
|
public AssetPairData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
|
public AssetPairData(string assetBought, string assetSold, decimal minimumTradeQty)
|
||||||
{
|
{
|
||||||
AssetBought = assetBought;
|
AssetBought = assetBought;
|
||||||
@@ -25,7 +25,7 @@ public class AssetPairData
|
|||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public decimal MinimumTradeQty { set; get; }
|
public decimal MinimumTradeQty { set; get; }
|
||||||
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return AssetBought + "/" + AssetSold;
|
return AssetBought + "/" + AssetSold;
|
||||||
|
@@ -11,14 +11,14 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
|
public CreateLightningInvoiceRequest(LightMoney amount, string description, TimeSpan expiry)
|
||||||
{
|
{
|
||||||
Amount = amount;
|
Amount = amount;
|
||||||
Description = description;
|
Description = description;
|
||||||
Expiry = expiry;
|
Expiry = expiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.LightMoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.LightMoneyJsonConverter))]
|
||||||
public LightMoney Amount { get; set; }
|
public LightMoney Amount { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
@@ -5,11 +5,11 @@ namespace BTCPayServer.Client.Models
|
|||||||
public abstract class CustodianAccountBaseData
|
public abstract class CustodianAccountBaseData
|
||||||
{
|
{
|
||||||
public string CustodianCode { get; set; }
|
public string CustodianCode { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
public string StoreId { get; set; }
|
public string StoreId { get; set; }
|
||||||
|
|
||||||
public JObject Config { get; set; }
|
public JObject Config { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,13 +2,13 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class CustodianAccountResponse: CustodianAccountData
|
public class CustodianAccountResponse : CustodianAccountData
|
||||||
{
|
{
|
||||||
public IDictionary<string, decimal> AssetBalances { get; set; }
|
public IDictionary<string, decimal> AssetBalances { get; set; }
|
||||||
|
|
||||||
public CustodianAccountResponse()
|
public CustodianAccountResponse()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -9,5 +9,5 @@ public class CustodianData
|
|||||||
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
|
public Dictionary<string, AssetPairData> TradableAssetPairs { get; set; }
|
||||||
public string[] WithdrawablePaymentMethods { get; set; }
|
public string[] WithdrawablePaymentMethods { get; set; }
|
||||||
public string[] DepositablePaymentMethods { get; set; }
|
public string[] DepositablePaymentMethods { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,10 +6,10 @@ public class DepositAddressData
|
|||||||
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
|
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
|
||||||
// */
|
// */
|
||||||
// public string Type { get; set; }
|
// public string Type { get; set; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format depends hugely on the type.
|
* Format depends hugely on the type.
|
||||||
*/
|
*/
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -86,6 +86,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
public bool? RequiresRefundEmail { get; set; } = null;
|
public bool? RequiresRefundEmail { get; set; } = null;
|
||||||
public string DefaultLanguage { get; set; }
|
public string DefaultLanguage { get; set; }
|
||||||
public CheckoutType? CheckoutType { get; set; }
|
public CheckoutType? CheckoutType { get; set; }
|
||||||
|
public bool? LazyPaymentMethods { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class InvoiceData : InvoiceDataBase
|
public class InvoiceData : InvoiceDataBase
|
||||||
|
@@ -3,7 +3,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
public class LNURLPayPaymentMethodBaseData
|
public class LNURLPayPaymentMethodBaseData
|
||||||
{
|
{
|
||||||
public bool UseBech32Scheme { get; set; }
|
public bool UseBech32Scheme { get; set; }
|
||||||
public bool EnableForStandardInvoices { get; set; }
|
|
||||||
public bool LUD12Enabled { get; set; }
|
public bool LUD12Enabled { get; set; }
|
||||||
|
|
||||||
public LNURLPayPaymentMethodBaseData()
|
public LNURLPayPaymentMethodBaseData()
|
||||||
|
@@ -16,12 +16,11 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public LNURLPayPaymentMethodData(string cryptoCode, bool enabled, bool useBech32Scheme, bool enableForStandardInvoices)
|
public LNURLPayPaymentMethodData(string cryptoCode, bool enabled, bool useBech32Scheme)
|
||||||
{
|
{
|
||||||
Enabled = enabled;
|
Enabled = enabled;
|
||||||
CryptoCode = cryptoCode;
|
CryptoCode = cryptoCode;
|
||||||
UseBech32Scheme = useBech32Scheme;
|
UseBech32Scheme = useBech32Scheme;
|
||||||
EnableForStandardInvoices = enableForStandardInvoices;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using BTCPayServer.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ namespace BTCPayServer.Client.Models;
|
|||||||
public class LedgerEntryData
|
public class LedgerEntryData
|
||||||
{
|
{
|
||||||
public string Asset { get; }
|
public string Asset { get; }
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal Qty { get; }
|
public decimal Qty { get; }
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
10
BTCPayServer.Client/Models/LightningAddressData.cs
Normal file
10
BTCPayServer.Client/Models/LightningAddressData.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
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 BTCPayServer.Client.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models;
|
|||||||
public class LightningAutomatedPayoutSettings
|
public class LightningAutomatedPayoutSettings
|
||||||
{
|
{
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
public TimeSpan IntervalSeconds { get; set; }
|
public TimeSpan IntervalSeconds { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -17,8 +17,14 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonProperty("BOLT11")]
|
[JsonProperty("BOLT11")]
|
||||||
public string BOLT11 { get; set; }
|
public string BOLT11 { get; set; }
|
||||||
|
|
||||||
|
public string PaymentHash { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string Preimage { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset? PaidAt { get; set; }
|
public DateTimeOffset? PaidAt { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset ExpiresAt { get; set; }
|
public DateTimeOffset ExpiresAt { get; set; }
|
||||||
|
|
||||||
|
@@ -4,7 +4,6 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
|
|
||||||
public string ConnectionString { get; set; }
|
public string ConnectionString { get; set; }
|
||||||
public bool DisableBOLT11PaymentOption { get; set; }
|
|
||||||
public LightningNetworkPaymentMethodBaseData()
|
public LightningNetworkPaymentMethodBaseData()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -16,13 +16,12 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public LightningNetworkPaymentMethodData(string cryptoCode, string connectionString, bool enabled, string paymentMethod, bool disableBOLT11PaymentOption)
|
public LightningNetworkPaymentMethodData(string cryptoCode, string connectionString, bool enabled, string paymentMethod)
|
||||||
{
|
{
|
||||||
Enabled = enabled;
|
Enabled = enabled;
|
||||||
CryptoCode = cryptoCode;
|
CryptoCode = cryptoCode;
|
||||||
ConnectionString = connectionString;
|
ConnectionString = connectionString;
|
||||||
PaymentMethod = paymentMethod;
|
PaymentMethod = paymentMethod;
|
||||||
DisableBOLT11PaymentOption = disableBOLT11PaymentOption;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
|
@@ -9,10 +9,10 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonProperty("onchain")]
|
[JsonProperty("onchain")]
|
||||||
public OnchainBalanceData OnchainBalance { get; set; }
|
public OnchainBalanceData OnchainBalance { get; set; }
|
||||||
|
|
||||||
[JsonProperty("offchain")]
|
[JsonProperty("offchain")]
|
||||||
public OffchainBalanceData OffchainBalance { get; set; }
|
public OffchainBalanceData OffchainBalance { get; set; }
|
||||||
|
|
||||||
public LightningNodeBalanceData()
|
public LightningNodeBalanceData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||||
public Money Unconfirmed { get; set; }
|
public Money Unconfirmed { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
|
||||||
public Money Reserved { get; set; }
|
public Money Reserved { get; set; }
|
||||||
}
|
}
|
||||||
@@ -40,13 +40,13 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Opening { get; set; }
|
public LightMoney Opening { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Local { get; set; }
|
public LightMoney Local { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Remote { get; set; }
|
public LightMoney Remote { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Closing { get; set; }
|
public LightMoney Closing { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -17,12 +17,12 @@ namespace BTCPayServer.Client.Models
|
|||||||
|
|
||||||
[JsonProperty("BOLT11")]
|
[JsonProperty("BOLT11")]
|
||||||
public string BOLT11 { get; set; }
|
public string BOLT11 { get; set; }
|
||||||
|
|
||||||
public string Preimage { get; set; }
|
public string Preimage { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset? CreatedAt { get; set; }
|
public DateTimeOffset? CreatedAt { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney TotalAmount { get; set; }
|
public LightMoney TotalAmount { get; set; }
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
namespace BTCPayServer.Client;
|
namespace BTCPayServer.Client;
|
||||||
|
|
||||||
public class LockUserRequest
|
public class LockUserRequest
|
||||||
{
|
{
|
||||||
|
@@ -16,7 +16,7 @@ public class MarketTradeResponseData
|
|||||||
public string TradeId { get; }
|
public string TradeId { get; }
|
||||||
|
|
||||||
public string AccountId { get; }
|
public string AccountId { get; }
|
||||||
|
|
||||||
public string CustodianCode { get; }
|
public string CustodianCode { get; }
|
||||||
|
|
||||||
public MarketTradeResponseData(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId, string accountId, string custodianCode)
|
public MarketTradeResponseData(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId, string accountId, string custodianCode)
|
||||||
|
@@ -6,6 +6,8 @@ namespace BTCPayServer.Client.Models
|
|||||||
public class NotificationData
|
public class NotificationData
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
public string Body { get; set; }
|
public string Body { get; set; }
|
||||||
public bool Seen { get; set; }
|
public bool Seen { get; set; }
|
||||||
public Uri Link { get; set; }
|
public Uri Link { get; set; }
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using BTCPayServer.Client.JsonConverters;
|
using BTCPayServer.Client.JsonConverters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@@ -7,9 +7,9 @@ namespace BTCPayServer.Client.Models;
|
|||||||
public class OnChainAutomatedPayoutSettings
|
public class OnChainAutomatedPayoutSettings
|
||||||
{
|
{
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
public TimeSpan IntervalSeconds { get; set; }
|
public TimeSpan IntervalSeconds { get; set; }
|
||||||
|
|
||||||
public int? FeeBlockTarget { get; set; }
|
public int? FeeBlockTarget { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -11,13 +11,13 @@ namespace BTCPayServer.Client.Models
|
|||||||
{
|
{
|
||||||
[JsonProperty("BOLT11")]
|
[JsonProperty("BOLT11")]
|
||||||
public string BOLT11 { get; set; }
|
public string BOLT11 { get; set; }
|
||||||
|
|
||||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||||
public float? MaxFeePercent { get; set; }
|
public float? MaxFeePercent { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||||
public Money MaxFeeFlat { get; set; }
|
public Money MaxFeeFlat { get; set; }
|
||||||
|
|
||||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
public LightMoney Amount { get; set; }
|
public LightMoney Amount { get; set; }
|
||||||
|
|
||||||
|
13
BTCPayServer.Client/Models/PaymentMethodCriteriaData.cs
Normal file
13
BTCPayServer.Client/Models/PaymentMethodCriteriaData.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
public class PaymentMethodCriteriaData
|
||||||
|
{
|
||||||
|
public string PaymentMethod { get; set; }
|
||||||
|
public string CurrencyCode { get; set; }
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
|
public decimal Amount { get; set; }
|
||||||
|
public bool Above { get; set; }
|
||||||
|
}
|
@@ -12,14 +12,56 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PointOfSaleAppData : AppDataBase
|
public class PointOfSaleAppData : AppDataBase
|
||||||
{
|
{
|
||||||
// We can add POS specific things here later
|
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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CrowdfundAppData : AppDataBase
|
public class CrowdfundAppData : AppDataBase
|
||||||
{
|
{
|
||||||
// We can add Crowdfund specific things here later
|
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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
BTCPayServer.Client/Models/PullPaymentLNURL.cs
Normal file
8
BTCPayServer.Client/Models/PullPaymentLNURL.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
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 class RateSource
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,10 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public TimeSpan InvoiceExpiration { get; set; } = TimeSpan.FromMinutes(15);
|
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))]
|
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
|
||||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public TimeSpan MonitoringExpiration { get; set; } = TimeSpan.FromMinutes(60);
|
public TimeSpan MonitoringExpiration { get; set; } = TimeSpan.FromMinutes(60);
|
||||||
@@ -59,8 +63,11 @@ namespace BTCPayServer.Client.Models
|
|||||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
|
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
|
||||||
|
|
||||||
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public List<PaymentMethodCriteriaData> PaymentMethodCriteria { get; set; }
|
||||||
|
|
||||||
public bool PayJoinEnabled { get; set; }
|
public bool PayJoinEnabled { get; set; }
|
||||||
|
|
||||||
public InvoiceData.ReceiptOptions Receipt { get; set; }
|
public InvoiceData.ReceiptOptions Receipt { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ namespace BTCPayServer.Client.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StoreUserData
|
public class StoreUserData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
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,7 +1,13 @@
|
|||||||
namespace BTCPayServer.Client.Models;
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class StoreRateResult
|
public class StoreRateResult
|
||||||
{
|
{
|
||||||
public string CurrencyPair { get; set; }
|
public string CurrencyPair { get; set; }
|
||||||
public decimal Rate { get; set; }
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
}
|
public decimal? Rate { get; set; }
|
||||||
|
public List<string> Errors { get; set; }
|
||||||
|
}
|
||||||
|
@@ -1,8 +1,13 @@
|
|||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class TradeQuoteResponseData
|
public class TradeQuoteResponseData
|
||||||
{
|
{
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal Bid { get; }
|
public decimal Bid { get; }
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal Ask { get; }
|
public decimal Ask { get; }
|
||||||
public string ToAsset { get; }
|
public string ToAsset { get; }
|
||||||
public string FromAsset { get; }
|
public string FromAsset { get; }
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class TradeRequestData
|
public class TradeRequestData
|
||||||
{
|
{
|
||||||
public string FromAsset { set; get; }
|
public string FromAsset { set; get; }
|
||||||
public string ToAsset { set; get; }
|
public string ToAsset { set; get; }
|
||||||
public string Qty { set; get; }
|
[JsonConverter(typeof(JsonConverters.TradeQuantityJsonConverter))]
|
||||||
|
public TradeQuantity Qty { set; get; }
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class WithdrawRequestData
|
public class WithdrawRequestData
|
||||||
{
|
{
|
||||||
public string PaymentMethod { set; get; }
|
public string PaymentMethod { set; get; }
|
||||||
public decimal Qty { set; get; }
|
[JsonConverter(typeof(JsonConverters.TradeQuantityJsonConverter))]
|
||||||
|
public TradeQuantity Qty { set; get; }
|
||||||
|
|
||||||
public WithdrawRequestData(string paymentMethod, decimal qty)
|
public WithdrawRequestData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public WithdrawRequestData(string paymentMethod, TradeQuantity qty)
|
||||||
{
|
{
|
||||||
PaymentMethod = paymentMethod;
|
PaymentMethod = paymentMethod;
|
||||||
Qty = qty;
|
Qty = qty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
public record TradeQuantity
|
||||||
|
{
|
||||||
|
public TradeQuantity(decimal value, ValueType type)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ValueType
|
||||||
|
{
|
||||||
|
Exact,
|
||||||
|
Percent
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueType Type { get; }
|
||||||
|
public decimal Value { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (Type == ValueType.Exact)
|
||||||
|
return Value.ToString(CultureInfo.InvariantCulture);
|
||||||
|
else
|
||||||
|
return Value.ToString(CultureInfo.InvariantCulture) + "%";
|
||||||
|
}
|
||||||
|
public static TradeQuantity Parse(string str)
|
||||||
|
{
|
||||||
|
if (!TryParse(str, out var r))
|
||||||
|
throw new FormatException("Invalid TradeQuantity");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
public static bool TryParse(string str, [MaybeNullWhen(false)] out TradeQuantity quantity)
|
||||||
|
{
|
||||||
|
if (str is null)
|
||||||
|
throw new ArgumentNullException(nameof(str));
|
||||||
|
quantity = null;
|
||||||
|
str = str.Trim();
|
||||||
|
str = str.Replace(" ", "");
|
||||||
|
if (str.Length == 0)
|
||||||
|
return false;
|
||||||
|
if (str[^1] == '%')
|
||||||
|
{
|
||||||
|
if (!decimal.TryParse(str[..^1], NumberStyles.Any, CultureInfo.InvariantCulture, out var r))
|
||||||
|
return false;
|
||||||
|
if (r < 0.0m)
|
||||||
|
return false;
|
||||||
|
quantity = new TradeQuantity(r, TradeQuantity.ValueType.Percent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out var r))
|
||||||
|
return false;
|
||||||
|
if (r < 0.0m)
|
||||||
|
return false;
|
||||||
|
quantity = new TradeQuantity(r, TradeQuantity.ValueType.Exact);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
22
BTCPayServer.Client/Models/WithdrawalBaseResponseData.cs
Normal file
22
BTCPayServer.Client/Models/WithdrawalBaseResponseData.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
public abstract class WithdrawalBaseResponseData
|
||||||
|
{
|
||||||
|
public string Asset { get; }
|
||||||
|
public string PaymentMethod { get; }
|
||||||
|
public List<LedgerEntryData> LedgerEntries { get; }
|
||||||
|
public string AccountId { get; }
|
||||||
|
public string CustodianCode { get; }
|
||||||
|
|
||||||
|
public WithdrawalBaseResponseData(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string accountId,
|
||||||
|
string custodianCode)
|
||||||
|
{
|
||||||
|
PaymentMethod = paymentMethod;
|
||||||
|
Asset = asset;
|
||||||
|
LedgerEntries = ledgerEntries;
|
||||||
|
AccountId = accountId;
|
||||||
|
CustodianCode = custodianCode;
|
||||||
|
}
|
||||||
|
}
|
@@ -5,18 +5,13 @@ using Newtonsoft.Json.Converters;
|
|||||||
|
|
||||||
namespace BTCPayServer.Client.Models;
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
public class WithdrawalResponseData
|
public class WithdrawalResponseData : WithdrawalBaseResponseData
|
||||||
{
|
{
|
||||||
public string Asset { get; }
|
|
||||||
public string PaymentMethod { get; }
|
|
||||||
public List<LedgerEntryData> LedgerEntries { get; }
|
|
||||||
public string WithdrawalId { get; }
|
|
||||||
public string AccountId { get; }
|
|
||||||
public string CustodianCode { get; }
|
|
||||||
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public WithdrawalStatus Status { get; }
|
public WithdrawalStatus Status { get; }
|
||||||
|
|
||||||
|
public string WithdrawalId { get; }
|
||||||
public DateTimeOffset CreatedTime { get; }
|
public DateTimeOffset CreatedTime { get; }
|
||||||
|
|
||||||
public string TransactionId { get; }
|
public string TransactionId { get; }
|
||||||
@@ -24,14 +19,10 @@ public class WithdrawalResponseData
|
|||||||
public string TargetAddress { get; }
|
public string TargetAddress { get; }
|
||||||
|
|
||||||
public WithdrawalResponseData(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string withdrawalId, string accountId,
|
public WithdrawalResponseData(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string withdrawalId, string accountId,
|
||||||
string custodianCode, WithdrawalStatus status, DateTimeOffset createdTime, string targetAddress, string transactionId)
|
string custodianCode, WithdrawalStatus status, DateTimeOffset createdTime, string targetAddress, string transactionId) : base(paymentMethod, asset, ledgerEntries, accountId,
|
||||||
|
custodianCode)
|
||||||
{
|
{
|
||||||
PaymentMethod = paymentMethod;
|
|
||||||
Asset = asset;
|
|
||||||
LedgerEntries = ledgerEntries;
|
|
||||||
WithdrawalId = withdrawalId;
|
WithdrawalId = withdrawalId;
|
||||||
AccountId = accountId;
|
|
||||||
CustodianCode = custodianCode;
|
|
||||||
TargetAddress = targetAddress;
|
TargetAddress = targetAddress;
|
||||||
TransactionId = transactionId;
|
TransactionId = transactionId;
|
||||||
Status = status;
|
Status = status;
|
||||||
|
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using BTCPayServer.JsonConverters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Client.Models;
|
||||||
|
|
||||||
|
public class WithdrawalSimulationResponseData : WithdrawalBaseResponseData
|
||||||
|
{
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
|
public decimal? MinQty { get; set; }
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
|
public decimal? MaxQty { get; set; }
|
||||||
|
|
||||||
|
public WithdrawalSimulationResponseData(string paymentMethod, string asset, string accountId,
|
||||||
|
string custodianCode, List<LedgerEntryData> ledgerEntries, decimal? minQty, decimal? maxQty) : base(paymentMethod,
|
||||||
|
asset, ledgerEntries, accountId, custodianCode)
|
||||||
|
{
|
||||||
|
MinQty = minQty;
|
||||||
|
MaxQty = maxQty;
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,9 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
public class Policies
|
public class Policies
|
||||||
{
|
{
|
||||||
|
public const string CanViewLightningInvoiceInternalNode = "btcpay.server.canviewlightninginvoiceinternalnode";
|
||||||
public const string CanCreateLightningInvoiceInternalNode = "btcpay.server.cancreatelightninginvoiceinternalnode";
|
public const string CanCreateLightningInvoiceInternalNode = "btcpay.server.cancreatelightninginvoiceinternalnode";
|
||||||
|
public const string CanViewLightningInvoiceInStore = "btcpay.store.canviewlightninginvoice";
|
||||||
public const string CanCreateLightningInvoiceInStore = "btcpay.store.cancreatelightninginvoice";
|
public const string CanCreateLightningInvoiceInStore = "btcpay.store.cancreatelightninginvoice";
|
||||||
public const string CanUseInternalLightningNode = "btcpay.server.canuseinternallightningnode";
|
public const string CanUseInternalLightningNode = "btcpay.server.canuseinternallightningnode";
|
||||||
public const string CanUseLightningNodeInStore = "btcpay.store.canuselightningnode";
|
public const string CanUseLightningNodeInStore = "btcpay.store.canuselightningnode";
|
||||||
@@ -26,8 +28,11 @@ namespace BTCPayServer.Client
|
|||||||
public const string CanViewNotificationsForUser = "btcpay.user.canviewnotificationsforuser";
|
public const string CanViewNotificationsForUser = "btcpay.user.canviewnotificationsforuser";
|
||||||
public const string CanViewUsers = "btcpay.server.canviewusers";
|
public const string CanViewUsers = "btcpay.server.canviewusers";
|
||||||
public const string CanCreateUser = "btcpay.server.cancreateuser";
|
public const string CanCreateUser = "btcpay.server.cancreateuser";
|
||||||
|
public const string CanManageUsers = "btcpay.server.canmanageusers";
|
||||||
public const string CanDeleteUser = "btcpay.user.candeleteuser";
|
public const string CanDeleteUser = "btcpay.user.candeleteuser";
|
||||||
public const string CanManagePullPayments = "btcpay.store.canmanagepullpayments";
|
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 CanViewCustodianAccounts = "btcpay.store.canviewcustodianaccounts";
|
||||||
public const string CanManageCustodianAccounts = "btcpay.store.canmanagecustodianaccounts";
|
public const string CanManageCustodianAccounts = "btcpay.store.canmanagecustodianaccounts";
|
||||||
public const string CanDepositToCustodianAccounts = "btcpay.store.candeposittocustodianaccount";
|
public const string CanDepositToCustodianAccounts = "btcpay.store.candeposittocustodianaccount";
|
||||||
@@ -56,15 +61,20 @@ namespace BTCPayServer.Client
|
|||||||
yield return CanViewNotificationsForUser;
|
yield return CanViewNotificationsForUser;
|
||||||
yield return Unrestricted;
|
yield return Unrestricted;
|
||||||
yield return CanUseInternalLightningNode;
|
yield return CanUseInternalLightningNode;
|
||||||
|
yield return CanViewLightningInvoiceInternalNode;
|
||||||
yield return CanCreateLightningInvoiceInternalNode;
|
yield return CanCreateLightningInvoiceInternalNode;
|
||||||
yield return CanUseLightningNodeInStore;
|
yield return CanUseLightningNodeInStore;
|
||||||
|
yield return CanViewLightningInvoiceInStore;
|
||||||
yield return CanCreateLightningInvoiceInStore;
|
yield return CanCreateLightningInvoiceInStore;
|
||||||
yield return CanManagePullPayments;
|
yield return CanManagePullPayments;
|
||||||
|
yield return CanCreatePullPayments;
|
||||||
|
yield return CanCreateNonApprovedPullPayments;
|
||||||
yield return CanViewCustodianAccounts;
|
yield return CanViewCustodianAccounts;
|
||||||
yield return CanManageCustodianAccounts;
|
yield return CanManageCustodianAccounts;
|
||||||
yield return CanDepositToCustodianAccounts;
|
yield return CanDepositToCustodianAccounts;
|
||||||
yield return CanWithdrawFromCustodianAccounts;
|
yield return CanWithdrawFromCustodianAccounts;
|
||||||
yield return CanTradeCustodianAccount;
|
yield return CanTradeCustodianAccount;
|
||||||
|
yield return CanManageUsers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static bool IsValidPolicy(string policy)
|
public static bool IsValidPolicy(string policy)
|
||||||
@@ -88,9 +98,45 @@ namespace BTCPayServer.Client
|
|||||||
{
|
{
|
||||||
return policy.StartsWith("btcpay.plugin", StringComparison.OrdinalIgnoreCase);
|
return policy.StartsWith("btcpay.plugin", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
public static bool IsUserPolicy(string policy)
|
||||||
|
{
|
||||||
|
return policy.StartsWith("btcpay.user", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PermissionSet
|
||||||
|
{
|
||||||
|
public PermissionSet() : this(Array.Empty<Permission>())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public PermissionSet(Permission[] permissions)
|
||||||
|
{
|
||||||
|
Permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Permission[] Permissions { get; }
|
||||||
|
|
||||||
|
public bool Contains(Permission requestedPermission)
|
||||||
|
{
|
||||||
|
return Permissions.Any(p => p.Contains(requestedPermission));
|
||||||
|
}
|
||||||
|
public bool Contains(string permission, string store)
|
||||||
|
{
|
||||||
|
if (permission is null)
|
||||||
|
throw new ArgumentNullException(nameof(permission));
|
||||||
|
if (store is null)
|
||||||
|
throw new ArgumentNullException(nameof(store));
|
||||||
|
return Contains(Permission.Create(permission, store));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public class Permission
|
public class Permission
|
||||||
{
|
{
|
||||||
|
static Permission()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
public static Permission Create(string policy, string scope = null)
|
public static Permission Create(string policy, string scope = null)
|
||||||
{
|
{
|
||||||
if (TryCreatePermission(policy, scope, out var r))
|
if (TryCreatePermission(policy, scope, out var r))
|
||||||
@@ -106,7 +152,7 @@ namespace BTCPayServer.Client
|
|||||||
policy = policy.Trim().ToLowerInvariant();
|
policy = policy.Trim().ToLowerInvariant();
|
||||||
if (!Policies.IsValidPolicy(policy))
|
if (!Policies.IsValidPolicy(policy))
|
||||||
return false;
|
return false;
|
||||||
if (scope != null && !Policies.IsStorePolicy(policy))
|
if (!string.IsNullOrEmpty(scope) && !Policies.IsStorePolicy(policy))
|
||||||
return false;
|
return false;
|
||||||
permission = new Permission(policy, scope);
|
permission = new Permission(policy, scope);
|
||||||
return true;
|
return true;
|
||||||
@@ -159,7 +205,7 @@ namespace BTCPayServer.Client
|
|||||||
}
|
}
|
||||||
if (!Policies.IsStorePolicy(subpermission.Policy))
|
if (!Policies.IsStorePolicy(subpermission.Policy))
|
||||||
return true;
|
return true;
|
||||||
return Scope == null || subpermission.Scope == this.Scope;
|
return Scope == null || subpermission.Scope == Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Permission> ToPermissions(string[] permissions)
|
public static IEnumerable<Permission> ToPermissions(string[] permissions)
|
||||||
@@ -175,35 +221,61 @@ namespace BTCPayServer.Client
|
|||||||
|
|
||||||
private bool ContainsPolicy(string subpolicy)
|
private bool ContainsPolicy(string subpolicy)
|
||||||
{
|
{
|
||||||
if (this.Policy == Policies.Unrestricted)
|
return ContainsPolicy(Policy, subpolicy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ContainsPolicy(string policy, string subpolicy)
|
||||||
|
{
|
||||||
|
if (policy == Policies.Unrestricted)
|
||||||
return true;
|
return true;
|
||||||
if (this.Policy == subpolicy)
|
if (policy == subpolicy)
|
||||||
return true;
|
return true;
|
||||||
switch (subpolicy)
|
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,
|
||||||
|
Policies.CanUseLightningNodeInStore);
|
||||||
|
|
||||||
|
PolicyHasChild(Policies.CanManageUsers, Policies.CanCreateUser);
|
||||||
|
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,
|
||||||
|
Policies.CanManageUsers);
|
||||||
|
PolicyHasChild(Policies.CanUseInternalLightningNode, Policies.CanCreateLightningInvoiceInternalNode, Policies.CanViewLightningInvoiceInternalNode);
|
||||||
|
PolicyHasChild(Policies.CanManageCustodianAccounts, Policies.CanViewCustodianAccounts);
|
||||||
|
PolicyHasChild(Policies.CanModifyInvoices, Policies.CanViewInvoices, Policies.CanCreateInvoice, Policies.CanCreateLightningInvoiceInStore);
|
||||||
|
PolicyHasChild(Policies.CanViewStoreSettings, Policies.CanViewInvoices, Policies.CanViewPaymentRequests);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PolicyHasChild(string policy, params string[] subPolicies)
|
||||||
|
{
|
||||||
|
if (PolicyMap.TryGetValue(policy, out var existingSubPolicies))
|
||||||
{
|
{
|
||||||
case Policies.CanViewInvoices when this.Policy == Policies.CanModifyStoreSettings:
|
foreach (string subPolicy in subPolicies)
|
||||||
case Policies.CanViewInvoices when this.Policy == Policies.CanModifyInvoices:
|
{
|
||||||
case Policies.CanModifyStoreWebhooks when this.Policy == Policies.CanModifyStoreSettings:
|
existingSubPolicies.Add(subPolicy);
|
||||||
case Policies.CanViewInvoices when this.Policy == Policies.CanViewStoreSettings:
|
}
|
||||||
case Policies.CanViewStoreSettings when this.Policy == Policies.CanModifyStoreSettings:
|
}
|
||||||
case Policies.CanCreateInvoice when this.Policy == Policies.CanModifyStoreSettings:
|
else
|
||||||
case Policies.CanModifyInvoices when this.Policy == Policies.CanModifyStoreSettings:
|
{
|
||||||
case Policies.CanViewProfile when this.Policy == Policies.CanModifyProfile:
|
PolicyMap.Add(policy, subPolicies.ToHashSet());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,23 +284,17 @@ namespace BTCPayServer.Client
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (Scope != null)
|
return Scope != null ? $"{Policy}:{Scope}" : Policy;
|
||||||
{
|
|
||||||
return $"{Policy}:{Scope}";
|
|
||||||
}
|
|
||||||
return Policy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
Permission item = obj as Permission;
|
Permission item = obj as Permission;
|
||||||
if (item == null)
|
return item != null && ToString().Equals(item.ToString());
|
||||||
return false;
|
|
||||||
return ToString().Equals(item.ToString());
|
|
||||||
}
|
}
|
||||||
public static bool operator ==(Permission a, Permission b)
|
public static bool operator ==(Permission a, Permission b)
|
||||||
{
|
{
|
||||||
if (System.Object.ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return true;
|
return true;
|
||||||
if (((object)a == null) || ((object)b == null))
|
if (((object)a == null) || ((object)b == null))
|
||||||
return false;
|
return false;
|
||||||
|
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
<PackageReference Include="NBXplorer.Client" Version="4.2.2" />
|
<PackageReference Include="NBXplorer.Client" Version="4.2.3" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="2.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(Altcoins)' != 'true'">
|
<ItemGroup Condition="'$(Altcoins)' != 'true'">
|
||||||
<Compile Remove="Altcoins\**\*.cs"></Compile>
|
<Compile Remove="Altcoins\**\*.cs"></Compile>
|
||||||
|
@@ -23,7 +23,7 @@ namespace BTCPayServer
|
|||||||
internal Task ProcessTask;
|
internal Task ProcessTask;
|
||||||
public async Task Process(CancellationToken cancellationToken)
|
public async Task Process(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
while (Chan.Reader.TryRead(out var item))
|
while (Chan.Reader.TryRead(out var item))
|
||||||
{
|
{
|
||||||
await item(cancellationToken);
|
await item(cancellationToken);
|
||||||
@@ -52,7 +52,7 @@ namespace BTCPayServer
|
|||||||
{
|
{
|
||||||
lock (_Queues)
|
lock (_Queues)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
if (stopped)
|
if (stopped)
|
||||||
return;
|
return;
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using BTCPayServer.Data.Data;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
@@ -30,7 +30,12 @@ namespace BTCPayServer.Data
|
|||||||
{
|
{
|
||||||
_designTime = designTime;
|
_designTime = designTime;
|
||||||
}
|
}
|
||||||
|
#nullable enable
|
||||||
|
public async Task<string?> GetMigrationState()
|
||||||
|
{
|
||||||
|
return (await Settings.FromSqlRaw("SELECT \"Id\", \"Value\" FROM \"Settings\" WHERE \"Id\"='MigrationData'").AsNoTracking().FirstOrDefaultAsync())?.Value;
|
||||||
|
}
|
||||||
|
#nullable restore
|
||||||
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
|
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
|
||||||
public DbSet<APIKeyData> ApiKeys { get; set; }
|
public DbSet<APIKeyData> ApiKeys { get; set; }
|
||||||
public DbSet<AppData> Apps { get; set; }
|
public DbSet<AppData> Apps { get; set; }
|
||||||
@@ -67,8 +72,9 @@ namespace BTCPayServer.Data
|
|||||||
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
|
||||||
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
|
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
|
||||||
public DbSet<WebhookData> Webhooks { get; set; }
|
public DbSet<WebhookData> Webhooks { get; set; }
|
||||||
public DbSet<LightningAddressData> LightningAddresses{ get; set; }
|
public DbSet<LightningAddressData> LightningAddresses { get; set; }
|
||||||
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
|
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
|
||||||
|
public DbSet<FormData> Forms { get; set; }
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
@@ -83,23 +89,23 @@ namespace BTCPayServer.Data
|
|||||||
|
|
||||||
// some of the data models don't have OnModelCreating for now, commenting them
|
// some of the data models don't have OnModelCreating for now, commenting them
|
||||||
|
|
||||||
ApplicationUser.OnModelCreating(builder);
|
ApplicationUser.OnModelCreating(builder, Database);
|
||||||
AddressInvoiceData.OnModelCreating(builder);
|
AddressInvoiceData.OnModelCreating(builder);
|
||||||
APIKeyData.OnModelCreating(builder);
|
APIKeyData.OnModelCreating(builder, Database);
|
||||||
AppData.OnModelCreating(builder);
|
AppData.OnModelCreating(builder);
|
||||||
CustodianAccountData.OnModelCreating(builder);
|
CustodianAccountData.OnModelCreating(builder, Database);
|
||||||
//StoredFile.OnModelCreating(builder);
|
//StoredFile.OnModelCreating(builder);
|
||||||
InvoiceEventData.OnModelCreating(builder);
|
InvoiceEventData.OnModelCreating(builder);
|
||||||
InvoiceSearchData.OnModelCreating(builder);
|
InvoiceSearchData.OnModelCreating(builder);
|
||||||
InvoiceWebhookDeliveryData.OnModelCreating(builder);
|
InvoiceWebhookDeliveryData.OnModelCreating(builder);
|
||||||
InvoiceData.OnModelCreating(builder);
|
InvoiceData.OnModelCreating(builder, Database);
|
||||||
NotificationData.OnModelCreating(builder);
|
NotificationData.OnModelCreating(builder, Database);
|
||||||
//OffchainTransactionData.OnModelCreating(builder);
|
//OffchainTransactionData.OnModelCreating(builder);
|
||||||
BTCPayServer.Data.PairedSINData.OnModelCreating(builder);
|
BTCPayServer.Data.PairedSINData.OnModelCreating(builder);
|
||||||
PairingCodeData.OnModelCreating(builder);
|
PairingCodeData.OnModelCreating(builder);
|
||||||
//PayjoinLock.OnModelCreating(builder);
|
//PayjoinLock.OnModelCreating(builder);
|
||||||
PaymentRequestData.OnModelCreating(builder);
|
PaymentRequestData.OnModelCreating(builder, Database);
|
||||||
PaymentData.OnModelCreating(builder);
|
PaymentData.OnModelCreating(builder, Database);
|
||||||
PayoutData.OnModelCreating(builder);
|
PayoutData.OnModelCreating(builder);
|
||||||
PendingInvoiceData.OnModelCreating(builder);
|
PendingInvoiceData.OnModelCreating(builder);
|
||||||
//PlannedTransaction.OnModelCreating(builder);
|
//PlannedTransaction.OnModelCreating(builder);
|
||||||
@@ -110,7 +116,7 @@ namespace BTCPayServer.Data
|
|||||||
StoreWebhookData.OnModelCreating(builder);
|
StoreWebhookData.OnModelCreating(builder);
|
||||||
StoreData.OnModelCreating(builder, Database);
|
StoreData.OnModelCreating(builder, Database);
|
||||||
U2FDevice.OnModelCreating(builder);
|
U2FDevice.OnModelCreating(builder);
|
||||||
Fido2Credential.OnModelCreating(builder);
|
Fido2Credential.OnModelCreating(builder, Database);
|
||||||
BTCPayServer.Data.UserStore.OnModelCreating(builder);
|
BTCPayServer.Data.UserStore.OnModelCreating(builder);
|
||||||
//WalletData.OnModelCreating(builder);
|
//WalletData.OnModelCreating(builder);
|
||||||
WalletObjectData.OnModelCreating(builder, Database);
|
WalletObjectData.OnModelCreating(builder, Database);
|
||||||
@@ -118,10 +124,11 @@ namespace BTCPayServer.Data
|
|||||||
#pragma warning disable CS0612 // Type or member is obsolete
|
#pragma warning disable CS0612 // Type or member is obsolete
|
||||||
WalletTransactionData.OnModelCreating(builder);
|
WalletTransactionData.OnModelCreating(builder);
|
||||||
#pragma warning restore CS0612 // Type or member is obsolete
|
#pragma warning restore CS0612 // Type or member is obsolete
|
||||||
WebhookDeliveryData.OnModelCreating(builder);
|
WebhookDeliveryData.OnModelCreating(builder, Database);
|
||||||
LightningAddressData.OnModelCreating(builder);
|
LightningAddressData.OnModelCreating(builder, Database);
|
||||||
PayoutProcessorData.OnModelCreating(builder);
|
PayoutProcessorData.OnModelCreating(builder, Database);
|
||||||
//WebhookData.OnModelCreating(builder);
|
WebhookData.OnModelCreating(builder, Database);
|
||||||
|
FormData.OnModelCreating(builder, Database);
|
||||||
|
|
||||||
|
|
||||||
if (Database.IsSqlite() && !_designTime)
|
if (Database.IsSqlite() && !_designTime)
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class APIKeyData
|
public class APIKeyData : IHasBlob<APIKeyBlob>
|
||||||
{
|
{
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
@@ -16,13 +18,15 @@ namespace BTCPayServer.Data
|
|||||||
|
|
||||||
public APIKeyType Type { get; set; } = APIKeyType.Legacy;
|
public APIKeyType Type { get; set; } = APIKeyType.Legacy;
|
||||||
|
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
public StoreData StoreData { get; set; }
|
public StoreData StoreData { get; set; }
|
||||||
public ApplicationUser User { get; set; }
|
public ApplicationUser User { get; set; }
|
||||||
public string Label { get; set; }
|
public string Label { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<APIKeyData>()
|
builder.Entity<APIKeyData>()
|
||||||
.HasOne(o => o.StoreData)
|
.HasOne(o => o.StoreData)
|
||||||
@@ -36,6 +40,13 @@ namespace BTCPayServer.Data
|
|||||||
|
|
||||||
builder.Entity<APIKeyData>()
|
builder.Entity<APIKeyData>()
|
||||||
.HasIndex(o => o.StoreId);
|
.HasIndex(o => o.StoreId);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<APIKeyData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,11 +2,13 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
// Add profile data for application users by adding properties to the ApplicationUser class
|
// Add profile data for application users by adding properties to the ApplicationUser class
|
||||||
public class ApplicationUser : IdentityUser
|
public class ApplicationUser : IdentityUser, IHasBlob<UserBlob>
|
||||||
{
|
{
|
||||||
public bool RequiresEmailConfirmation { get; set; }
|
public bool RequiresEmailConfirmation { get; set; }
|
||||||
public List<StoredFile> StoredFiles { get; set; }
|
public List<StoredFile> StoredFiles { get; set; }
|
||||||
@@ -20,15 +22,28 @@ namespace BTCPayServer.Data
|
|||||||
public List<UserStore> UserStores { get; set; }
|
public List<UserStore> UserStores { get; set; }
|
||||||
public List<Fido2Credential> Fido2Credentials { get; set; }
|
public List<Fido2Credential> Fido2Credentials { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
public List<IdentityUserRole<string>> UserRoles { get; set; }
|
public List<IdentityUserRole<string>> UserRoles { get; set; }
|
||||||
|
|
||||||
public static void OnModelCreating(ModelBuilder builder)
|
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<ApplicationUser>()
|
builder.Entity<ApplicationUser>()
|
||||||
.HasMany<IdentityUserRole<string>>(user => user.UserRoles)
|
.HasMany<IdentityUserRole<string>>(user => user.UserRoles)
|
||||||
.WithOne().HasForeignKey(role => role.UserId);
|
.WithOne().HasForeignKey(role => role.UserId);
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<ApplicationUser>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UserBlob
|
||||||
|
{
|
||||||
|
public bool ShowInvoiceStatusChangeHint { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Data;
|
namespace BTCPayServer.Data;
|
||||||
|
|
||||||
public class CustodianAccountData
|
public class CustodianAccountData : IHasBlob<JObject>
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
@@ -14,29 +16,39 @@ public class CustodianAccountData
|
|||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string StoreId { get; set; }
|
public string StoreId { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string CustodianCode { get; set; }
|
public string CustodianCode { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public StoreData StoreData { get; set; }
|
public StoreData StoreData { get; set; }
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<CustodianAccountData>()
|
builder.Entity<CustodianAccountData>()
|
||||||
.HasOne(o => o.StoreData)
|
.HasOne(o => o.StoreData)
|
||||||
.WithMany(i => i.CustodianAccounts)
|
.WithMany(i => i.CustodianAccounts)
|
||||||
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
builder.Entity<APIKeyData>()
|
builder.Entity<CustodianAccountData>()
|
||||||
.HasIndex(o => o.StoreId);
|
.HasIndex(o => o.StoreId);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<CustodianAccountData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,10 +2,11 @@ using System;
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class Fido2Credential
|
public class Fido2Credential : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
@@ -14,6 +15,7 @@ namespace BTCPayServer.Data
|
|||||||
public string ApplicationUserId { get; set; }
|
public string ApplicationUserId { get; set; }
|
||||||
|
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
public CredentialType Type { get; set; }
|
public CredentialType Type { get; set; }
|
||||||
public enum CredentialType
|
public enum CredentialType
|
||||||
{
|
{
|
||||||
@@ -22,12 +24,18 @@ namespace BTCPayServer.Data
|
|||||||
[Display(Name = "Lightning node (LNURL Auth)")]
|
[Display(Name = "Lightning node (LNURL Auth)")]
|
||||||
LNURLAuth
|
LNURLAuth
|
||||||
}
|
}
|
||||||
public static void OnModelCreating(ModelBuilder builder)
|
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<Fido2Credential>()
|
builder.Entity<Fido2Credential>()
|
||||||
.HasOne(o => o.ApplicationUser)
|
.HasOne(o => o.ApplicationUser)
|
||||||
.WithMany(i => i.Fido2Credentials)
|
.WithMany(i => i.Fido2Credentials)
|
||||||
.HasForeignKey(i => i.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
.HasForeignKey(i => i.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<Fido2Credential>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationUser ApplicationUser { get; set; }
|
public ApplicationUser ApplicationUser { get; set; }
|
||||||
|
@@ -2,11 +2,30 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data.Data;
|
namespace BTCPayServer.Data;
|
||||||
|
|
||||||
public class FormData
|
public class FormData
|
||||||
{
|
{
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string StoreId { get; set; }
|
||||||
|
public StoreData Store { get; set; }
|
||||||
public string Config { get; set; }
|
public string Config { get; set; }
|
||||||
|
public bool Public { get; set; }
|
||||||
|
|
||||||
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
|
{
|
||||||
|
builder.Entity<FormData>()
|
||||||
|
.HasOne(o => o.Store)
|
||||||
|
.WithMany(o => o.Forms).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
builder.Entity<FormData>().HasIndex(o => o.StoreId);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<FormData>()
|
||||||
|
.Property(o => o.Config)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
28
BTCPayServer.Data/Data/IHasBlob.cs
Normal file
28
BTCPayServer.Data/Data/IHasBlob.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Data
|
||||||
|
{
|
||||||
|
public interface IHasBlob<T>
|
||||||
|
{
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
|
byte[] Blob { get; set; }
|
||||||
|
string Blob2 { get; set; }
|
||||||
|
}
|
||||||
|
public interface IHasBlob
|
||||||
|
{
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
|
byte[] Blob { get; set; }
|
||||||
|
string Blob2 { get; set; }
|
||||||
|
public Type Type { get; set; }
|
||||||
|
}
|
||||||
|
public interface IHasBlobUntyped
|
||||||
|
{
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
|
byte[] Blob { get; set; }
|
||||||
|
string Blob2 { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -2,10 +2,11 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class InvoiceData
|
public class InvoiceData : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
@@ -16,7 +17,9 @@ namespace BTCPayServer.Data
|
|||||||
public List<PaymentData> Payments { get; set; }
|
public List<PaymentData> Payments { get; set; }
|
||||||
public List<InvoiceEventData> Events { get; set; }
|
public List<InvoiceEventData> Events { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
public string ItemCode { get; set; }
|
public string ItemCode { get; set; }
|
||||||
public string OrderId { get; set; }
|
public string OrderId { get; set; }
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
@@ -32,7 +35,7 @@ namespace BTCPayServer.Data
|
|||||||
public RefundData CurrentRefund { get; set; }
|
public RefundData CurrentRefund { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<InvoiceData>()
|
builder.Entity<InvoiceData>()
|
||||||
.HasOne(o => o.StoreData)
|
.HasOne(o => o.StoreData)
|
||||||
@@ -42,6 +45,13 @@ namespace BTCPayServer.Data
|
|||||||
builder.Entity<InvoiceData>()
|
builder.Entity<InvoiceData>()
|
||||||
.HasOne(o => o.CurrentRefund);
|
.HasOne(o => o.CurrentRefund);
|
||||||
builder.Entity<InvoiceData>().HasIndex(o => o.Created);
|
builder.Entity<InvoiceData>().HasIndex(o => o.Created);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<InvoiceData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,22 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Data;
|
namespace BTCPayServer.Data;
|
||||||
|
|
||||||
public class LightningAddressData
|
public class LightningAddressData : IHasBlob<LightningAddressDataBlob>
|
||||||
{
|
{
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string StoreDataId { get; set; }
|
public string StoreDataId { get; set; }
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
public StoreData Store { get; set; }
|
public StoreData Store { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<LightningAddressData>()
|
builder.Entity<LightningAddressData>()
|
||||||
.HasOne(o => o.Store)
|
.HasOne(o => o.Store)
|
||||||
@@ -20,6 +25,12 @@ public class LightningAddressData
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
builder.Entity<LightningAddressData>().HasKey(o => o.Username);
|
builder.Entity<LightningAddressData>().HasKey(o => o.Username);
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<LightningAddressData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,4 +39,6 @@ public class LightningAddressDataBlob
|
|||||||
public string CurrencyCode { get; set; }
|
public string CurrencyCode { get; set; }
|
||||||
public decimal? Min { get; set; }
|
public decimal? Min { get; set; }
|
||||||
public decimal? Max { get; set; }
|
public decimal? Max { get; set; }
|
||||||
|
|
||||||
|
public JObject InvoiceMetadata { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class NotificationData
|
public class NotificationData : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
[MaxLength(36)]
|
[MaxLength(36)]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
@@ -17,15 +19,23 @@ namespace BTCPayServer.Data
|
|||||||
[Required]
|
[Required]
|
||||||
public string NotificationType { get; set; }
|
public string NotificationType { get; set; }
|
||||||
public bool Seen { get; set; }
|
public bool Seen { get; set; }
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<NotificationData>()
|
builder.Entity<NotificationData>()
|
||||||
.HasOne(o => o.ApplicationUser)
|
.HasOne(o => o.ApplicationUser)
|
||||||
.WithMany(n => n.Notifications)
|
.WithMany(n => n.Notifications)
|
||||||
.HasForeignKey(k => k.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
.HasForeignKey(k => k.ApplicationUserId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<NotificationData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +1,34 @@
|
|||||||
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class PaymentData
|
public class PaymentData : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string InvoiceDataId { get; set; }
|
public string InvoiceDataId { get; set; }
|
||||||
public InvoiceData InvoiceData { get; set; }
|
public InvoiceData InvoiceData { get; set; }
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
public bool Accounted { get; set; }
|
public bool Accounted { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<PaymentData>()
|
builder.Entity<PaymentData>()
|
||||||
.HasOne(o => o.InvoiceData)
|
.HasOne(o => o.InvoiceData)
|
||||||
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
|
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
|
||||||
builder.Entity<PaymentData>()
|
builder.Entity<PaymentData>()
|
||||||
.HasIndex(o => o.InvoiceDataId);
|
.HasIndex(o => o.InvoiceDataId);
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<PaymentData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
public class PaymentRequestData
|
public class PaymentRequestData : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
@@ -14,10 +15,12 @@ namespace BTCPayServer.Data
|
|||||||
|
|
||||||
public Client.Models.PaymentRequestData.PaymentRequestStatus Status { get; set; }
|
public Client.Models.PaymentRequestData.PaymentRequestStatus Status { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
public byte[] Blob { get; set; }
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
builder.Entity<PaymentRequestData>()
|
builder.Entity<PaymentRequestData>()
|
||||||
.HasOne(o => o.StoreData)
|
.HasOne(o => o.StoreData)
|
||||||
@@ -28,6 +31,13 @@ namespace BTCPayServer.Data
|
|||||||
.HasDefaultValue(new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
.HasDefaultValue(new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
||||||
builder.Entity<PaymentRequestData>()
|
builder.Entity<PaymentRequestData>()
|
||||||
.HasIndex(o => o.Status);
|
.HasIndex(o => o.Status);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<PaymentRequestData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,15 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace BTCPayServer.Data.Data;
|
namespace BTCPayServer.Data;
|
||||||
|
|
||||||
public class PayoutProcessorData
|
public class AutomatedPayoutBlob
|
||||||
|
{
|
||||||
|
public TimeSpan Interval { get; set; } = TimeSpan.FromHours(1);
|
||||||
|
}
|
||||||
|
public class PayoutProcessorData : IHasBlobUntyped
|
||||||
{
|
{
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
@@ -11,15 +17,23 @@ public class PayoutProcessorData
|
|||||||
public StoreData Store { get; set; }
|
public StoreData Store { get; set; }
|
||||||
public string PaymentMethod { get; set; }
|
public string PaymentMethod { get; set; }
|
||||||
public string Processor { get; set; }
|
public string Processor { get; set; }
|
||||||
|
|
||||||
public byte[] Blob { get; set; }
|
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
[Obsolete("Use Blob2 instead")]
|
||||||
|
public byte[] Blob { get; set; }
|
||||||
|
public string Blob2 { get; set; }
|
||||||
|
|
||||||
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
|
{
|
||||||
builder.Entity<PayoutProcessorData>()
|
builder.Entity<PayoutProcessorData>()
|
||||||
.HasOne(o => o.Store)
|
.HasOne(o => o.Store)
|
||||||
.WithMany(data => data.PayoutProcessors).OnDelete(DeleteBehavior.Cascade);
|
.WithMany(data => data.PayoutProcessors).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
if (databaseFacade.IsNpgsql())
|
||||||
|
{
|
||||||
|
builder.Entity<PayoutProcessorData>()
|
||||||
|
.Property(o => o.Blob2)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Text;
|
||||||
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.Data.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using PayoutProcessorData = BTCPayServer.Data.Data.PayoutProcessorData;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PayoutProcessorData = BTCPayServer.Data.PayoutProcessorData;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
@@ -25,7 +27,6 @@ namespace BTCPayServer.Data
|
|||||||
[Obsolete("Use GetDerivationStrategies instead")]
|
[Obsolete("Use GetDerivationStrategies instead")]
|
||||||
public string DerivationStrategy { get; set; }
|
public string DerivationStrategy { get; set; }
|
||||||
|
|
||||||
[Obsolete("Use GetDerivationStrategies instead")]
|
|
||||||
public string DerivationStrategies { get; set; }
|
public string DerivationStrategies { get; set; }
|
||||||
|
|
||||||
public string StoreName { get; set; }
|
public string StoreName { get; set; }
|
||||||
@@ -50,6 +51,7 @@ namespace BTCPayServer.Data
|
|||||||
public IEnumerable<PayoutData> Payouts { get; set; }
|
public IEnumerable<PayoutData> Payouts { get; set; }
|
||||||
public IEnumerable<CustodianAccountData> CustodianAccounts { get; set; }
|
public IEnumerable<CustodianAccountData> CustodianAccounts { get; set; }
|
||||||
public IEnumerable<StoreSettingData> Settings { get; set; }
|
public IEnumerable<StoreSettingData> Settings { get; set; }
|
||||||
|
public IEnumerable<FormData> Forms { get; set; }
|
||||||
|
|
||||||
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
internal static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
|
||||||
{
|
{
|
||||||
@@ -58,6 +60,20 @@ namespace BTCPayServer.Data
|
|||||||
builder.Entity<StoreData>()
|
builder.Entity<StoreData>()
|
||||||
.Property(o => o.StoreBlob)
|
.Property(o => o.StoreBlob)
|
||||||
.HasColumnType("JSONB");
|
.HasColumnType("JSONB");
|
||||||
|
|
||||||
|
builder.Entity<StoreData>()
|
||||||
|
.Property(o => o.DerivationStrategies)
|
||||||
|
.HasColumnType("JSONB");
|
||||||
|
}
|
||||||
|
else if (databaseFacade.IsMySql())
|
||||||
|
{
|
||||||
|
builder.Entity<StoreData>()
|
||||||
|
.Property(o => o.StoreBlob)
|
||||||
|
.HasConversion(new ValueConverter<string, byte[]>
|
||||||
|
(
|
||||||
|
convertToProviderExpression: (str) => Encoding.UTF8.GetBytes(str),
|
||||||
|
convertFromProviderExpression: (bytes) => Encoding.UTF8.GetString(bytes)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user