mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Refactoring to prepare multiple DerivationSchemes per store and invoices
This commit is contained in:
parent
2f9afda0ab
commit
781b2885cc
18 changed files with 724 additions and 63 deletions
|
@ -12,5 +12,16 @@ namespace BTCPayServer
|
||||||
public string CryptoCode { get; internal set; }
|
public string CryptoCode { get; internal set; }
|
||||||
public string BlockExplorerLink { get; internal set; }
|
public string BlockExplorerLink { get; internal set; }
|
||||||
public string UriScheme { get; internal set; }
|
public string UriScheme { get; internal set; }
|
||||||
|
|
||||||
|
|
||||||
|
[Obsolete("Should not be needed")]
|
||||||
|
public bool IsBTC
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return CryptoCode == "BTC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace BTCPayServer
|
||||||
Dictionary<string, BTCPayNetwork> _Networks = new Dictionary<string, BTCPayNetwork>();
|
Dictionary<string, BTCPayNetwork> _Networks = new Dictionary<string, BTCPayNetwork>();
|
||||||
public BTCPayNetworkProvider(Network network)
|
public BTCPayNetworkProvider(Network network)
|
||||||
{
|
{
|
||||||
if(network == Network.Main)
|
if (network == Network.Main)
|
||||||
{
|
{
|
||||||
Add(new BTCPayNetwork()
|
Add(new BTCPayNetwork()
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,15 @@ namespace BTCPayServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Should not be needed")]
|
||||||
|
public BTCPayNetwork BTC
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetNetwork("BTC");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(BTCPayNetwork network)
|
public void Add(BTCPayNetwork network)
|
||||||
{
|
{
|
||||||
_Networks.Add(network.CryptoCode, network);
|
_Networks.Add(network.CryptoCode, network);
|
||||||
|
|
|
@ -325,7 +325,7 @@ namespace BTCPayServer.Controllers
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
var store = await _StoreRepository.FindStore(model.StoreId, GetUserId());
|
var store = await _StoreRepository.FindStore(model.StoreId, GetUserId());
|
||||||
if (string.IsNullOrEmpty(store.DerivationStrategy))
|
if (store.GetDerivationStrategies(_NetworkProvider).Count() == 0)
|
||||||
{
|
{
|
||||||
StatusMessage = "Error: You need to configure the derivation scheme in order to create an invoice";
|
StatusMessage = "Error: You need to configure the derivation scheme in order to create an invoice";
|
||||||
return RedirectToAction(nameof(StoresController.UpdateStore), "Stores", new
|
return RedirectToAction(nameof(StoresController.UpdateStore), "Stores", new
|
||||||
|
|
|
@ -82,12 +82,15 @@ namespace BTCPayServer.Controllers
|
||||||
|
|
||||||
internal async Task<DataWrapper<InvoiceResponse>> CreateInvoiceCore(Invoice invoice, StoreData store, string serverUrl, double expiryMinutes = 15)
|
internal async Task<DataWrapper<InvoiceResponse>> CreateInvoiceCore(Invoice invoice, StoreData store, string serverUrl, double expiryMinutes = 15)
|
||||||
{
|
{
|
||||||
var derivationStrategy = store.DerivationStrategy;
|
var derivationStrategies = store.GetDerivationStrategies(_NetworkProvider).ToList();
|
||||||
|
if (derivationStrategies.Count == 0)
|
||||||
|
throw new BitpayHttpException(400, "This store has not configured the derivation strategy");
|
||||||
var entity = new InvoiceEntity
|
var entity = new InvoiceEntity
|
||||||
{
|
{
|
||||||
InvoiceTime = DateTimeOffset.UtcNow,
|
InvoiceTime = DateTimeOffset.UtcNow
|
||||||
DerivationStrategy = derivationStrategy ?? throw new BitpayHttpException(400, "This store has not configured the derivation strategy")
|
|
||||||
};
|
};
|
||||||
|
entity.SetDerivationStrategies(derivationStrategies);
|
||||||
|
|
||||||
var storeBlob = store.GetStoreBlob();
|
var storeBlob = store.GetStoreBlob();
|
||||||
Uri notificationUri = Uri.IsWellFormedUriString(invoice.NotificationURL, UriKind.Absolute) ? new Uri(invoice.NotificationURL, UriKind.Absolute) : null;
|
Uri notificationUri = Uri.IsWellFormedUriString(invoice.NotificationURL, UriKind.Absolute) ? new Uri(invoice.NotificationURL, UriKind.Absolute) : null;
|
||||||
if (notificationUri == null || (notificationUri.Scheme != "http" && notificationUri.Scheme != "https")) //TODO: Filer non routable addresses ?
|
if (notificationUri == null || (notificationUri.Scheme != "http" && notificationUri.Scheme != "https")) //TODO: Filer non routable addresses ?
|
||||||
|
@ -113,17 +116,15 @@ namespace BTCPayServer.Controllers
|
||||||
entity.Status = "new";
|
entity.Status = "new";
|
||||||
entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy);
|
entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy);
|
||||||
|
|
||||||
var queries = storeBlob.GetSupportedCryptoCurrencies()
|
var queries = derivationStrategies
|
||||||
.Select(n => _NetworkProvider.GetNetwork(n))
|
.Select(derivationStrategy =>
|
||||||
.Where(n => n != null)
|
|
||||||
.Select(network =>
|
|
||||||
{
|
{
|
||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
network = network,
|
network = derivationStrategy.Network,
|
||||||
getFeeRate = _FeeProviderFactory.CreateFeeProvider(network).GetFeeRateAsync(),
|
getFeeRate = _FeeProviderFactory.CreateFeeProvider(derivationStrategy.Network).GetFeeRateAsync(),
|
||||||
getRate = _RateProvider.GetRateAsync(invoice.Currency),
|
getRate = _RateProvider.GetRateAsync(invoice.Currency),
|
||||||
getAddress = _Wallet.ReserveAddressAsync(ParseDerivationStrategy(derivationStrategy, network))
|
getAddress = _Wallet.ReserveAddressAsync(derivationStrategy)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ namespace BTCPayServer.Controllers
|
||||||
cryptoData.DepositAddress = (await q.getAddress).ToString();
|
cryptoData.DepositAddress = (await q.getAddress).ToString();
|
||||||
|
|
||||||
#pragma warning disable CS0618
|
#pragma warning disable CS0618
|
||||||
if (q.network.CryptoCode == "BTC")
|
if (q.network.IsBTC)
|
||||||
{
|
{
|
||||||
entity.TxFee = cryptoData.TxFee;
|
entity.TxFee = cryptoData.TxFee;
|
||||||
entity.Rate = cryptoData.Rate;
|
entity.Rate = cryptoData.Rate;
|
||||||
|
|
|
@ -43,10 +43,11 @@ namespace BTCPayServer.Controllers
|
||||||
_TokenController = tokenController;
|
_TokenController = tokenController;
|
||||||
_Wallet = wallet;
|
_Wallet = wallet;
|
||||||
_Env = env;
|
_Env = env;
|
||||||
_Network = networkProvider.GetNetwork("BTC").NBitcoinNetwork;
|
_NetworkProvider = networkProvider;
|
||||||
_CallbackController = callbackController;
|
_CallbackController = callbackController;
|
||||||
}
|
}
|
||||||
Network _Network;
|
BTCPayNetworkProvider _NetworkProvider;
|
||||||
|
|
||||||
CallbackController _CallbackController;
|
CallbackController _CallbackController;
|
||||||
BTCPayWallet _Wallet;
|
BTCPayWallet _Wallet;
|
||||||
AccessTokenController _TokenController;
|
AccessTokenController _TokenController;
|
||||||
|
@ -93,8 +94,12 @@ namespace BTCPayServer.Controllers
|
||||||
StoresViewModel result = new StoresViewModel();
|
StoresViewModel result = new StoresViewModel();
|
||||||
result.StatusMessage = StatusMessage;
|
result.StatusMessage = StatusMessage;
|
||||||
var stores = await _Repo.GetStoresByUserId(GetUserId());
|
var stores = await _Repo.GetStoresByUserId(GetUserId());
|
||||||
var balances = stores.Select(async s => string.IsNullOrEmpty(s.DerivationStrategy) ? Money.Zero : await _Wallet.GetBalance(ParseDerivationStrategy(s.DerivationStrategy, null))).ToArray();
|
var balances = stores
|
||||||
|
.Select(s => s.GetDerivationStrategies(_NetworkProvider)
|
||||||
|
.Select(async ss => (await _Wallet.GetBalance(ss)).ToString() + " " + ss.Network.CryptoCode))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
await Task.WhenAll(balances.SelectMany(_ => _));
|
||||||
for (int i = 0; i < stores.Length; i++)
|
for (int i = 0; i < stores.Length; i++)
|
||||||
{
|
{
|
||||||
var store = stores[i];
|
var store = stores[i];
|
||||||
|
@ -103,7 +108,7 @@ namespace BTCPayServer.Controllers
|
||||||
Id = store.Id,
|
Id = store.Id,
|
||||||
Name = store.StoreName,
|
Name = store.StoreName,
|
||||||
WebSite = store.StoreWebsite,
|
WebSite = store.StoreWebsite,
|
||||||
Balance = await balances[i]
|
Balances = balances[i].Select(t => t.Result).ToArray()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return View(result);
|
return View(result);
|
||||||
|
@ -196,9 +201,9 @@ namespace BTCPayServer.Controllers
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(model.DerivationScheme))
|
if (!string.IsNullOrEmpty(model.DerivationScheme))
|
||||||
{
|
{
|
||||||
var strategy = ParseDerivationStrategy(model.DerivationScheme, model.DerivationSchemeFormat);
|
var strategy = ParseDerivationStrategy(model.DerivationScheme, model.DerivationSchemeFormat, _NetworkProvider.BTC);
|
||||||
await _Wallet.TrackAsync(strategy);
|
await _Wallet.TrackAsync(strategy);
|
||||||
await _CallbackController.RegisterCallbackUriAsync(strategy);
|
await _CallbackController.RegisterCallbackUriAsync(strategy.DerivationStrategyBase);
|
||||||
model.DerivationScheme = strategy.ToString();
|
model.DerivationScheme = strategy.ToString();
|
||||||
}
|
}
|
||||||
store.DerivationStrategy = model.DerivationScheme;
|
store.DerivationStrategy = model.DerivationScheme;
|
||||||
|
@ -236,13 +241,13 @@ namespace BTCPayServer.Controllers
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var scheme = ParseDerivationStrategy(model.DerivationScheme, model.DerivationSchemeFormat);
|
var scheme = ParseDerivationStrategy(model.DerivationScheme, model.DerivationSchemeFormat, _NetworkProvider.BTC);
|
||||||
var line = scheme.GetLineFor(DerivationFeature.Deposit);
|
var line = scheme.DerivationStrategyBase.GetLineFor(DerivationFeature.Deposit);
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
var address = line.Derive((uint)i);
|
var address = line.Derive((uint)i);
|
||||||
model.AddressSamples.Add((line.Path.Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(_Network).ToString()));
|
model.AddressSamples.Add((line.Path.Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(scheme.Network.NBitcoinNetwork).ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -254,7 +259,7 @@ namespace BTCPayServer.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DerivationStrategyBase ParseDerivationStrategy(string derivationScheme, string format)
|
private DerivationStrategy ParseDerivationStrategy(string derivationScheme, string format, BTCPayNetwork network)
|
||||||
{
|
{
|
||||||
if (format == "Electrum")
|
if (format == "Electrum")
|
||||||
{
|
{
|
||||||
|
@ -276,19 +281,19 @@ namespace BTCPayServer.Controllers
|
||||||
var prefix = Utils.ToUInt32(data, false);
|
var prefix = Utils.ToUInt32(data, false);
|
||||||
if (!electrumMapping.TryGetValue(prefix, out string[] labels))
|
if (!electrumMapping.TryGetValue(prefix, out string[] labels))
|
||||||
throw new FormatException("!electrumMapping.TryGetValue(prefix, out string[] labels)");
|
throw new FormatException("!electrumMapping.TryGetValue(prefix, out string[] labels)");
|
||||||
var standardPrefix = Utils.ToBytes(_Network == Network.Main ? 0x0488b21eU : 0x043587cf, false);
|
var standardPrefix = Utils.ToBytes(network.NBitcoinNetwork == Network.Main ? 0x0488b21eU : 0x043587cf, false);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
data[i] = standardPrefix[i];
|
data[i] = standardPrefix[i];
|
||||||
|
|
||||||
derivationScheme = new BitcoinExtPubKey(Encoders.Base58Check.EncodeData(data), _Network).ToString();
|
derivationScheme = new BitcoinExtPubKey(Encoders.Base58Check.EncodeData(data), network.NBitcoinNetwork).ToString();
|
||||||
foreach (var label in labels)
|
foreach (var label in labels)
|
||||||
{
|
{
|
||||||
derivationScheme = derivationScheme + $"-[{label}]";
|
derivationScheme = derivationScheme + $"-[{label}]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DerivationStrategyFactory(_Network).Parse(derivationScheme);
|
return DerivationStrategy.Parse(new DerivationStrategyFactory(network.NBitcoinNetwork).Parse(derivationScheme).ToString(), network);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
|
|
@ -10,6 +10,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Data
|
namespace BTCPayServer.Data
|
||||||
{
|
{
|
||||||
|
@ -26,11 +27,50 @@ namespace BTCPayServer.Data
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use GetDerivationStrategies instead")]
|
||||||
public string DerivationStrategy
|
public string DerivationStrategy
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use GetDerivationStrategies instead")]
|
||||||
|
public string DerivationStrategies
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<DerivationStrategy> GetDerivationStrategies(BTCPayNetworkProvider networks)
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
bool btcReturned = false;
|
||||||
|
if (!string.IsNullOrEmpty(DerivationStrategy))
|
||||||
|
{
|
||||||
|
if (networks.BTC != null)
|
||||||
|
{
|
||||||
|
btcReturned = true;
|
||||||
|
yield return BTCPayServer.DerivationStrategy.Parse(DerivationStrategy, networks.BTC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(DerivationStrategies))
|
||||||
|
{
|
||||||
|
JObject strategies = JObject.Parse(DerivationStrategies);
|
||||||
|
foreach (var strat in strategies.Properties())
|
||||||
|
{
|
||||||
|
var network = networks.GetNetwork(strat.Name);
|
||||||
|
if (network != null)
|
||||||
|
{
|
||||||
|
if (network == networks.BTC && btcReturned)
|
||||||
|
continue;
|
||||||
|
yield return BTCPayServer.DerivationStrategy.Parse(strat.Value<string>(), network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
}
|
||||||
|
|
||||||
public string StoreName
|
public string StoreName
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
|
@ -97,19 +137,5 @@ namespace BTCPayServer.Data
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use GetSupportedCryptoCurrencies() instead")]
|
|
||||||
public string[] SupportedCryptoCurrencies { get; set; }
|
|
||||||
|
|
||||||
public string[] GetSupportedCryptoCurrencies()
|
|
||||||
{
|
|
||||||
#pragma warning disable CS0618
|
|
||||||
if(SupportedCryptoCurrencies == null)
|
|
||||||
{
|
|
||||||
return new string[] { "BTC" };
|
|
||||||
}
|
|
||||||
return SupportedCryptoCurrencies;
|
|
||||||
#pragma warning restore CS0618
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
BTCPayServer/DerivationStrategy.cs
Normal file
40
BTCPayServer/DerivationStrategy.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NBitcoin;
|
||||||
|
using NBXplorer.DerivationStrategy;
|
||||||
|
|
||||||
|
namespace BTCPayServer
|
||||||
|
{
|
||||||
|
public class DerivationStrategy
|
||||||
|
{
|
||||||
|
private DerivationStrategyBase _DerivationStrategy;
|
||||||
|
private BTCPayNetwork _Network;
|
||||||
|
|
||||||
|
DerivationStrategy(DerivationStrategyBase result, BTCPayNetwork network)
|
||||||
|
{
|
||||||
|
this._DerivationStrategy = result;
|
||||||
|
this._Network = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DerivationStrategy Parse(string derivationStrategy, BTCPayNetwork network)
|
||||||
|
{
|
||||||
|
if (network == null)
|
||||||
|
throw new ArgumentNullException(nameof(network));
|
||||||
|
if (derivationStrategy == null)
|
||||||
|
throw new ArgumentNullException(nameof(derivationStrategy));
|
||||||
|
var result = new NBXplorer.DerivationStrategy.DerivationStrategyFactory(network.NBitcoinNetwork).Parse(derivationStrategy);
|
||||||
|
return new DerivationStrategy(result, network);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BTCPayNetwork Network { get { return this._Network; } }
|
||||||
|
|
||||||
|
public DerivationStrategyBase DerivationStrategyBase { get { return this._DerivationStrategy; } }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return _DerivationStrategy.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,11 @@ namespace BTCPayServer
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
|
public static bool SupportDropColumn(this Microsoft.EntityFrameworkCore.Migrations.Migration migration, string activeProvider)
|
||||||
|
{
|
||||||
|
return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite";
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<Dictionary<uint256, TransactionResult>> GetTransactions(this ExplorerClient client, uint256[] hashes, CancellationToken cts = default(CancellationToken))
|
public static async Task<Dictionary<uint256, TransactionResult>> GetTransactions(this ExplorerClient client, uint256[] hashes, CancellationToken cts = default(CancellationToken))
|
||||||
{
|
{
|
||||||
hashes = hashes.Distinct().ToArray();
|
hashes = hashes.Distinct().ToArray();
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace BTCPayServer.Migrations
|
||||||
{
|
{
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
if (SupportDropColumn(migrationBuilder.ActiveProvider))
|
if (this.SupportDropColumn(migrationBuilder.ActiveProvider))
|
||||||
{
|
{
|
||||||
migrationBuilder.DropColumn(
|
migrationBuilder.DropColumn(
|
||||||
name: "Name",
|
name: "Name",
|
||||||
|
@ -30,11 +30,6 @@ namespace BTCPayServer.Migrations
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SupportDropColumn(string activeProvider)
|
|
||||||
{
|
|
||||||
return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
|
|
483
BTCPayServer/Migrations/20180106095215_DerivationStrategies.Designer.cs
generated
Normal file
483
BTCPayServer/Migrations/20180106095215_DerivationStrategies.Designer.cs
generated
Normal file
|
@ -0,0 +1,483 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using BTCPayServer.Data;
|
||||||
|
using BTCPayServer.Services.Invoices;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20180106095215_DerivationStrategies")]
|
||||||
|
partial class DerivationStrategies
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.0.1-rtm-125");
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("CreatedTime");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Address");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("AddressInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.Property<string>("Address");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Assigned");
|
||||||
|
|
||||||
|
b.Property<string>("CryptoCode");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("UnAssigned");
|
||||||
|
|
||||||
|
b.HasKey("InvoiceDataId", "Address");
|
||||||
|
|
||||||
|
b.ToTable("HistoricalAddressInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Created");
|
||||||
|
|
||||||
|
b.Property<string>("CustomerEmail");
|
||||||
|
|
||||||
|
b.Property<string>("ExceptionStatus");
|
||||||
|
|
||||||
|
b.Property<string>("ItemCode");
|
||||||
|
|
||||||
|
b.Property<string>("OrderId");
|
||||||
|
|
||||||
|
b.Property<string>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("StoreDataId");
|
||||||
|
|
||||||
|
b.ToTable("Invoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Facade");
|
||||||
|
|
||||||
|
b.Property<string>("Label");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("PairingTime");
|
||||||
|
|
||||||
|
b.Property<string>("SIN");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SIN");
|
||||||
|
|
||||||
|
b.HasIndex("StoreDataId");
|
||||||
|
|
||||||
|
b.ToTable("PairedSINData");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PairingCodeData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateCreated");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Expiration");
|
||||||
|
|
||||||
|
b.Property<string>("Facade");
|
||||||
|
|
||||||
|
b.Property<string>("Label");
|
||||||
|
|
||||||
|
b.Property<string>("SIN");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.Property<string>("TokenValue");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PairingCodes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Accounted");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("Payments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PendingInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<byte[]>("Blob");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceDataId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceDataId");
|
||||||
|
|
||||||
|
b.ToTable("RefundAddresses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.SettingData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.StoreData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("DerivationStrategies");
|
||||||
|
|
||||||
|
b.Property<string>("DerivationStrategy");
|
||||||
|
|
||||||
|
b.Property<int>("SpeedPolicy");
|
||||||
|
|
||||||
|
b.Property<byte[]>("StoreBlob");
|
||||||
|
|
||||||
|
b.Property<byte[]>("StoreCertificate");
|
||||||
|
|
||||||
|
b.Property<string>("StoreName");
|
||||||
|
|
||||||
|
b.Property<string>("StoreWebsite");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Stores");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("ApplicationUserId");
|
||||||
|
|
||||||
|
b.Property<string>("StoreDataId");
|
||||||
|
|
||||||
|
b.Property<string>("Role");
|
||||||
|
|
||||||
|
b.HasKey("ApplicationUserId", "StoreDataId");
|
||||||
|
|
||||||
|
b.HasIndex("StoreDataId");
|
||||||
|
|
||||||
|
b.ToTable("UserStore");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Models.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed");
|
||||||
|
|
||||||
|
b.Property<bool>("RequiresEmailConfirmation");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken();
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256);
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("Value");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany("AddressInvoices")
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData")
|
||||||
|
.WithMany("HistoricalAddressInvoices")
|
||||||
|
.HasForeignKey("InvoiceDataId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StoreDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany("Payments")
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||||
|
.WithMany("RefundAddresses")
|
||||||
|
.HasForeignKey("InvoiceDataId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser", "ApplicationUser")
|
||||||
|
.WithMany("UserStores")
|
||||||
|
.HasForeignKey("ApplicationUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||||
|
.WithMany("UserStores")
|
||||||
|
.HasForeignKey("StoreDataId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Migrations
|
||||||
|
{
|
||||||
|
public partial class DerivationStrategies : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "DerivationStrategies",
|
||||||
|
table: "Stores",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "DerivationStrategies",
|
||||||
|
table: "Stores");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -190,6 +190,8 @@ namespace BTCPayServer.Migrations
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
.ValueGeneratedOnAdd();
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("DerivationStrategies");
|
||||||
|
|
||||||
b.Property<string>("DerivationStrategy");
|
b.Property<string>("DerivationStrategy");
|
||||||
|
|
||||||
b.Property<int>("SpeedPolicy");
|
b.Property<int>("SpeedPolicy");
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
public Money Balance
|
public string[] Balances
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,11 +153,64 @@ namespace BTCPayServer.Services.Invoices
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use GetDerivationStrategies instead")]
|
||||||
public string DerivationStrategy
|
public string DerivationStrategy
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use GetDerivationStrategies instead")]
|
||||||
|
public string DerivationStrategies
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<DerivationStrategy> GetDerivationStrategies(BTCPayNetworkProvider networks)
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
bool btcReturned = false;
|
||||||
|
if (!string.IsNullOrEmpty(DerivationStrategies))
|
||||||
|
{
|
||||||
|
JObject strategies = JObject.Parse(DerivationStrategies);
|
||||||
|
foreach (var strat in strategies.Properties())
|
||||||
|
{
|
||||||
|
var network = networks.GetNetwork(strat.Name);
|
||||||
|
if (network != null)
|
||||||
|
{
|
||||||
|
if (network == networks.BTC && btcReturned)
|
||||||
|
btcReturned = true;
|
||||||
|
yield return BTCPayServer.DerivationStrategy.Parse(strat.Value.Value<string>(), network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!btcReturned && !string.IsNullOrEmpty(DerivationStrategy))
|
||||||
|
{
|
||||||
|
if (networks.BTC != null)
|
||||||
|
{
|
||||||
|
yield return BTCPayServer.DerivationStrategy.Parse(DerivationStrategy, networks.BTC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetDerivationStrategies(IEnumerable<DerivationStrategy> derivationStrategies)
|
||||||
|
{
|
||||||
|
JObject obj = new JObject();
|
||||||
|
foreach(var strat in derivationStrategies)
|
||||||
|
{
|
||||||
|
obj.Add(strat.Network.CryptoCode, new JValue(strat.DerivationStrategyBase.ToString()));
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
if (strat.Network.IsBTC)
|
||||||
|
DerivationStrategy = strat.DerivationStrategyBase.ToString();
|
||||||
|
}
|
||||||
|
DerivationStrategies = JsonConvert.SerializeObject(obj);
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
}
|
||||||
|
|
||||||
public string Status
|
public string Status
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -424,7 +477,7 @@ namespace BTCPayServer.Services.Invoices
|
||||||
public Money TxFee { get; set; }
|
public Money TxFee { get; set; }
|
||||||
[JsonProperty(PropertyName = "depositAddress")]
|
[JsonProperty(PropertyName = "depositAddress")]
|
||||||
public string DepositAddress { get; set; }
|
public string DepositAddress { get; set; }
|
||||||
|
|
||||||
public CryptoDataAccounting Calculate()
|
public CryptoDataAccounting Calculate()
|
||||||
{
|
{
|
||||||
var cryptoData = ParentEntity.GetCryptoData();
|
var cryptoData = ParentEntity.GetCryptoData();
|
||||||
|
@ -464,7 +517,7 @@ namespace BTCPayServer.Services.Invoices
|
||||||
accounting.NetworkFee = TxFee * txCount;
|
accounting.NetworkFee = TxFee * txCount;
|
||||||
return accounting;
|
return accounting;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AccountedPaymentEntity
|
public class AccountedPaymentEntity
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace BTCPayServer.Services.Invoices
|
||||||
currencyData.DepositAddress = bitcoinAddress.ToString();
|
currencyData.DepositAddress = bitcoinAddress.ToString();
|
||||||
|
|
||||||
#pragma warning disable CS0618
|
#pragma warning disable CS0618
|
||||||
if (network.CryptoCode == "BTC")
|
if (network.IsBTC)
|
||||||
{
|
{
|
||||||
invoiceEntity.DepositAddress = currencyData.DepositAddress;
|
invoiceEntity.DepositAddress = currencyData.DepositAddress;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace BTCPayServer.Services.Invoices
|
||||||
{
|
{
|
||||||
InvoiceRepository _InvoiceRepository;
|
InvoiceRepository _InvoiceRepository;
|
||||||
ExplorerClient _ExplorerClient;
|
ExplorerClient _ExplorerClient;
|
||||||
DerivationStrategyFactory _DerivationFactory;
|
|
||||||
EventAggregator _EventAggregator;
|
EventAggregator _EventAggregator;
|
||||||
BTCPayWallet _Wallet;
|
BTCPayWallet _Wallet;
|
||||||
BTCPayNetworkProvider _NetworkProvider;
|
BTCPayNetworkProvider _NetworkProvider;
|
||||||
|
@ -42,7 +41,6 @@ namespace BTCPayServer.Services.Invoices
|
||||||
PollInterval = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0);
|
PollInterval = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0);
|
||||||
_Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet));
|
_Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet));
|
||||||
_ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
|
_ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient));
|
||||||
_DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network);
|
|
||||||
_InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
|
_InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository));
|
||||||
_EventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
_EventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
||||||
_NetworkProvider = networkProvider;
|
_NetworkProvider = networkProvider;
|
||||||
|
@ -125,8 +123,8 @@ namespace BTCPayServer.Services.Invoices
|
||||||
{
|
{
|
||||||
bool needSave = false;
|
bool needSave = false;
|
||||||
//Fetch unknown payments
|
//Fetch unknown payments
|
||||||
var strategy = _DerivationFactory.Parse(invoice.DerivationStrategy);
|
var strategy = invoice.GetDerivationStrategies(_NetworkProvider).First(s => s.Network.IsBTC);
|
||||||
changes = await _ExplorerClient.SyncAsync(strategy, changes, !LongPollingMode, _Cts.Token).ConfigureAwait(false);
|
changes = await _ExplorerClient.SyncAsync(strategy.DerivationStrategyBase, changes, !LongPollingMode, _Cts.Token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
var utxos = changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs).ToArray();
|
var utxos = changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs).ToArray();
|
||||||
|
@ -192,7 +190,7 @@ namespace BTCPayServer.Services.Invoices
|
||||||
needSave = true;
|
needSave = true;
|
||||||
if (dirtyAddress)
|
if (dirtyAddress)
|
||||||
{
|
{
|
||||||
var address = await _Wallet.ReserveAddressAsync(_DerivationFactory.Parse(invoice.DerivationStrategy));
|
var address = await _Wallet.ReserveAddressAsync(strategy);
|
||||||
Logs.PayServer.LogInformation("Generate new " + address);
|
Logs.PayServer.LogInformation("Generate new " + address);
|
||||||
await _InvoiceRepository.NewAddress(invoice.Id, address, network);
|
await _InvoiceRepository.NewAddress(invoice.Id, address, network);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,15 +28,15 @@ namespace BTCPayServer.Services.Wallets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<BitcoinAddress> ReserveAddressAsync(DerivationStrategyBase derivationStrategy)
|
public async Task<BitcoinAddress> ReserveAddressAsync(DerivationStrategy derivationStrategy)
|
||||||
{
|
{
|
||||||
var pathInfo = await _Client.GetUnusedAsync(derivationStrategy, DerivationFeature.Deposit, 0, true).ConfigureAwait(false);
|
var pathInfo = await _Client.GetUnusedAsync(derivationStrategy.DerivationStrategyBase, DerivationFeature.Deposit, 0, true).ConfigureAwait(false);
|
||||||
return pathInfo.ScriptPubKey.GetDestinationAddress(_Client.Network);
|
return pathInfo.ScriptPubKey.GetDestinationAddress(_Client.Network);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task TrackAsync(DerivationStrategyBase derivationStrategy)
|
public async Task TrackAsync(DerivationStrategy derivationStrategy)
|
||||||
{
|
{
|
||||||
await _Client.TrackAsync(derivationStrategy);
|
await _Client.TrackAsync(derivationStrategy.DerivationStrategyBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] ToBytes<T>(T obj)
|
private byte[] ToBytes<T>(T obj)
|
||||||
|
@ -50,9 +50,9 @@ namespace BTCPayServer.Services.Wallets
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Money> GetBalance(DerivationStrategyBase derivationStrategy)
|
public async Task<Money> GetBalance(DerivationStrategy derivationStrategy)
|
||||||
{
|
{
|
||||||
var result = await _Client.SyncAsync(derivationStrategy, null, true);
|
var result = await _Client.SyncAsync(derivationStrategy.DerivationStrategyBase, null, true);
|
||||||
return result.Confirmed.UTXOs.Select(u => u.Value)
|
return result.Confirmed.UTXOs.Select(u => u.Value)
|
||||||
.Concat(result.Unconfirmed.UTXOs.Select(u => u.Value))
|
.Concat(result.Unconfirmed.UTXOs.Select(u => u.Value))
|
||||||
.Sum();
|
.Sum();
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Website</th>
|
<th>Website</th>
|
||||||
<th>Balance</th>
|
<th>Balances</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -42,7 +42,16 @@
|
||||||
<a href="@store.WebSite">@store.WebSite</a>
|
<a href="@store.WebSite">@store.WebSite</a>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@store.Balance</td>
|
<td>
|
||||||
|
@for(int i = 0; i < store.Balances.Length; i++)
|
||||||
|
{
|
||||||
|
<span>@store.Balances[i]</span>
|
||||||
|
if(i != store.Balances.Length - 1)
|
||||||
|
{
|
||||||
|
<br />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</td>
|
||||||
<td><a asp-action="UpdateStore" asp-route-storeId="@store.Id">Settings</a> - <a asp-action="DeleteStore" asp-route-storeId="@store.Id">Remove</a></td>
|
<td><a asp-action="UpdateStore" asp-route-storeId="@store.Id">Settings</a> - <a asp-action="DeleteStore" asp-route-storeId="@store.Id">Remove</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue