Compare commits

..

1 Commits

Author SHA1 Message Date
597116bb26 Allow Users to be disabled/enabled 2022-04-14 19:16:55 +02:00
556 changed files with 5483 additions and 18746 deletions

View File

@ -4,15 +4,6 @@ set -e
cd ../BTCPayServer.Tests
docker-compose -v
docker-compose -f "docker-compose.altcoins.yml" down --v
# For some reason, docker-compose pull fails time to time, so we try several times
n=0
until [ "$n" -ge 10 ]
do
docker-compose -f "docker-compose.altcoins.yml" pull && break
n=$((n+1))
sleep 5
done
docker-compose -f "docker-compose.altcoins.yml" pull
docker-compose -f "docker-compose.altcoins.yml" build
docker-compose -f "docker-compose.altcoins.yml" run -e "TEST_FILTERS=$1" tests

63
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@ -0,0 +1,63 @@
---
name: "\U0001F41B Bug report"
about: Report a bug or a technical issue
---
<!--
Thank you for reporting a technical issue.
This issue tracker is only for bug reports and problems.
For general questions please read our documentation docs.btcpayserver.org. You can ask technical questions in discussions https://github.com/btcpayserver/btcpayserver/discussions and general support on our community chat chat.btcpayserver.org
Please fill in as much of the template below as you're able.
-->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce the bug**
Steps to reproduce the reported bug:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
<!--
A clear and concise description of what you expected to happen.
-->
**Screenshots**
<!--
If applicable, add screenshots to help explain your problem.
-->
**Your BTCPay Environment (please complete the following information):**
- BTCPay Server Version: <!--[available in the right bottom corner of footer] -->
- Deployment Method: <!--[e.g. Docker, Manual, Third-Party-host]-->
- Browser: <!--[e.g. Chrome, Safari]-->
**Logs (if applicable)**
<!--
Basic logs can be found in Server Settings > Logs.
More logs https://docs.btcpayserver.org/Troubleshooting/#2-looking-through-the-logs
-->
**Setup Parameters**
<!--
If you're reporting a deployment issue run `. btcpay-setup.sh -i` and paste the setup parameters here with your private information removed or obscured.
-->
**Additional context**
<!--
Add any other context about the problem here.
-->

View File

@ -1,68 +0,0 @@
name: 🐛 Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! Please provide as much information as you can. It helps us better understand the problem and fix it faster.
- type: textarea
id: version
attributes:
label: What is your BTCPay version?
description: You can see the version in the footer's bottom right corner
placeholder: I'm running BTCPay v1.X.X.X
validations:
required: true
- type: textarea
id: deployment
attributes:
label: How did you deploy BTCPay Server?
description: Docker, manual, third-party host? Read more on deployment methods [here](https://docs.btcpayserver.org/Deployment/)
placeholder: I'm running BTCPay Server on a...
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: A clear and concise description of what the bug is.
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: How did you encounter this bug?
description: Step by step describe how did you encounter the bug?
placeholder: 1. I clicked X 2. Then I clicked Y 3. See error
validations:
required: true
- type: textarea
id: logoutput
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Logs can be found in Server Settings > Logs. Here's how you can [troubleshoot an issue](https://docs.btcpayserver.org/Troubleshooting/)
render: shell
- type: textarea
id: browser
attributes:
label: What browser do you use?
description: Provide your browser and it's version. If you replicated issues on multiple browsers, let us know which ones.
placeholder: For example Safari 15.00, Chrome 10.0, Tor, Edge, etc
validations:
required: false
- type: textarea
id: additonal
attributes:
label: Additional information
description: Feel free to provide additional information. Screenshots are always helpful.
- type: checkboxes
id: terms
attributes:
label: Are you sure this is a bug report?
description: By submitting this report, you agree that this is not a support or a feature request. For general questions please read our [documentation](https://docs.btcpayserver.org). You can ask questions in [discussions](https://github.com/btcpayserver/btcpayserver/discussions) and [on our community chat](https://chat.btcpayserver.org)
options:
- label: I confirm this is a bug report
required: true

View File

@ -1,11 +1,11 @@
blank_issues_enabled: true
contact_links:
- name: 🚀 Discussions
blank_issues_enabled: false
contact_links:
- name: 🚀 Discussions
url: https://github.com/btcpayserver/btcpayserver/discussions
about: Technical discussions, questions and feature requests
about: Technical discussions, questions and feature requests
- name: 📝 Official Documentation
url: https://docs.btcpayserver.org
about: Check our documentation for answers to common questions
- name: 💬 Community Support Chat
about: Check our documentation for answers to common questions
- name: 💬 Community Support Chat
url: https://chat.btcpayserver.org/
about: Ask general questions and get community support in real-time

View File

@ -31,10 +31,9 @@
<None Include="icon.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.1" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +0,0 @@
#nullable enable
namespace BTCPayServer.Abstractions.Contracts;
public interface IScopeProvider
{
string? GetCurrentStoreId();
}

View File

@ -1,10 +0,0 @@
#nullable enable
using System.Threading.Tasks;
namespace BTCPayServer.Abstractions.Contracts;
public interface IStoreRepository
{
Task<T?> GetSettingAsync<T>(string storeId, string name) where T : class;
Task UpdateSetting<T>(string storeId, string name, T obj) where T : class;
}

View File

@ -1,18 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class AssetQuoteResult
{
public string FromAsset { get; }
public string ToAsset { get; }
public decimal Bid { get; }
public decimal Ask { get; }
public AssetQuoteResult(string fromAsset, string toAsset,decimal bid, decimal ask)
{
this.FromAsset = fromAsset;
this.ToAsset = toAsset;
this.Bid = bid;
this.Ask = ask;
}
}

View File

@ -1,11 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class AssetBalancesUnavailableException : CustodianApiException
{
public AssetBalancesUnavailableException(System.Exception e) : base(500, "asset-balances-unavailable", $"Cannot fetch the asset balances: {e.Message}", e)
{
}
}

View File

@ -1,13 +0,0 @@
using BTCPayServer.Client.Models;
namespace BTCPayServer.Abstractions.Custodians;
public class AssetQuoteUnavailableException : CustodianApiException
{
public AssetPairData AssetPair { get; }
public AssetQuoteUnavailableException(AssetPairData assetPair) : base(400, "asset-price-unavailable", "Cannot find a quote for pair " + assetPair)
{
this.AssetPair = assetPair;
}
}

View File

@ -1,13 +0,0 @@
using System;
namespace BTCPayServer.Abstractions.Custodians;
public class BadConfigException : CustodianApiException
{
public string[] BadConfigKeys { get; set; }
public BadConfigException(string[] badConfigKeys) : base(500, "bad-custodian-account-config", "Wrong config values: " + String.Join(", ", badConfigKeys))
{
this.BadConfigKeys = badConfigKeys;
}
}

View File

@ -1,13 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class CannotWithdrawException : CustodianApiException
{
public CannotWithdrawException(ICustodian custodian, string paymentMethod, string message) : base(403, "cannot-withdraw", message)
{
}
public CannotWithdrawException(ICustodian custodian, string paymentMethod, string targetAddress, CustodianApiException originalException) : base(403, "cannot-withdraw", $"{custodian.Name} cannot withdraw {paymentMethod} to '{targetAddress}': {originalException.Message}")
{
}
}

View File

@ -1,16 +0,0 @@
using System;
namespace BTCPayServer.Abstractions.Custodians;
public class CustodianApiException: Exception {
public int HttpStatus { get; }
public string Code { get; }
public CustodianApiException(int httpStatus, string code, string message, System.Exception ex) : base(message, ex)
{
HttpStatus = httpStatus;
Code = code;
}
public CustodianApiException( int httpStatus, string code, string message) : this(httpStatus, code, message, null)
{
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class CustodianFeatureNotImplementedException: CustodianApiException
{
public CustodianFeatureNotImplementedException(string message) : base(400, "not-implemented", message)
{
}
}

View File

@ -1,8 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class DepositsUnavailableException : CustodianApiException
{
public DepositsUnavailableException(string message) : base(404, "deposits-unavailable", message)
{
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class InsufficientFundsException : CustodianApiException
{
public InsufficientFundsException(string message) : base(400, "insufficient-funds", message)
{
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class InvalidWithdrawalTargetException : CustodianApiException
{
public InvalidWithdrawalTargetException(ICustodian custodian, string paymentMethod, string targetAddress, CustodianApiException originalException) : base(403, "invalid-withdrawal-target", $"{custodian.Name} cannot withdraw {paymentMethod} to '{targetAddress}': {originalException.Message}")
{
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class PermissionDeniedCustodianApiException : CustodianApiException
{
public PermissionDeniedCustodianApiException(ICustodian custodian) : base(403, "custodian-api-permission-denied", $"{custodian.Name}'s API reported that you don't have permission.")
{
}
}

View File

@ -1,11 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class TradeNotFoundException : CustodianApiException
{
private string tradeId { get; }
public TradeNotFoundException(string tradeId) : base(404,"trade-not-found","Could not find trade ID " + tradeId)
{
this.tradeId = tradeId;
}
}

View File

@ -1,11 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class WithdrawalNotFoundException : CustodianApiException
{
private string WithdrawalId { get; }
public WithdrawalNotFoundException(string withdrawalId) : base(404, "withdrawal-not-found", $"Could not find withdrawal ID {withdrawalId}.")
{
WithdrawalId = withdrawalId;
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Abstractions.Custodians;
public class WrongTradingPairException: CustodianApiException
{
public const int HttpCode = 404;
public WrongTradingPairException(string fromAsset, string toAsset) : base(HttpCode, "wrong-trading-pair", $"Cannot find a trading pair for converting {fromAsset} into {toAsset}.")
{
}
}

View File

@ -1,29 +0,0 @@
using System.Collections.Generic;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Abstractions.Custodians;
/**
* The result of a market trade. Used as a return type for custodians implementing ICanTrade
*/
public class MarketTradeResult
{
public string FromAsset { get; }
public string ToAsset { get; }
/**
* The ledger entries that show the balances that were affected by the trade.
*/
public List<LedgerEntryData> LedgerEntries { get; }
/**
* The unique ID of the trade that was executed.
*/
public string TradeId { get; }
public MarketTradeResult(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId)
{
this.FromAsset = fromAsset;
this.ToAsset = toAsset;
this.LedgerEntries = ledgerEntries;
this.TradeId = tradeId;
}
}

View File

@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Abstractions.Custodians;
public class WithdrawResult
{
public string PaymentMethod { get; }
public string Asset { get; set; }
public List<LedgerEntryData> LedgerEntries { get; }
public string WithdrawalId { get; }
public WithdrawalResponseData.WithdrawalStatus Status { get; }
public DateTimeOffset CreatedTime { get; }
public string TargetAddress { get; }
public string TransactionId { get; }
public WithdrawResult(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string withdrawalId, WithdrawalResponseData.WithdrawalStatus status, DateTimeOffset createdTime, string targetAddress, string transactionId)
{
PaymentMethod = paymentMethod;
Asset = asset;
LedgerEntries = ledgerEntries;
WithdrawalId = withdrawalId;
CreatedTime = createdTime;
Status = status;
TargetAddress = targetAddress;
TransactionId = transactionId;
}
}

View File

@ -1,17 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;
public interface ICanDeposit
{
/**
* Get the address where we can deposit for the chosen payment method (crypto code + network).
* The result can be a string in different formats like a bitcoin address or even a LN invoice.
*/
public Task<DepositAddressData> GetDepositAddressAsync(string paymentMethod, JObject config, CancellationToken cancellationToken);
public string[] GetDepositablePaymentMethods();
}

View File

@ -1,32 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;
public interface ICanTrade
{
/**
* A list of tradable asset pairs, or NULL if the custodian cannot trade/convert assets. if thr asset pair contains fiat, fiat is always put last. If both assets are a cyrptocode or both are fiat, the pair is written alphabetically. Always in uppercase. Example: ["BTC/EUR","BTC/USD", "EUR/USD", "BTC/ETH",...]
*/
public List<AssetPairData> GetTradableAssetPairs();
/**
* Execute a market order right now.
*/
public Task<MarketTradeResult> TradeMarketAsync(string fromAsset, string toAsset, decimal qty, JObject config, CancellationToken cancellationToken);
/**
* Get the details about a previous market trade.
*/
public Task<MarketTradeResult> GetTradeInfoAsync(string tradeId, JObject config, CancellationToken cancellationToken);
public Task<AssetQuoteResult> GetQuoteForAssetAsync(string fromAsset, string toAsset, JObject config, CancellationToken cancellationToken);
}

View File

@ -1,14 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;
public interface ICanWithdraw
{
public Task<WithdrawResult> WithdrawAsync(string paymentMethod, decimal amount, JObject config, CancellationToken cancellationToken);
public Task<WithdrawResult> GetWithdrawalInfoAsync(string paymentMethod, string withdrawalId, JObject config, CancellationToken cancellationToken);
public string[] GetWithdrawablePaymentMethods();
}

View File

@ -1,26 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Abstractions.Custodians;
public interface ICustodian
{
/**
* Get the unique code that identifies this custodian.
*/
string Code { get; }
string Name { get; }
/**
* Get a list of assets and their qty in custody.
*/
Task<Dictionary<string, decimal>> GetAssetBalancesAsync(JObject config, CancellationToken cancellationToken);
public Task<Form.Form> GetConfigForm(JObject config, string locale,
CancellationToken cancellationToken = default);
}

View File

@ -1,14 +0,0 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using BTCPayServer.Abstractions.Custodians;
namespace BTCPayServer.Abstractions.Extensions;
public static class CustodianExtensions
{
public static ICustodian? GetCustodianByCode(this IEnumerable<ICustodian> custodians, string code)
{
return custodians.FirstOrDefault(custodian => custodian.Code == code);
}
}

View File

@ -90,7 +90,7 @@ namespace BTCPayServer.Abstractions.Extensions
public static string ToTimeAgo(this DateTimeOffset date)
{
var diff = DateTimeOffset.UtcNow - date;
var formatted = diff.TotalSeconds > 0
var formatted = diff.Seconds > 0
? $"{diff.TimeString()} ago"
: $"in {diff.Negate().TimeString()}";
return formatted;
@ -113,9 +113,9 @@ namespace BTCPayServer.Abstractions.Extensions
return $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
}
private static string Plural(int value)
private static string Plural(int totalDays)
{
return value > 1 ? "s" : string.Empty;
return totalDays > 1 ? "s" : string.Empty;
}
}
}

View File

@ -1,37 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Abstractions.Form;
public class AlertMessage
{
// Corresponds to the Bootstrap CSS "alert alert-xxx" messages:
// Success = green
// Warning = orange
// Danger = red
// Info = blue
public enum AlertMessageType
{
Success,
Warning,
Danger,
Info
}
[JsonConverter(typeof(StringEnumConverter))]
public AlertMessageType Type;
// The translated message to be shown to the user
public string Message;
public AlertMessage()
{
}
public AlertMessage(AlertMessageType type, string message)
{
this.Type = type;
this.Message = message;
}
}

View File

@ -1,35 +0,0 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public abstract class Field
{
// HTML5 compatible type string like "text", "textarea", "email", "password", etc. Each type is a class and may contain more fields (i.e. "select" would have options).
public string Type;
// The name of the HTML5 node. Should be used as the key for the posted data.
public string Name;
// The translated label of the field.
public string Label;
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
// If this is the first the user sees the form, then value and original value are the same. Value changes as the user starts interacting with the form.
public string Value;
// The original value is the value that is currently saved in the backend. A "reset" button can be used to revert back to this. Should only be set from the constructor.
public string OriginalValue;
// A useful note shown below the field or via a tooltip / info icon. Should be translated for the user.
public string HelpText;
// The field is considered "valid" if there are no validation errors
public List<string> ValidationErrors = new List<string>();
public bool Required = false;
public bool IsValid()
{
return ValidationErrors.Count == 0;
}
}

View File

@ -1,14 +0,0 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public class Fieldset
{
public Fieldset()
{
this.Fields = new List<Field>();
}
public string Label { get; set; }
public List<Field> Fields { get; set; }
}

View File

@ -1,60 +0,0 @@
using System.Collections.Generic;
namespace BTCPayServer.Abstractions.Form;
public class Form
{
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
public List<AlertMessage> TopMessages { get; set; } = new();
// Groups of fields in the form
public List<Fieldset> Fieldsets { get; set; } = new();
// Are all the fields valid in the form?
public bool IsValid()
{
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
if (!field.IsValid())
{
return false;
}
}
}
return true;
}
public Field GetFieldByName(string name)
{
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
if (name.Equals(field.Name))
{
return field;
}
}
}
return null;
}
public List<string> GetAllNames()
{
var names = new List<string>();
foreach (var fieldset in Fieldsets)
{
foreach (var field in fieldset.Fields)
{
names.Add(field.Name);
}
}
return names;
}
}

View File

@ -1,19 +0,0 @@
namespace BTCPayServer.Abstractions.Form;
public class TextField : Field
{
public TextField(string label, string name, string value, bool required, string helpText)
{
this.Label = label;
this.Name = name;
this.Value = value;
this.OriginalValue = value;
this.Required = required;
this.HelpText = helpText;
this.Type = "text";
}
// TODO JSON parsing from string to objects again probably won't work out of the box because of the different field types.
}

View File

@ -14,7 +14,7 @@
<RepositoryType>git</RepositoryType>
</PropertyGroup>
<PropertyGroup>
<Version Condition=" '$(Version)' == '' ">1.7.0</Version>
<Version Condition=" '$(Version)' == '' ">1.6.0</Version>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PublishRepositoryUrl>true</PublishRepositoryUrl>
@ -28,8 +28,8 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.8" />
<PackageReference Include="NBitcoin" Version="7.0.1" />
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,43 +0,0 @@
using System;
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<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
CreatePointOfSaleAppRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/apps/pos", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<PointOfSaleAppData>(response);
}
public virtual async Task<AppDataBase> GetApp(string appId, CancellationToken token = default)
{
if (appId == null)
throw new ArgumentNullException(nameof(appId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/apps/{appId}",
method: HttpMethod.Get), token);
return await HandleResponse<AppDataBase>(response);
}
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
{
if (appId == null)
throw new ArgumentNullException(nameof(appId));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/apps/{appId}",
method: HttpMethod.Delete), token);
await HandleResponse(response);
}
}
}

View File

@ -1,93 +0,0 @@
using System.Collections.Generic;
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<IEnumerable<CustodianAccountData>> GetCustodianAccounts(string storeId, bool includeAssetBalances = false, CancellationToken token = default)
{
var queryPayload = new Dictionary<string, object>();
if (includeAssetBalances)
{
queryPayload.Add("assetBalances", "true");
}
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts", queryPayload), token);
return await HandleResponse<IEnumerable<CustodianAccountData>>(response);
}
public virtual async Task<CustodianAccountResponse> GetCustodianAccount(string storeId, string accountId, bool includeAssetBalances = false, CancellationToken token = default)
{
var queryPayload = new Dictionary<string, object>();
if (includeAssetBalances)
{
queryPayload.Add("assetBalances", "true");
}
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", queryPayload), token);
return await HandleResponse<CustodianAccountResponse>(response);
}
public virtual async Task<CustodianAccountData> CreateCustodianAccount(string storeId, CreateCustodianAccountRequest request, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts", bodyPayload: request, method: HttpMethod.Post), token);
return await HandleResponse<CustodianAccountData>(response);
}
public virtual async Task<CustodianAccountData> UpdateCustodianAccount(string storeId, string accountId, CreateCustodianAccountRequest request, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", bodyPayload: request, method: HttpMethod.Put), token);
return await HandleResponse<CustodianAccountData>(response);
}
public virtual async Task DeleteCustodianAccount(string storeId, string accountId, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}", method: HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task<DepositAddressData> GetDepositAddress(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);
return await HandleResponse<DepositAddressData>(response);
}
public virtual async Task<MarketTradeResponseData> TradeMarket(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", bodyPayload: request, method: HttpMethod.Post), token);
return await HandleResponse<MarketTradeResponseData>(response);
}
public virtual async Task<MarketTradeResponseData> GetTradeInfo(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);
return await HandleResponse<MarketTradeResponseData>(response);
}
public virtual async Task<TradeQuoteResponseData> GetTradeQuote(string storeId, string accountId, string fromAsset, string toAsset, CancellationToken token = default)
{
var queryPayload = new Dictionary<string, object>();
queryPayload.Add("fromAsset", fromAsset);
queryPayload.Add("toAsset", toAsset);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote", queryPayload), token);
return await HandleResponse<TradeQuoteResponseData>(response);
}
public virtual async Task<WithdrawalResponseData> CreateWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken token = default)
{
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);
}
public virtual async Task<WithdrawalResponseData> GetWithdrawalInfo(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);
return await HandleResponse<WithdrawalResponseData>(response);
}
}
}

View File

@ -1,16 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<IEnumerable<CustodianData>> GetCustodians(CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/custodians"), token);
return await HandleResponse<IEnumerable<CustodianData>>(response);
}
}
}

View File

@ -17,15 +17,6 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/balance",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeBalanceData>(response);
}
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)

View File

@ -17,15 +17,6 @@ namespace BTCPayServer.Client
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeInformationData>(response);
}
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance",
method: HttpMethod.Get), token);
return await HandleResponse<LightningNodeBalanceData>(response);
}
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
CancellationToken token = default)

View File

@ -55,7 +55,7 @@ namespace BTCPayServer.Client
}
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null,
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null,
CancellationToken token = default)
{
var query = new Dictionary<string, object>();
@ -63,9 +63,6 @@ namespace BTCPayServer.Client
{
query.Add(nameof(statusFilter), statusFilter);
}
if (labelFilter != null) {
query.Add(nameof(labelFilter), labelFilter);
}
var response =
await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/onchain/{cryptoCode}/wallet/transactions", query), token);

View File

@ -1,18 +0,0 @@
#nullable enable
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Client.Models;
namespace BTCPayServer.Client
{
public partial class BTCPayServerClient
{
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/payout-processors"), token);
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
}
}
}

View File

@ -41,23 +41,12 @@ namespace BTCPayServer.Client
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PayoutData[]>(response);
}
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
{
Dictionary<string, object> query = new Dictionary<string, object>();
query.Add("includeCancelled", includeCancelled);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get), cancellationToken);
return await HandleResponse<PayoutData[]>(response);
}
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post), cancellationToken);
return await HandleResponse<PayoutData>(response);
}
public virtual async Task<PayoutData> 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);
return await HandleResponse<PayoutData>(response);
}
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", method: HttpMethod.Delete), cancellationToken);

View File

@ -1,48 +0,0 @@
#nullable enable
using System.Collections.Generic;
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<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors"), token);
return await HandleResponse<IEnumerable<PayoutProcessorData>>(response);
}
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete), token);
await HandleResponse(response);
}
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
return await HandleResponse<IEnumerable<LightningAutomatedPayoutSettings>>(response);
}
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);
return await HandleResponse<LightningAutomatedPayoutSettings>(response);
}
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);
return await HandleResponse<OnChainAutomatedPayoutSettings>(response);
}
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null? string.Empty: $"/{paymentMethod}")}"), token);
return await HandleResponse<IEnumerable<OnChainAutomatedPayoutSettings>>(response);
}
}
}

View File

@ -33,10 +33,12 @@ namespace BTCPayServer.Client
return await HandleResponse<ApplicationUserData>(response);
}
public virtual async Task LockUser(string idOrEmail, bool locked, CancellationToken token = default)
public virtual async Task ToggleUser(string idOrEmail, bool enabled, CancellationToken token = default)
{
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/lock", null,
new LockUserRequest() {Locked = locked}, HttpMethod.Post), token);
var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/users/{idOrEmail}/toggle", null,new
{
enabled
} , HttpMethod.Post), token);
await HandleResponse(response);
}

View File

@ -0,0 +1,7 @@
namespace BTCPayServer.Client.Models
{
public class AddCustomerEmailRequest
{
public string Email { get; set; }
}
}

View File

@ -1,22 +0,0 @@
namespace BTCPayServer.Client.Models;
public class AssetPairData
{
public AssetPairData()
{
}
public AssetPairData(string assetBought, string assetSold)
{
AssetBought = assetBought;
AssetSold = assetSold;
}
public string AssetBought { set; get; }
public string AssetSold { set; get; }
public override string ToString()
{
return AssetBought + "/" + AssetSold;
}
}

View File

@ -1,41 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models
{
public enum PosViewType
{
Static,
Cart,
Light,
Print
}
public class CreateAppRequest
{
public string AppName { get; set; }
public string AppType { get; set; }
}
public class CreatePointOfSaleAppRequest : CreateAppRequest
{
public string Currency { get; set; } = null;
public string Title { get; set; } = null;
public string Description { get; set; } = null;
public string Template { get; set; } = null;
[JsonConverter(typeof(StringEnumConverter))]
public PosViewType DefaultView { get; set; }
public bool ShowCustomAmount { get; set; } = true;
public bool ShowDiscount { get; set; } = true;
public bool EnableTips { get; set; } = true;
public string CustomAmountPayButtonText { get; set; } = null;
public string FixedAmountPayButtonText { get; set; } = null;
public string TipText { get; set; } = null;
public string CustomCSSLink { get; set; } = null;
public string NotificationUrl { get; set; } = null;
public string RedirectUrl { get; set; } = null;
public bool? RedirectAutomatically { get; set; } = null;
public bool? RequiresRefundEmail { get; set; } = null;
public string EmbeddedCSS { get; set; } = null;
}
}

View File

@ -1,12 +0,0 @@
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
public class CreateCustodianAccountRequest
{
public string CustodianCode { get; set; }
public string Name { get; set; }
public JObject Config { get; set; }
}
}

View File

@ -26,6 +26,5 @@ namespace BTCPayServer.Client.Models
public List<CreateOnChainTransactionRequestDestination> Destinations { get; set; }
[JsonProperty("rbf")]
public bool? RBF { get; set; } = null;
public bool ExcludeUnconfirmed { get; set; } = false;
}
}

View File

@ -1,8 +0,0 @@
#nullable enable
namespace BTCPayServer.Client.Models;
public class CreatePayoutThroughStoreRequest : CreatePayoutRequest
{
public string? PullPaymentId { get; set; }
public bool? Approved { get; set; }
}

View File

@ -22,6 +22,5 @@ namespace BTCPayServer.Client.Models
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset? StartsAt { get; set; }
public string[] PaymentMethods { get; set; }
public bool AutoApproveClaims { get; set; }
}
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Client.Models
{
public abstract class CustodianAccountBaseData
{
public string CustodianCode { get; set; }
public string Name { get; set; }
public string StoreId { get; set; }
public JObject Config { get; set; }
}
}

View File

@ -1,7 +0,0 @@
namespace BTCPayServer.Client.Models
{
public class CustodianAccountData : CustodianAccountBaseData
{
public string Id { get; set; }
}
}

View File

@ -1,14 +0,0 @@
using System.Collections.Generic;
namespace BTCPayServer.Client.Models;
public class CustodianAccountResponse: CustodianAccountData
{
public IDictionary<string, decimal> AssetBalances { get; set; }
public CustodianAccountResponse()
{
}
}

View File

@ -1,11 +0,0 @@
namespace BTCPayServer.Client.Models;
public class CustodianData
{
public string Code { get; set; }
public string Name { get; set; }
public string[] TradableAssetPairs { get; set; }
public string[] WithdrawablePaymentMethods { get; set; }
public string[] DepositablePaymentMethods { get; set; }
}

View File

@ -1,15 +0,0 @@
namespace BTCPayServer.Client.Models;
public class DepositAddressData
{
// /**
// * Example: P2PKH, P2SH, P2WPKH, P2TR, BOLT11, ...
// */
// public string Type { get; set; }
/**
* Format depends hugely on the type.
*/
public string Address { get; set; }
}

View File

@ -1,4 +1,4 @@
namespace BTCPayServer.Client.Models;
namespace BTCPayServer.Client.Models;
public class EmailSettingsData
{
@ -21,9 +21,13 @@ public class EmailSettingsData
{
get; set;
}
public string FromDisplay
{
get; set;
}
public string From
{
get; set;
}
public bool DisableCertificateCheck { get; set; }
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using Newtonsoft.Json;
@ -20,48 +19,6 @@ namespace BTCPayServer.Client.Models
public string Currency { get; set; }
public JObject Metadata { get; set; }
public CheckoutOptions Checkout { get; set; } = new CheckoutOptions();
public ReceiptOptions Receipt { get; set; } = new ReceiptOptions();
public class ReceiptOptions
{
public bool? Enabled { get; set; }
public bool? ShowQR { get; set; }
public bool? ShowPayments { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
#nullable enable
/// <summary>
/// Make sure that the return has all values set by order of priority: invoice/store/default
/// </summary>
/// <param name="storeLevelOption"></param>
/// <param name="invoiceLevelOption"></param>
/// <returns></returns>
public static ReceiptOptions Merge(ReceiptOptions? storeLevelOption, ReceiptOptions? invoiceLevelOption)
{
storeLevelOption ??= new ReceiptOptions();
invoiceLevelOption ??= new ReceiptOptions();
var store = JObject.FromObject(storeLevelOption);
var inv = JObject.FromObject(invoiceLevelOption);
var result = JObject.FromObject(CreateDefault());
var mergeSettings = new JsonMergeSettings() { MergeNullValueHandling = MergeNullValueHandling.Ignore };
result.Merge(store, mergeSettings);
result.Merge(inv, mergeSettings);
var options = result.ToObject<ReceiptOptions>()!;
return options;
}
public static ReceiptOptions CreateDefault()
{
return new ReceiptOptions()
{
ShowQR = true,
Enabled = true,
ShowPayments = true
};
}
#nullable restore
}
public class CheckoutOptions
{

View File

@ -1,27 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models;
public class LedgerEntryData
{
public string Asset { get; }
public decimal Qty { get; }
[JsonConverter(typeof(StringEnumConverter))]
public LedgerEntryType Type { get; }
public LedgerEntryData(string asset, decimal qty, LedgerEntryType type)
{
Asset = asset;
Qty = qty;
Type = type;
}
public enum LedgerEntryType
{
Trade = 0,
Fee = 1,
Withdrawal = 2
}
}

View File

@ -1,13 +0,0 @@
using System;
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models;
public class LightningAutomatedPayoutSettings
{
public string PaymentMethod { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
public TimeSpan IntervalSeconds { get; set; }
}

View File

@ -1,53 +0,0 @@
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Lightning;
using NBitcoin;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class LightningNodeBalanceData
{
[JsonProperty("onchain")]
public OnchainBalanceData OnchainBalance { get; set; }
[JsonProperty("offchain")]
public OffchainBalanceData OffchainBalance { get; set; }
public LightningNodeBalanceData()
{
}
public LightningNodeBalanceData(OnchainBalanceData onchain, OffchainBalanceData offchain)
{
OnchainBalance = onchain;
OffchainBalance = offchain;
}
}
public class OnchainBalanceData
{
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Confirmed { get; set; }
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Unconfirmed { get; set; }
[JsonConverter(typeof(JsonConverters.MoneyJsonConverter))]
public Money Reserved { get; set; }
}
public class OffchainBalanceData
{
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Opening { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Local { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Remote { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Closing { get; set; }
}
}

View File

@ -1,6 +0,0 @@
namespace BTCPayServer.Client;
public class LockUserRequest
{
public bool Locked { get; set; }
}

View File

@ -1,31 +0,0 @@
using System.Collections.Generic;
namespace BTCPayServer.Client.Models;
public class MarketTradeResponseData
{
public string FromAsset { get; }
public string ToAsset { get; }
/**
* The ledger entries that show the balances that were affected by the trade.
*/
public List<LedgerEntryData> LedgerEntries { get; }
/**
* The unique ID of the trade that was executed.
*/
public string TradeId { get; }
public string AccountId { get; }
public string CustodianCode { get; }
public MarketTradeResponseData(string fromAsset, string toAsset, List<LedgerEntryData> ledgerEntries, string tradeId, string accountId, string custodianCode)
{
FromAsset = fromAsset;
ToAsset = toAsset;
LedgerEntries = ledgerEntries;
TradeId = tradeId;
AccountId = accountId;
CustodianCode = custodianCode;
}
}

View File

@ -1,13 +0,0 @@
using System;
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models;
public class OnChainAutomatedPayoutSettings
{
public string PaymentMethod { get; set; }
[JsonConverter(typeof(TimeSpanJsonConverter.Seconds))]
public TimeSpan IntervalSeconds { get; set; }
}

View File

@ -1,6 +1,6 @@
#nullable enable
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.JsonConverters;
using BTCPayServer.Lightning;
using NBitcoin;
using Newtonsoft.Json;
@ -15,9 +15,6 @@ namespace BTCPayServer.Client.Models
public float? MaxFeePercent { get; set; }
[JsonConverter(typeof(MoneyJsonConverter))]
public Money MaxFeeFlat { get; set; }
[JsonConverter(typeof(LightMoneyJsonConverter))]
public LightMoney Amount { get; set; }
public Money? MaxFeeFlat { get; set; }
}
}

View File

@ -1,9 +0,0 @@
namespace BTCPayServer.Client.Models
{
public class PayoutProcessorData
{
public string Name { get; set; }
public string FriendlyName { get; set; }
public string[] PaymentMethods { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using System;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class AppDataBase
{
public string Id { get; set; }
public string AppType { get; set; }
public string Name { get; set; }
public string StoreId { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
public DateTimeOffset Created { get; set; }
}
public class PointOfSaleAppData : AppDataBase
{
// We can add POS specific things here later
}
}

View File

@ -31,6 +31,5 @@ namespace BTCPayServer.Client.Models
public TimeSpan BOLT11Expiration { get; set; }
public bool Archived { get; set; }
public string ViewLink { get; set; }
public bool AutoApproveClaims { get; set; }
}
}

View File

@ -58,8 +58,6 @@ namespace BTCPayServer.Client.Models
public NetworkFeeMode NetworkFeeMode { get; set; } = NetworkFeeMode.Never;
public bool PayJoinEnabled { get; set; }
public InvoiceData.ReceiptOptions Receipt { get; set; }
[JsonExtensionData]

View File

@ -1,17 +0,0 @@
namespace BTCPayServer.Client.Models;
public class TradeQuoteResponseData
{
public decimal Bid { get; }
public decimal Ask { get; }
public string ToAsset { get; }
public string FromAsset { get; }
public TradeQuoteResponseData(string fromAsset, string toAsset, decimal bid, decimal ask)
{
FromAsset = fromAsset;
ToAsset = toAsset;
Bid = bid;
Ask = ask;
}
}

View File

@ -1,8 +0,0 @@
namespace BTCPayServer.Client.Models;
public class TradeRequestData
{
public string FromAsset { set; get; }
public string ToAsset { set; get; }
public string Qty { set; get; }
}

View File

@ -3,6 +3,7 @@ namespace BTCPayServer.Client.Models
public enum TransactionStatus
{
Unconfirmed,
Confirmed
Confirmed,
Replaced
}
}

View File

@ -1,3 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BTCPayServer.Client.Models
{
public enum WebhookEventType

View File

@ -1,13 +0,0 @@
namespace BTCPayServer.Client.Models;
public class WithdrawRequestData
{
public string PaymentMethod { set; get; }
public decimal Qty { set; get; }
public WithdrawRequestData(string paymentMethod, decimal qty)
{
PaymentMethod = paymentMethod;
Qty = qty;
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace BTCPayServer.Client.Models;
public class WithdrawalResponseData
{
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))]
public WithdrawalStatus Status { get; }
public DateTimeOffset CreatedTime { get; }
public string TransactionId { get; }
public string TargetAddress { get; }
public WithdrawalResponseData(string paymentMethod, string asset, List<LedgerEntryData> ledgerEntries, string withdrawalId, string accountId,
string custodianCode, WithdrawalStatus status, DateTimeOffset createdTime, string targetAddress, string transactionId)
{
PaymentMethod = paymentMethod;
Asset = asset;
LedgerEntries = ledgerEntries;
WithdrawalId = withdrawalId;
AccountId = accountId;
CustodianCode = custodianCode;
TargetAddress = targetAddress;
TransactionId = transactionId;
Status = status;
CreatedTime = createdTime;
}
public enum WithdrawalStatus
{
Unknown = 0,
Queued = 1,
Complete = 2,
Failed = 3
}
}

View File

@ -28,11 +28,6 @@ namespace BTCPayServer.Client
public const string CanCreateUser = "btcpay.server.cancreateuser";
public const string CanDeleteUser = "btcpay.user.candeleteuser";
public const string CanManagePullPayments = "btcpay.store.canmanagepullpayments";
public const string CanViewCustodianAccounts = "btcpay.store.canviewcustodianaccounts";
public const string CanManageCustodianAccounts = "btcpay.store.canmanagecustodianaccounts";
public const string CanDepositToCustodianAccounts = "btcpay.store.candeposittocustodianaccount";
public const string CanWithdrawFromCustodianAccounts = "btcpay.store.canwithdrawfromcustodianaccount";
public const string CanTradeCustodianAccount = "btcpay.store.cantradecustodianaccount";
public const string Unrestricted = "unrestricted";
public static IEnumerable<string> AllPolicies
{
@ -60,11 +55,6 @@ namespace BTCPayServer.Client
yield return CanUseLightningNodeInStore;
yield return CanCreateLightningInvoiceInStore;
yield return CanManagePullPayments;
yield return CanViewCustodianAccounts;
yield return CanManageCustodianAccounts;
yield return CanDepositToCustodianAccounts;
yield return CanWithdrawFromCustodianAccounts;
yield return CanTradeCustodianAccount;
}
}
public static bool IsValidPolicy(string policy)
@ -194,9 +184,6 @@ namespace BTCPayServer.Client
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;

View File

@ -106,11 +106,9 @@ namespace BTCPayServer
{
}
}
cancellationToken.ThrowIfCancellationRequested();
lock (_Queues)
{
if (_Queues.Count is 0)
return;
cancellationToken.ThrowIfCancellationRequested();
Cleanup();
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Linq;
using BTCPayServer.Data.Data;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
@ -34,8 +33,8 @@ namespace BTCPayServer.Data
public DbSet<AddressInvoiceData> AddressInvoices { get; set; }
public DbSet<APIKeyData> ApiKeys { get; set; }
public DbSet<AppData> Apps { get; set; }
public DbSet<CustodianAccountData> CustodianAccount { get; set; }
public DbSet<StoredFile> Files { get; set; }
public DbSet<HistoricalAddressInvoiceData> HistoricalAddressInvoices { get; set; }
public DbSet<InvoiceEventData> InvoiceEvents { get; set; }
public DbSet<InvoiceSearchData> InvoiceSearches { get; set; }
public DbSet<InvoiceWebhookDeliveryData> InvoiceWebhookDeliveries { get; set; }
@ -53,7 +52,6 @@ namespace BTCPayServer.Data
public DbSet<PullPaymentData> PullPayments { get; set; }
public DbSet<RefundData> Refunds { get; set; }
public DbSet<SettingData> Settings { get; set; }
public DbSet<StoreSettingData> StoreSettings { get; set; }
public DbSet<StoreWebhookData> StoreWebhooks { get; set; }
public DbSet<StoreData> Stores { get; set; }
public DbSet<U2FDevice> U2FDevices { get; set; }
@ -63,8 +61,6 @@ namespace BTCPayServer.Data
public DbSet<WalletTransactionData> WalletTransactions { get; set; }
public DbSet<WebhookDeliveryData> WebhookDeliveries { get; set; }
public DbSet<WebhookData> Webhooks { get; set; }
public DbSet<LightningAddressData> LightningAddresses{ get; set; }
public DbSet<PayoutProcessorData> PayoutProcessors { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
@ -83,15 +79,15 @@ namespace BTCPayServer.Data
AddressInvoiceData.OnModelCreating(builder);
APIKeyData.OnModelCreating(builder);
AppData.OnModelCreating(builder);
CustodianAccountData.OnModelCreating(builder);
//StoredFile.OnModelCreating(builder);
HistoricalAddressInvoiceData.OnModelCreating(builder);
InvoiceEventData.OnModelCreating(builder);
InvoiceSearchData.OnModelCreating(builder);
InvoiceWebhookDeliveryData.OnModelCreating(builder);
InvoiceData.OnModelCreating(builder);
NotificationData.OnModelCreating(builder);
//OffchainTransactionData.OnModelCreating(builder);
BTCPayServer.Data.PairedSINData.OnModelCreating(builder);
Data.PairedSINData.OnModelCreating(builder);
PairingCodeData.OnModelCreating(builder);
//PayjoinLock.OnModelCreating(builder);
PaymentRequestData.OnModelCreating(builder);
@ -102,17 +98,14 @@ namespace BTCPayServer.Data
PullPaymentData.OnModelCreating(builder);
RefundData.OnModelCreating(builder);
//SettingData.OnModelCreating(builder);
StoreSettingData.OnModelCreating(builder, Database);
StoreWebhookData.OnModelCreating(builder);
//StoreData.OnModelCreating(builder);
U2FDevice.OnModelCreating(builder);
Fido2Credential.OnModelCreating(builder);
BTCPayServer.Data.UserStore.OnModelCreating(builder);
Data.UserStore.OnModelCreating(builder);
//WalletData.OnModelCreating(builder);
WalletTransactionData.OnModelCreating(builder);
WebhookDeliveryData.OnModelCreating(builder);
LightningAddressData.OnModelCreating(builder);
PayoutProcessorData.OnModelCreating(builder);
//WebhookData.OnModelCreating(builder);

View File

@ -15,6 +15,7 @@ namespace BTCPayServer.Data
public bool TagAllInvoices { get; set; }
public string Settings { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<AppData>()
@ -27,7 +28,9 @@ namespace BTCPayServer.Data
// utility methods
public T GetSettings<T>() where T : class, new()
{
return string.IsNullOrEmpty(Settings) ? new T() : JsonConvert.DeserializeObject<T>(Settings);
if (String.IsNullOrEmpty(Settings))
return new T();
return JsonConvert.DeserializeObject<T>(Settings);
}
public void SetSettings(object value)

View File

@ -1,42 +0,0 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Data;
public class CustodianAccountData
{
[Required]
[MaxLength(50)]
public string Id { get; set; }
[Required]
[MaxLength(50)]
public string StoreId { get; set; }
[Required]
[MaxLength(50)]
public string CustodianCode { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[JsonIgnore]
public byte[] Blob { get; set; }
[JsonIgnore]
public StoreData StoreData { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<CustodianAccountData>()
.HasOne(o => o.StoreData)
.WithMany(i => i.CustodianAccounts)
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
builder.Entity<APIKeyData>()
.HasIndex(o => o.StoreId);
}
}

View File

@ -0,0 +1,41 @@
using System;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data
{
public class HistoricalAddressInvoiceData
{
public string InvoiceDataId { get; set; }
public InvoiceData InvoiceData { get; set; }
/// <summary>
/// Some crypto currencies share same address prefix
/// For not having exceptions thrown by two address on different network, we suffix by "#CRYPTOCODE"
/// </summary>
[Obsolete("Use GetCryptoCode instead")]
public string Address { get; set; }
[Obsolete("Use GetCryptoCode instead")]
public string CryptoCode { get; set; }
public DateTimeOffset Assigned { get; set; }
public DateTimeOffset? UnAssigned { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<HistoricalAddressInvoiceData>()
.HasOne(o => o.InvoiceData)
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
builder.Entity<HistoricalAddressInvoiceData>()
.HasKey(o => new
{
o.InvoiceDataId,
#pragma warning disable CS0618
o.Address
#pragma warning restore CS0618
});
}
}
}

View File

@ -16,6 +16,8 @@ namespace BTCPayServer.Data
public List<PaymentData> Payments { get; set; }
public List<InvoiceEventData> Events { get; set; }
public List<HistoricalAddressInvoiceData> HistoricalAddressInvoices { get; set; }
public byte[] Blob { get; set; }
public string ItemCode { get; set; }
public string OrderId { get; set; }
@ -41,7 +43,6 @@ namespace BTCPayServer.Data
builder.Entity<InvoiceData>().HasIndex(o => o.OrderId);
builder.Entity<InvoiceData>()
.HasOne(o => o.CurrentRefund);
builder.Entity<InvoiceData>().HasIndex(o => o.Created);
}
}
}

View File

@ -1,31 +0,0 @@
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data;
public class LightningAddressData
{
public string Username { get; set; }
public string StoreDataId { get; set; }
public byte[] Blob { get; set; }
public StoreData Store { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<LightningAddressData>()
.HasOne(o => o.Store)
.WithMany(a => a.LightningAddresses)
.HasForeignKey(data => data.StoreDataId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<LightningAddressData>().HasKey(o => o.Username);
}
}
public class LightningAddressDataBlob
{
public string CurrencyCode { get; set; }
public decimal? Min { get; set; }
public decimal? Max { get; set; }
}

View File

@ -14,7 +14,6 @@ namespace BTCPayServer.Data
public string Id { get; set; }
public DateTimeOffset Date { get; set; }
public string PullPaymentDataId { get; set; }
public string StoreDataId { get; set; }
public PullPaymentData PullPaymentData { get; set; }
[MaxLength(20)]
public PayoutState State { get; set; }
@ -26,16 +25,12 @@ namespace BTCPayServer.Data
#nullable enable
public string? Destination { get; set; }
#nullable restore
public StoreData StoreData { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PayoutData>()
.HasOne(o => o.PullPaymentData)
.WithMany(o => o.Payouts).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PayoutData>()
.HasOne(o => o.StoreData)
.WithMany(o => o.Payouts).OnDelete(DeleteBehavior.Cascade);
builder.Entity<PayoutData>()
.Property(o => o.State)
.HasConversion<string>();
@ -51,10 +46,12 @@ namespace BTCPayServer.Data
var period = pp.GetPeriod(now);
if (period is { } p)
{
return p.Start <= Date && (p.End is not { } end || Date < end);
return p.Start <= Date && (p.End is DateTimeOffset end ? Date < end : true);
}
else
{
return false;
}
return false;
}
}
}

View File

@ -1,24 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace BTCPayServer.Data.Data;
public class PayoutProcessorData
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; set; }
public string StoreId { get; set; }
public StoreData Store { get; set; }
public string PaymentMethod { get; set; }
public string Processor { get; set; }
public byte[] Blob { get; set; }
internal static void OnModelCreating(ModelBuilder builder)
{
builder.Entity<PayoutProcessorData>()
.HasOne(o => o.Store)
.WithMany(data => data.PayoutProcessors).OnDelete(DeleteBehavior.Cascade);
}
}

View File

@ -2,8 +2,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using BTCPayServer.Client.Models;
using BTCPayServer.Data.Data;
using PayoutProcessorData = BTCPayServer.Data.Data.PayoutProcessorData;
namespace BTCPayServer.Data
{
@ -43,10 +41,5 @@ namespace BTCPayServer.Data
public List<PairedSINData> PairedSINs { get; set; }
public IEnumerable<APIKeyData> APIKeys { get; set; }
public IEnumerable<LightningAddressData> LightningAddresses { get; set; }
public IEnumerable<PayoutProcessorData> PayoutProcessors { get; set; }
public IEnumerable<PayoutData> Payouts { get; set; }
public IEnumerable<CustodianAccountData> CustodianAccounts { get; set; }
public IEnumerable<StoreSettingData> Settings { get; set; }
}
}

View File

@ -1,28 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace BTCPayServer.Data;
public class StoreSettingData
{
public string Name { get; set; }
public string StoreId { get; set; }
public string Value { get; set; }
public StoreData Store { get; set; }
public static void OnModelCreating(ModelBuilder builder, DatabaseFacade databaseFacade)
{
builder.Entity<StoreSettingData>().HasKey(data => new { data.StoreId, data.Name });
builder.Entity<StoreSettingData>()
.HasOne(o => o.Store)
.WithMany(o => o.Settings).OnDelete(DeleteBehavior.Cascade);
if (databaseFacade.IsNpgsql())
{
builder.Entity<StoreSettingData>()
.Property(o => o.Value)
.HasColumnType("JSONB");
}
}
}

View File

@ -1,6 +0,0 @@
namespace BTCPayServer.Data;
public class TradeResultData
{
}

View File

@ -1,50 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220115184620_AddCustodianAccountData")]
public partial class AddCustodianAccountData : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "CustodianAccount",
columns: table => new
{
Id = table.Column<string>(maxLength: 50, nullable: false),
StoreId = table.Column<string>(maxLength: 50, nullable: false),
CustodianCode = table.Column<string>(maxLength: 50, nullable: false),
Name = table.Column<string>(maxLength: 50, nullable: true),
Blob = table.Column<byte[]>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_CustodianAccount", x => x.Id);
table.ForeignKey(
name: "FK_CustodianAccount_Stores_StoreId",
column: x => x.StoreId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_CustodianAccount_StoreId",
table: "CustodianAccount",
column: "StoreId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CustodianAccount");
}
}
}

View File

@ -1,92 +0,0 @@
// <auto-generated />
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220311135252_AddPayoutProcessors")]
public partial class AddPayoutProcessors : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "StoreDataId",
table: "Payouts",
type: "TEXT",
nullable: true);
migrationBuilder.CreateTable(
name: "PayoutProcessors",
columns: table => new
{
Id = table.Column<string>(type: "TEXT", nullable: false),
StoreId = table.Column<string>(type: "TEXT", nullable: true),
PaymentMethod = table.Column<string>(type: "TEXT", nullable: true),
Processor = table.Column<string>(type: "TEXT", nullable: true),
Blob = table.Column<byte[]>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PayoutProcessors", x => x.Id);
table.ForeignKey(
name: "FK_PayoutProcessors_Stores_StoreId",
column: x => x.StoreId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Payouts_StoreDataId",
table: "Payouts",
column: "StoreDataId");
migrationBuilder.CreateIndex(
name: "IX_PayoutProcessors_StoreId",
table: "PayoutProcessors",
column: "StoreId");
if (this.SupportAddForeignKey(ActiveProvider))
{
migrationBuilder.AddForeignKey(
name: "FK_Payouts_Stores_StoreDataId",
table: "Payouts",
column: "StoreDataId",
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
protected override void Down(MigrationBuilder migrationBuilder)
{
if (this.SupportDropForeignKey(ActiveProvider))
{
migrationBuilder.DropForeignKey(
name: "FK_Payouts_Stores_StoreDataId",
table: "Payouts");
migrationBuilder.DropTable(
name: "PayoutProcessors");
migrationBuilder.DropIndex(
name: "IX_Payouts_StoreDataId",
table: "Payouts");
}
if(this.SupportDropColumn(ActiveProvider))
{
migrationBuilder.DropColumn(
name: "StoreDataId",
table: "Payouts");
}
}
}
}

View File

@ -1,51 +0,0 @@
// <auto-generated />
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220414132313_AddLightningAddress")]
public partial class AddLightningAddress : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "LightningAddresses",
columns: table => new
{
Username = table.Column<string>(type: "TEXT", nullable: false),
StoreDataId = table.Column<string>(type: "TEXT", nullable: false),
Blob = table.Column<byte[]>( nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_LightningAddresses", x => x.Username);
table.ForeignKey(
name: "FK_LightningAddresses_Stores_StoreDataId",
column: x => x.StoreDataId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_LightningAddresses_StoreDataId",
table: "LightningAddresses",
column: "StoreDataId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "LightningAddresses");
}
}
}

View File

@ -1,28 +0,0 @@
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220518061525_invoice_created_idx")]
public partial class invoice_created_idx : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_Invoices_Created",
table: "Invoices",
column: "Created");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Invoices_Created",
table: "Invoices");
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220523022603_remove_historical_addresses")]
public partial class remove_historical_addresses : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "HistoricalAddressInvoices");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "HistoricalAddressInvoices",
columns: table => new
{
InvoiceDataId = table.Column<string>(type: "TEXT", nullable: false),
Address = table.Column<string>(type: "TEXT", nullable: false),
Assigned = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
CryptoCode = table.Column<string>(type: "TEXT", nullable: true),
UnAssigned = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_HistoricalAddressInvoices", x => new { x.InvoiceDataId, x.Address });
table.ForeignKey(
name: "FK_HistoricalAddressInvoices_Invoices_InvoiceDataId",
column: x => x.InvoiceDataId,
principalTable: "Invoices",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using BTCPayServer.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220610090843_AddSettingsToStore")]
public partial class AddSettingsToStore : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "StoreSettings",
columns: table => new
{
Name = table.Column<string>(type: "TEXT", nullable: false),
StoreId = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(type: migrationBuilder.IsNpgsql() ? "JSONB" : "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_StoreSettings", x => new { x.StoreId, x.Name });
table.ForeignKey(
name: "FK_StoreSettings_Stores_StoreId",
column: x => x.StoreId,
principalTable: "Stores",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "StoreSettings");
}
}
}

View File

@ -6,8 +6,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace BTCPayServer.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
@ -16,7 +14,40 @@ namespace BTCPayServer.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.1");
modelBuilder
.HasAnnotation("ProductVersion", "3.1.19");
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT")
.HasMaxLength(50);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.Property<string>("Label")
.HasColumnType("TEXT");
b.Property<string>("StoreId")
.HasColumnType("TEXT")
.HasMaxLength(50);
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Id");
b.HasIndex("StoreId");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
{
@ -36,38 +67,6 @@ namespace BTCPayServer.Migrations
b.ToTable("AddressInvoices");
});
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
{
b.Property<string>("Id")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.Property<string>("Label")
.HasColumnType("TEXT");
b.Property<string>("StoreId")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("UserId")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("StoreId");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("BTCPayServer.Data.AppData", b =>
{
b.Property<string>("Id")
@ -120,8 +119,8 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
@ -133,12 +132,12 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
@ -159,74 +158,19 @@ namespace BTCPayServer.Migrations
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
.HasName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("BTCPayServer.Data.CustodianAccountData", b =>
{
b.Property<string>("Id")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.Property<string>("CustodianCode")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<string>("StoreId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("StoreId");
b.ToTable("CustodianAccount");
});
modelBuilder.Entity("BTCPayServer.Data.Data.PayoutProcessorData", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.Property<string>("PaymentMethod")
.HasColumnType("TEXT");
b.Property<string>("Processor")
.HasColumnType("TEXT");
b.Property<string>("StoreId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("StoreId");
b.ToTable("PayoutProcessors");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("BTCPayServer.Data.Fido2Credential", b =>
@ -254,6 +198,28 @@ namespace BTCPayServer.Migrations
b.ToTable("Fido2Credentials");
});
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
{
b.Property<string>("InvoiceDataId")
.HasColumnType("TEXT");
b.Property<string>("Address")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("Assigned")
.HasColumnType("TEXT");
b.Property<string>("CryptoCode")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UnAssigned")
.HasColumnType("TEXT");
b.HasKey("InvoiceDataId", "Address");
b.ToTable("HistoricalAddressInvoices");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
{
b.Property<string>("Id")
@ -291,8 +257,6 @@ namespace BTCPayServer.Migrations
b.HasKey("Id");
b.HasIndex("Created");
b.HasIndex("OrderId");
b.HasIndex("StoreDataId");
@ -367,35 +331,16 @@ namespace BTCPayServer.Migrations
b.ToTable("InvoiceWebhookDeliveries");
});
modelBuilder.Entity("BTCPayServer.Data.LightningAddressData", b =>
{
b.Property<string>("Username")
.HasColumnType("TEXT");
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
b.Property<string>("StoreDataId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Username");
b.HasIndex("StoreDataId");
b.ToTable("LightningAddresses");
});
modelBuilder.Entity("BTCPayServer.Data.NotificationData", b =>
{
b.Property<string>("Id")
.HasMaxLength(36)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(36);
b.Property<string>("ApplicationUserId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(50);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
@ -405,8 +350,8 @@ namespace BTCPayServer.Migrations
b.Property<string>("NotificationType")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<bool>("Seen")
.HasColumnType("INTEGER");
@ -421,8 +366,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.OffchainTransactionData", b =>
{
b.Property<string>("Id")
.HasMaxLength(64)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(64);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
@ -492,8 +437,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.PayjoinLock", b =>
{
b.Property<string>("Id")
.HasMaxLength(100)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(100);
b.HasKey("Id");
@ -555,8 +500,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.PayoutData", b =>
{
b.Property<string>("Id")
.HasMaxLength(30)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(30);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
@ -569,8 +514,8 @@ namespace BTCPayServer.Migrations
b.Property<string>("PaymentMethodId")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(20);
b.Property<byte[]>("Proof")
.HasColumnType("BLOB");
@ -580,11 +525,8 @@ namespace BTCPayServer.Migrations
b.Property<string>("State")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("TEXT");
b.Property<string>("StoreDataId")
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(20);
b.HasKey("Id");
@ -592,8 +534,6 @@ namespace BTCPayServer.Migrations
b.HasIndex("State");
b.HasIndex("StoreDataId");
b.HasIndex("Destination", "State");
b.ToTable("Payouts");
@ -612,8 +552,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.PlannedTransaction", b =>
{
b.Property<string>("Id")
.HasMaxLength(100)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<byte[]>("Blob")
.HasColumnType("BLOB");
@ -629,8 +569,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.PullPaymentData", b =>
{
b.Property<string>("Id")
.HasMaxLength(30)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(30);
b.Property<bool>("Archived")
.HasColumnType("INTEGER");
@ -648,8 +588,8 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("StoreId")
.HasMaxLength(50)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Id");
@ -664,8 +604,8 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("PullPaymentDataId")
.HasMaxLength(30)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(30);
b.HasKey("InvoiceDataId", "PullPaymentDataId");
@ -721,6 +661,25 @@ namespace BTCPayServer.Migrations
b.ToTable("Stores");
});
modelBuilder.Entity("BTCPayServer.Data.StoreWebhookData", b =>
{
b.Property<string>("StoreId")
.HasColumnType("TEXT");
b.Property<string>("WebhookId")
.HasColumnType("TEXT");
b.HasKey("StoreId", "WebhookId");
b.HasIndex("StoreId")
.IsUnique();
b.HasIndex("WebhookId")
.IsUnique();
b.ToTable("StoreWebhooks");
});
modelBuilder.Entity("BTCPayServer.Data.StoredFile", b =>
{
b.Property<string>("Id")
@ -746,41 +705,6 @@ namespace BTCPayServer.Migrations
b.ToTable("Files");
});
modelBuilder.Entity("BTCPayServer.Data.StoreSettingData", b =>
{
b.Property<string>("StoreId")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("StoreId", "Name");
b.ToTable("StoreSettings");
});
modelBuilder.Entity("BTCPayServer.Data.StoreWebhookData", b =>
{
b.Property<string>("StoreId")
.HasColumnType("TEXT");
b.Property<string>("WebhookId")
.HasColumnType("TEXT");
b.HasKey("StoreId", "WebhookId");
b.HasIndex("StoreId")
.IsUnique();
b.HasIndex("WebhookId")
.IsUnique();
b.ToTable("StoreWebhooks");
});
modelBuilder.Entity("BTCPayServer.Data.U2FDevice", b =>
{
b.Property<string>("Id")
@ -867,8 +791,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.WebhookData", b =>
{
b.Property<string>("Id")
.HasMaxLength(25)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(25);
b.Property<byte[]>("Blob")
.IsRequired()
@ -882,8 +806,8 @@ namespace BTCPayServer.Migrations
modelBuilder.Entity("BTCPayServer.Data.WebhookDeliveryData", b =>
{
b.Property<string>("Id")
.HasMaxLength(25)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(25);
b.Property<byte[]>("Blob")
.IsRequired()
@ -894,8 +818,8 @@ namespace BTCPayServer.Migrations
b.Property<string>("WebhookId")
.IsRequired()
.HasMaxLength(25)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(25);
b.HasKey("Id");
@ -914,20 +838,20 @@ namespace BTCPayServer.Migrations
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
.HasColumnType("TEXT")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
@ -950,7 +874,7 @@ namespace BTCPayServer.Migrations
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
@ -973,7 +897,7 @@ namespace BTCPayServer.Migrations
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
@ -995,7 +919,7 @@ namespace BTCPayServer.Migrations
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
@ -1010,7 +934,7 @@ namespace BTCPayServer.Migrations
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
@ -1029,17 +953,7 @@ namespace BTCPayServer.Migrations
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
{
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
.WithMany("AddressInvoices")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("InvoiceData");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
@ -1053,10 +967,14 @@ namespace BTCPayServer.Migrations
.WithMany("APIKeys")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.Navigation("StoreData");
b.Navigation("User");
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
{
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
.WithMany("AddressInvoices")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("BTCPayServer.Data.AppData", b =>
@ -1065,29 +983,6 @@ namespace BTCPayServer.Migrations
.WithMany("Apps")
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.CustodianAccountData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
.WithMany("CustodianAccounts")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.Data.PayoutProcessorData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "Store")
.WithMany("PayoutProcessors")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("Store");
});
modelBuilder.Entity("BTCPayServer.Data.Fido2Credential", b =>
@ -1096,8 +991,15 @@ namespace BTCPayServer.Migrations
.WithMany("Fido2Credentials")
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade);
});
b.Navigation("ApplicationUser");
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
{
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
.WithMany("HistoricalAddressInvoices")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
@ -1110,10 +1012,6 @@ namespace BTCPayServer.Migrations
b.HasOne("BTCPayServer.Data.RefundData", "CurrentRefund")
.WithMany()
.HasForeignKey("Id", "CurrentRefundId");
b.Navigation("CurrentRefund");
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceEventData", b =>
@ -1123,8 +1021,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InvoiceData");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceSearchData", b =>
@ -1133,8 +1029,6 @@ namespace BTCPayServer.Migrations
.WithMany("InvoiceSearchData")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("InvoiceData");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceWebhookDeliveryData", b =>
@ -1150,21 +1044,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("BTCPayServer.Data.InvoiceWebhookDeliveryData", "InvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Delivery");
b.Navigation("Invoice");
});
modelBuilder.Entity("BTCPayServer.Data.LightningAddressData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "Store")
.WithMany("LightningAddresses")
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Store");
});
modelBuilder.Entity("BTCPayServer.Data.NotificationData", b =>
@ -1174,8 +1053,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApplicationUser");
});
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
@ -1184,8 +1061,6 @@ namespace BTCPayServer.Migrations
.WithMany("PairedSINs")
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
@ -1194,8 +1069,6 @@ namespace BTCPayServer.Migrations
.WithMany("Payments")
.HasForeignKey("InvoiceDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("InvoiceData");
});
modelBuilder.Entity("BTCPayServer.Data.PaymentRequestData", b =>
@ -1204,8 +1077,6 @@ namespace BTCPayServer.Migrations
.WithMany("PaymentRequests")
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.PayoutData", b =>
@ -1214,15 +1085,6 @@ namespace BTCPayServer.Migrations
.WithMany("Payouts")
.HasForeignKey("PullPaymentDataId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
.WithMany("Payouts")
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("PullPaymentData");
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
@ -1232,8 +1094,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InvoiceData");
});
modelBuilder.Entity("BTCPayServer.Data.PullPaymentData", b =>
@ -1242,8 +1102,6 @@ namespace BTCPayServer.Migrations
.WithMany("PullPayments")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.RefundData", b =>
@ -1259,30 +1117,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("PullPaymentDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("InvoiceData");
b.Navigation("PullPaymentData");
});
modelBuilder.Entity("BTCPayServer.Data.StoredFile", b =>
{
b.HasOne("BTCPayServer.Data.ApplicationUser", "ApplicationUser")
.WithMany("StoredFiles")
.HasForeignKey("ApplicationUserId");
b.Navigation("ApplicationUser");
});
modelBuilder.Entity("BTCPayServer.Data.StoreSettingData", b =>
{
b.HasOne("BTCPayServer.Data.StoreData", "Store")
.WithMany("Settings")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Store");
});
modelBuilder.Entity("BTCPayServer.Data.StoreWebhookData", b =>
@ -1298,10 +1132,13 @@ namespace BTCPayServer.Migrations
.HasForeignKey("BTCPayServer.Data.StoreWebhookData", "WebhookId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
b.Navigation("Store");
b.Navigation("Webhook");
modelBuilder.Entity("BTCPayServer.Data.StoredFile", b =>
{
b.HasOne("BTCPayServer.Data.ApplicationUser", "ApplicationUser")
.WithMany("StoredFiles")
.HasForeignKey("ApplicationUserId");
});
modelBuilder.Entity("BTCPayServer.Data.U2FDevice", b =>
@ -1310,8 +1147,6 @@ namespace BTCPayServer.Migrations
.WithMany("U2FDevices")
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("ApplicationUser");
});
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
@ -1327,10 +1162,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("StoreDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ApplicationUser");
b.Navigation("StoreData");
});
modelBuilder.Entity("BTCPayServer.Data.WalletTransactionData", b =>
@ -1340,8 +1171,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("WalletDataId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("WalletData");
});
modelBuilder.Entity("BTCPayServer.Data.WebhookDeliveryData", b =>
@ -1351,8 +1180,6 @@ namespace BTCPayServer.Migrations
.HasForeignKey("WebhookId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Webhook");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
@ -1391,7 +1218,7 @@ namespace BTCPayServer.Migrations
.IsRequired();
b.HasOne("BTCPayServer.Data.ApplicationUser", null)
.WithMany("UserRoles")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@ -1405,80 +1232,6 @@ namespace BTCPayServer.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("BTCPayServer.Data.ApplicationUser", b =>
{
b.Navigation("APIKeys");
b.Navigation("Fido2Credentials");
b.Navigation("Notifications");
b.Navigation("StoredFiles");
b.Navigation("U2FDevices");
b.Navigation("UserRoles");
b.Navigation("UserStores");
});
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
{
b.Navigation("AddressInvoices");
b.Navigation("Events");
b.Navigation("InvoiceSearchData");
b.Navigation("Payments");
b.Navigation("PendingInvoices");
b.Navigation("Refunds");
});
modelBuilder.Entity("BTCPayServer.Data.PullPaymentData", b =>
{
b.Navigation("Payouts");
});
modelBuilder.Entity("BTCPayServer.Data.StoreData", b =>
{
b.Navigation("APIKeys");
b.Navigation("Apps");
b.Navigation("CustodianAccounts");
b.Navigation("Invoices");
b.Navigation("LightningAddresses");
b.Navigation("PairedSINs");
b.Navigation("PaymentRequests");
b.Navigation("PayoutProcessors");
b.Navigation("Payouts");
b.Navigation("PullPayments");
b.Navigation("Settings");
b.Navigation("UserStores");
});
modelBuilder.Entity("BTCPayServer.Data.WalletData", b =>
{
b.Navigation("WalletTransactions");
});
modelBuilder.Entity("BTCPayServer.Data.WebhookData", b =>
{
b.Navigation("Deliveries");
});
#pragma warning restore 612, 618
}
}

View File

@ -1,22 +1,16 @@
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using NBitcoin.Crypto;
using NBitcoin.DataEncoders;
using NBitcoin.Secp256k1;
namespace BTCPayServer.PluginPacker
{
class Program
{
static async Task Main(string[] args)
static void Main(string[] args)
{
if (args.Length < 3)
{
@ -25,7 +19,7 @@ namespace BTCPayServer.PluginPacker
}
var directory = args[0];
var name = args[1];
var outputDir = Path.Combine(args[2], name);
var outputDir = args[2];
var outputFile = Path.Combine(outputDir, name);
var rootDLLPath = Path.Combine(directory, name + ".dll");
if (!File.Exists(rootDLLPath))
@ -43,68 +37,15 @@ namespace BTCPayServer.PluginPacker
var loadedPlugin = (IBTCPayServerPlugin)Activator.CreateInstance(extension);
var json = JsonSerializer.Serialize(loadedPlugin);
Directory.CreateDirectory(outputDir);
outputDir = Path.Combine(outputDir, loadedPlugin.Version.ToString());
Directory.CreateDirectory(outputDir);
outputFile = Path.Combine(outputDir, name);
if (File.Exists(outputFile + ".btcpay"))
{
File.Delete(outputFile + ".btcpay");
}
ZipFile.CreateFromDirectory(directory, outputFile + ".btcpay", CompressionLevel.Optimal, false);
await File.WriteAllTextAsync(outputFile + ".btcpay.json", json);
var sha256sums = new StringBuilder();
sha256sums.AppendLine(
$"{Encoders.Hex.EncodeData(Hashes.SHA256(Encoding.UTF8.GetBytes(json)))} {name}.btcpay.json");
sha256sums.AppendLine(
$"{Encoders.Hex.EncodeData(Hashes.SHA256(await File.ReadAllBytesAsync(outputFile + ".btcpay")))} {name}.btcpay");
var sha256dirs = Path.Combine(outputDir, "SHA256SUMS");
if (File.Exists(sha256dirs))
{
File.Delete(sha256dirs);
}
await File.WriteAllTextAsync(sha256dirs, sha256sums.ToString());
// try Windows executable first, fall back to macOS/Linux PowerShell
try
{
await CreateShasums("powershell.exe", sha256dirs, outputDir);
}
catch (Exception)
{
try
{
await CreateShasums("bash", sha256dirs, outputDir);
}
catch (Exception ex)
{
Console.WriteLine(
$"Attempted to sign hashes with gpg but maybe powershell is not installed?\n{ex.Message}");
}
}
File.WriteAllText(outputFile + ".btcpay.json", json);
Console.WriteLine($"Created {outputFile}.btcpay at {directory}");
}
private static async Task CreateShasums(string exec, string sha256dirs, string outputDir)
{
Process cmd = new();
cmd.StartInfo.FileName = exec;
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
await cmd.StandardInput.WriteLineAsync($"cat {sha256dirs} | gpg -s > {Path.Combine(outputDir, "SHA256SUMS.asc")}");
await cmd.StandardInput.FlushAsync();
cmd.StandardInput.Close();
await cmd.WaitForExitAsync();
Console.WriteLine(await cmd.StandardOutput.ReadToEndAsync());
}
private static Type[] GetAllExtensionTypesFromAssembly(Assembly assembly)
{
return assembly.GetTypes().Where(type =>

View File

@ -19,7 +19,6 @@ namespace BTCPayServer.Plugins.Test
{
services.AddSingleton<IUIExtension>(new UIExtension("TestExtensionNavExtension", "header-nav"));
services.AddHostedService<ApplicationPartsLogger>();
services.AddHostedService<TestPluginMigrationRunner>();
services.AddSingleton<TestPluginService>();
services.AddSingleton<TestPluginDbContextFactory>();
services.AddDbContext<TestPluginDbContext>((provider, o) =>
@ -28,5 +27,13 @@ namespace BTCPayServer.Plugins.Test
factory.ConfigureBuilder(o);
});
}
public override void Execute(IApplicationBuilder applicationBuilder, IServiceProvider applicationBuilderApplicationServices)
{
base.Execute(applicationBuilder, applicationBuilderApplicationServices);
applicationBuilderApplicationServices.GetService<TestPluginDbContextFactory>().CreateContext().Database.Migrate();
applicationBuilderApplicationServices.GetService<TestPluginService>().AddTestDataRecord().GetAwaiter().GetResult();
}
}
}

View File

@ -1,45 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Plugins.Test.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
namespace BTCPayServer.Plugins.Test;
public class TestPluginMigrationRunner:IHostedService
{
public class TestPluginDataMigrationHistory
{
public bool UpdatedSomething { get; set; }
}
private readonly TestPluginDbContextFactory _testPluginDbContextFactory;
private readonly ISettingsRepository _settingsRepository;
private readonly TestPluginService _testPluginService;
public TestPluginMigrationRunner(TestPluginDbContextFactory testPluginDbContextFactory, ISettingsRepository settingsRepository, TestPluginService testPluginService)
{
_testPluginDbContextFactory = testPluginDbContextFactory;
_settingsRepository = settingsRepository;
_testPluginService = testPluginService;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
var settings = await _settingsRepository.GetSettingAsync<TestPluginDataMigrationHistory>() ??
new TestPluginDataMigrationHistory();
await using var ctx = _testPluginDbContextFactory.CreateContext();
await ctx.Database.MigrateAsync(cancellationToken: cancellationToken);
if (!settings.UpdatedSomething)
{
await _testPluginService.AddTestDataRecord();
settings.UpdatedSomething = true;
await _settingsRepository.UpdateSetting(settings);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}

View File

@ -8,7 +8,7 @@
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="NBitcoin" Version="7.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="1.0.2" />
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.6.3" />
</ItemGroup>
<ItemGroup>

Some files were not shown because too many files have changed in this diff Show More