Merge remote-tracking branch 'source/master' into dev-lndrpc

This commit is contained in:
rockstardev 2018-06-25 22:31:42 -05:00
commit 9a5259510b
23 changed files with 118 additions and 73 deletions

View file

@ -5,6 +5,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn> <NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
<LangVersion>7.2</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View file

@ -321,7 +321,7 @@ namespace BTCPayServer.Tests
[Fact] [Fact]
public void RoundupCurrenciesCorrectly() public void RoundupCurrenciesCorrectly()
{ {
foreach(var test in new[] foreach (var test in new[]
{ {
(0.0005m, "$0.0005 (USD)"), (0.0005m, "$0.0005 (USD)"),
(0.001m, "$0.001 (USD)"), (0.001m, "$0.001 (USD)"),

View file

@ -111,7 +111,7 @@ services:
- "bitcoin_datadir:/data" - "bitcoin_datadir:/data"
customer_lightningd: customer_lightningd:
image: nicolasdorier/clightning:0.0.0.20-dev image: nicolasdorier/clightning:0.0.0.21-dev
environment: environment:
EXPOSE_TCP: "true" EXPOSE_TCP: "true"
LIGHTNINGD_OPT: | LIGHTNINGD_OPT: |
@ -153,7 +153,7 @@ services:
- merchant_lightningd - merchant_lightningd
merchant_lightningd: merchant_lightningd:
image: nicolasdorier/clightning:0.0.0.20-dev image: nicolasdorier/clightning:0.0.0.21-dev
environment: environment:
EXPOSE_TCP: "true" EXPOSE_TCP: "true"
LIGHTNINGD_OPT: | LIGHTNINGD_OPT: |

View file

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NBitcoin;
namespace BTCPayServer
{
public partial class BTCPayNetworkProvider
{
public void InitGroestlcoin()
{
var nbxplorerNetwork = NBXplorerNetworkProvider.GetFromCryptoCode("GRS");
Add(new BTCPayNetwork()
{
CryptoCode = nbxplorerNetwork.CryptoCode,
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://chainz.cryptoid.info/grs/tx.dws?{0}.htm" : "https://chainz.cryptoid.info/grs-test/tx.dws?{0}.htm",
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
NBXplorerNetwork = nbxplorerNetwork,
UriScheme = "groestlcoin",
DefaultRateRules = new[]
{
"GRS_X = GRS_BTC * BTC_X",
"GRS_BTC = bittrex(GRS_BTC)"
},
CryptoImagePath = "imlegacy/groestlcoin.png",
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("17'") : new KeyPath("1'")
});
}
}
}

View file

@ -52,6 +52,7 @@ namespace BTCPayServer
InitMonacoin(); InitMonacoin();
InitPolis(); InitPolis();
InitFeathercoin(); InitFeathercoin();
InitGroestlcoin();
InitUfo(); InitUfo();
} }

View file

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
<Version>1.0.2.34</Version> <Version>1.0.2.36</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn> <NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -40,10 +40,10 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" /> <PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" /> <PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
<PackageReference Include="NBitcoin" Version="4.1.1.10" /> <PackageReference Include="NBitcoin" Version="4.1.1.18" />
<PackageReference Include="NBitpayClient" Version="1.0.0.28" /> <PackageReference Include="NBitpayClient" Version="1.0.0.29" />
<PackageReference Include="DBreeze" Version="1.87.0" /> <PackageReference Include="DBreeze" Version="1.87.0" />
<PackageReference Include="NBXplorer.Client" Version="1.0.2.10" /> <PackageReference Include="NBXplorer.Client" Version="1.0.2.11" />
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.2" /> <PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.2" />
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" /> <PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.14" /> <PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.14" />

View file

@ -78,7 +78,7 @@ namespace BTCPayServer.Controllers
var wallet = _WalletProvider.GetWallet(network); var wallet = _WalletProvider.GetWallet(network);
if (wallet == null) if (wallet == null)
return NotFound(); return NotFound();
var payment = PaymentMessage.Load(Request.Body); var payment = PaymentMessage.Load(Request.Body, network.NBitcoinNetwork);
var unused = wallet.BroadcastTransactionsAsync(payment.Transactions); var unused = wallet.BroadcastTransactionsAsync(payment.Transactions);
await _InvoiceRepository.AddRefundsAsync(invoiceId, payment.RefundTo.Select(p => new TxOut(p.Amount, p.Script)).ToArray(), network.NBitcoinNetwork); await _InvoiceRepository.AddRefundsAsync(invoiceId, payment.RefundTo.Select(p => new TxOut(p.Amount, p.Script)).ToArray(), network.NBitcoinNetwork);
return new PaymentAckActionResult(payment.CreateACK(invoiceId + " is currently processing, thanks for your purchase...")); return new PaymentAckActionResult(payment.CreateACK(invoiceId + " is currently processing, thanks for your purchase..."));

View file

@ -356,7 +356,7 @@ namespace BTCPayServer.Controllers
{ {
leases.Add(_EventAggregator.Subscribe<Events.InvoiceDataChangedEvent>(async o => await NotifySocket(webSocket, o.InvoiceId, invoiceId))); leases.Add(_EventAggregator.Subscribe<Events.InvoiceDataChangedEvent>(async o => await NotifySocket(webSocket, o.InvoiceId, invoiceId)));
leases.Add(_EventAggregator.Subscribe<Events.InvoiceNewAddressEvent>(async o => await NotifySocket(webSocket, o.InvoiceId, invoiceId))); leases.Add(_EventAggregator.Subscribe<Events.InvoiceNewAddressEvent>(async o => await NotifySocket(webSocket, o.InvoiceId, invoiceId)));
leases.Add(_EventAggregator.Subscribe<Events.InvoiceEvent>(async o => await NotifySocket(webSocket, o.InvoiceId, invoiceId))); leases.Add(_EventAggregator.Subscribe<Events.InvoiceEvent>(async o => await NotifySocket(webSocket, o.Invoice.Id, invoiceId)));
while (true) while (true)
{ {
var message = await webSocket.ReceiveAsync(DummyBuffer, default(CancellationToken)); var message = await webSocket.ReceiveAsync(DummyBuffer, default(CancellationToken));
@ -535,8 +535,11 @@ namespace BTCPayServer.Controllers
[BitpayAPIConstraint(false)] [BitpayAPIConstraint(false)]
public async Task<IActionResult> InvalidatePaidInvoice(string invoiceId) public async Task<IActionResult> InvalidatePaidInvoice(string invoiceId)
{ {
var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId);
if (invoice == null)
return NotFound();
await _InvoiceRepository.UpdatePaidInvoiceToInvalid(invoiceId); await _InvoiceRepository.UpdatePaidInvoiceToInvalid(invoiceId);
_EventAggregator.Publish(new InvoiceEvent(invoiceId, 1008, "invoice_markedInvalid")); _EventAggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1008, "invoice_markedInvalid"));
return RedirectToAction(nameof(ListInvoices)); return RedirectToAction(nameof(ListInvoices));
} }

View file

@ -144,32 +144,26 @@ namespace BTCPayServer.Controllers
PaymentMethod: CreatePaymentMethodAsync(fetchingByCurrencyPair, o.Handler, o.SupportedPaymentMethod, o.Network, entity, store))) PaymentMethod: CreatePaymentMethodAsync(fetchingByCurrencyPair, o.Handler, o.SupportedPaymentMethod, o.Network, entity, store)))
.ToList(); .ToList();
List<string> paymentMethodErrors = new List<string>(); List<string> invoiceLogs = new List<string>();
List<ISupportedPaymentMethod> supported = new List<ISupportedPaymentMethod>(); List<ISupportedPaymentMethod> supported = new List<ISupportedPaymentMethod>();
var paymentMethods = new PaymentMethodDictionary(); var paymentMethods = new PaymentMethodDictionary();
foreach(var pair in fetchingByCurrencyPair) foreach (var pair in fetchingByCurrencyPair)
{ {
var rateResult = await pair.Value; var rateResult = await pair.Value;
bool hasError = false; invoiceLogs.Add($"{pair.Key}: The rating rule is {rateResult.Rule}");
if(rateResult.Errors.Count != 0) invoiceLogs.Add($"{pair.Key}: The evaluated rating rule is {rateResult.EvaluatedRule}");
if (rateResult.Errors.Count != 0)
{ {
var allRateRuleErrors = string.Join(", ", rateResult.Errors.ToArray()); var allRateRuleErrors = string.Join(", ", rateResult.Errors.ToArray());
paymentMethodErrors.Add($"{pair.Key}: Rate rule error ({allRateRuleErrors})"); invoiceLogs.Add($"{pair.Key}: Rate rule error ({allRateRuleErrors})");
hasError = true;
} }
if(rateResult.ExchangeExceptions.Count != 0) if (rateResult.ExchangeExceptions.Count != 0)
{ {
foreach(var ex in rateResult.ExchangeExceptions) foreach (var ex in rateResult.ExchangeExceptions)
{ {
paymentMethodErrors.Add($"{pair.Key}: Exception reaching exchange {ex.ExchangeName} ({ex.Exception.Message})"); invoiceLogs.Add($"{pair.Key}: Exception reaching exchange {ex.ExchangeName} ({ex.Exception.Message})");
} }
hasError = true;
}
if(hasError)
{
paymentMethodErrors.Add($"{pair.Key}: The rule is {rateResult.Rule}");
paymentMethodErrors.Add($"{pair.Key}: Evaluated rule is {rateResult.EvaluatedRule}");
} }
} }
@ -185,11 +179,11 @@ namespace BTCPayServer.Controllers
} }
catch (PaymentMethodUnavailableException ex) catch (PaymentMethodUnavailableException ex)
{ {
paymentMethodErrors.Add($"{o.SupportedPaymentMethod.PaymentId.CryptoCode} ({o.SupportedPaymentMethod.PaymentId.PaymentType}): Payment method unavailable ({ex.Message})"); invoiceLogs.Add($"{o.SupportedPaymentMethod.PaymentId.CryptoCode} ({o.SupportedPaymentMethod.PaymentId.PaymentType}): Payment method unavailable ({ex.Message})");
} }
catch (Exception ex) catch (Exception ex)
{ {
paymentMethodErrors.Add($"{o.SupportedPaymentMethod.PaymentId.CryptoCode} ({o.SupportedPaymentMethod.PaymentId.PaymentType}): Unexpected exception ({ex.ToString()})"); invoiceLogs.Add($"{o.SupportedPaymentMethod.PaymentId.CryptoCode} ({o.SupportedPaymentMethod.PaymentId.PaymentType}): Unexpected exception ({ex.ToString()})");
} }
} }
@ -197,7 +191,7 @@ namespace BTCPayServer.Controllers
{ {
StringBuilder errors = new StringBuilder(); StringBuilder errors = new StringBuilder();
errors.AppendLine("No payment method available for this store"); errors.AppendLine("No payment method available for this store");
foreach (var error in paymentMethodErrors) foreach (var error in invoiceLogs)
{ {
errors.AppendLine(error); errors.AppendLine(error);
} }
@ -207,9 +201,9 @@ namespace BTCPayServer.Controllers
entity.SetSupportedPaymentMethods(supported); entity.SetSupportedPaymentMethods(supported);
entity.SetPaymentMethods(paymentMethods); entity.SetPaymentMethods(paymentMethods);
entity.PosData = invoice.PosData; entity.PosData = invoice.PosData;
entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity, paymentMethodErrors, _NetworkProvider); entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity, invoiceLogs, _NetworkProvider);
_EventAggregator.Publish(new Events.InvoiceEvent(entity, 1001, "invoice_created")); _EventAggregator.Publish(new Events.InvoiceEvent(entity.EntityToDTO(_NetworkProvider), 1001, "invoice_created"));
var resp = entity.EntityToDTO(_NetworkProvider); var resp = entity.EntityToDTO(_NetworkProvider);
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" }; return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
} }

View file

@ -313,7 +313,7 @@ namespace BTCPayServer.Controllers
Action = "Continue", Action = "Continue",
Title = "Rate rule scripting", Title = "Rate rule scripting",
Description = scripting ? Description = scripting ?
"This action will mofify your current rate sources. Are you sure to turn on rate rules scripting? (Advanced users)" "This action will modify your current rate sources. Are you sure to turn on rate rules scripting? (Advanced users)"
: "This action will delete your rate script. Are you sure to turn off rate rules scripting?", : "This action will delete your rate script. Are you sure to turn off rate rules scripting?",
ButtonClass = "btn-primary" ButtonClass = "btn-primary"
}); });

View file

@ -72,7 +72,7 @@ namespace BTCPayServer
} }
try try
{ {
var data = Encoders.Base58Check.DecodeData(parts[i]); var data = Network.GetBase58CheckEncoder().DecodeData(parts[i]);
if (data.Length < 4) if (data.Length < 4)
continue; continue;
var prefix = Utils.ToUInt32(data, false); var prefix = Utils.ToUInt32(data, false);
@ -80,7 +80,7 @@ namespace BTCPayServer
for (int ii = 0; ii < 4; ii++) for (int ii = 0; ii < 4; ii++)
data[ii] = standardPrefix[ii]; data[ii] = standardPrefix[ii];
var derivationScheme = new BitcoinExtPubKey(Encoders.Base58Check.EncodeData(data), Network).ToString(); var derivationScheme = new BitcoinExtPubKey(Network.GetBase58CheckEncoder().EncodeData(data), Network).ToString();
electrumMapping.TryGetValue(prefix, out string[] labels); electrumMapping.TryGetValue(prefix, out string[] labels);
if (labels != null) if (labels != null)
{ {

View file

@ -8,24 +8,20 @@ namespace BTCPayServer.Events
{ {
public class InvoiceEvent public class InvoiceEvent
{ {
public InvoiceEvent(InvoiceEntity invoice, int code, string name) : this(invoice.Id, code, name) public InvoiceEvent(Models.InvoiceResponse invoice, int code, string name)
{ {
Invoice = invoice;
}
public InvoiceEvent(string invoiceId, int code, string name)
{
InvoiceId = invoiceId;
EventCode = code; EventCode = code;
Name = name; Name = name;
} }
public string InvoiceId { get; set; } public Models.InvoiceResponse Invoice { get; set; }
public int EventCode { get; set; } public int EventCode { get; set; }
public string Name { get; set; } public string Name { get; set; }
public override string ToString() public override string ToString()
{ {
return $"Invoice {InvoiceId} new event: {Name} ({EventCode})"; return $"Invoice {Invoice.Id} new event: {Name} ({EventCode})";
} }
} }
} }

View file

@ -308,7 +308,7 @@ namespace BTCPayServer.HostedServices
{ {
leases.Add(_EventAggregator.Subscribe<InvoiceEvent>(async e => leases.Add(_EventAggregator.Subscribe<InvoiceEvent>(async e =>
{ {
var invoice = await _InvoiceRepository.GetInvoice(null, e.InvoiceId); var invoice = await _InvoiceRepository.GetInvoice(null, e.Invoice.Id);
List<Task> tasks = new List<Task>(); List<Task> tasks = new List<Task>();
// Awaiting this later help make sure invoices should arrive in order // Awaiting this later help make sure invoices should arrive in order

View file

@ -66,10 +66,10 @@ namespace BTCPayServer.HostedServices
context.MarkDirty(); context.MarkDirty();
await _InvoiceRepository.UnaffectAddress(invoice.Id); await _InvoiceRepository.UnaffectAddress(invoice.Id);
context.Events.Add(new InvoiceEvent(invoice, 1004, "invoice_expired")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1004, "invoice_expired"));
invoice.Status = "expired"; invoice.Status = "expired";
if(invoice.ExceptionStatus == "paidPartial") if(invoice.ExceptionStatus == "paidPartial")
context.Events.Add(new InvoiceEvent(invoice, 2000, "invoice_expiredPaidPartial")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 2000, "invoice_expiredPaidPartial"));
} }
var payments = invoice.GetPayments().Where(p => p.Accounted).ToArray(); var payments = invoice.GetPayments().Where(p => p.Accounted).ToArray();
@ -84,7 +84,7 @@ namespace BTCPayServer.HostedServices
{ {
if (invoice.Status == "new") if (invoice.Status == "new")
{ {
context.Events.Add(new InvoiceEvent(invoice, 1003, "invoice_paidInFull")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1003, "invoice_paidInFull"));
invoice.Status = "paid"; invoice.Status = "paid";
invoice.ExceptionStatus = accounting.Paid > accounting.TotalDue ? "paidOver" : null; invoice.ExceptionStatus = accounting.Paid > accounting.TotalDue ? "paidOver" : null;
await _InvoiceRepository.UnaffectAddress(invoice.Id); await _InvoiceRepository.UnaffectAddress(invoice.Id);
@ -93,7 +93,7 @@ namespace BTCPayServer.HostedServices
else if (invoice.Status == "expired" && invoice.ExceptionStatus != "paidLate") else if (invoice.Status == "expired" && invoice.ExceptionStatus != "paidLate")
{ {
invoice.ExceptionStatus = "paidLate"; invoice.ExceptionStatus = "paidLate";
context.Events.Add(new InvoiceEvent(invoice, 1009, "invoice_paidAfterExpiration")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1009, "invoice_paidAfterExpiration"));
context.MarkDirty(); context.MarkDirty();
} }
} }
@ -139,14 +139,14 @@ namespace BTCPayServer.HostedServices
(confirmedAccounting.Paid < accounting.MinimumTotalDue)) (confirmedAccounting.Paid < accounting.MinimumTotalDue))
{ {
await _InvoiceRepository.UnaffectAddress(invoice.Id); await _InvoiceRepository.UnaffectAddress(invoice.Id);
context.Events.Add(new InvoiceEvent(invoice, 1013, "invoice_failedToConfirm")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1013, "invoice_failedToConfirm"));
invoice.Status = "invalid"; invoice.Status = "invalid";
context.MarkDirty(); context.MarkDirty();
} }
else if (confirmedAccounting.Paid >= accounting.MinimumTotalDue) else if (confirmedAccounting.Paid >= accounting.MinimumTotalDue)
{ {
await _InvoiceRepository.UnaffectAddress(invoice.Id); await _InvoiceRepository.UnaffectAddress(invoice.Id);
context.Events.Add(new InvoiceEvent(invoice, 1005, "invoice_confirmed")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1005, "invoice_confirmed"));
invoice.Status = "confirmed"; invoice.Status = "confirmed";
context.MarkDirty(); context.MarkDirty();
} }
@ -157,7 +157,7 @@ namespace BTCPayServer.HostedServices
var completedAccounting = paymentMethod.Calculate(p => p.GetCryptoPaymentData().PaymentCompleted(p, network)); var completedAccounting = paymentMethod.Calculate(p => p.GetCryptoPaymentData().PaymentCompleted(p, network));
if (completedAccounting.Paid >= accounting.MinimumTotalDue) if (completedAccounting.Paid >= accounting.MinimumTotalDue)
{ {
context.Events.Add(new InvoiceEvent(invoice, 1006, "invoice_completed")); context.Events.Add(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1006, "invoice_completed"));
invoice.Status = "complete"; invoice.Status = "complete";
context.MarkDirty(); context.MarkDirty();
} }
@ -249,13 +249,13 @@ namespace BTCPayServer.HostedServices
{ {
if (b.Name == "invoice_created") if (b.Name == "invoice_created")
{ {
Watch(b.InvoiceId); Watch(b.Invoice.Id);
await Wait(b.InvoiceId); await Wait(b.Invoice.Id);
} }
if (b.Name == "invoice_receivedPayment") if (b.Name == "invoice_receivedPayment")
{ {
Watch(b.InvoiceId); Watch(b.Invoice.Id);
} }
})); }));
return Task.CompletedTask; return Task.CompletedTask;

View file

@ -161,7 +161,7 @@ namespace BTCPayServer.Payments.Bitcoin
{ {
var payment = await _InvoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, paymentData, network.CryptoCode); var payment = await _InvoiceRepository.AddPayment(invoice.Id, DateTimeOffset.UtcNow, paymentData, network.CryptoCode);
if(payment != null) if(payment != null)
await ReceivedPayment(wallet, invoice.Id, payment, evt.DerivationStrategy); await ReceivedPayment(wallet, invoice, payment, evt.DerivationStrategy);
} }
else else
{ {
@ -332,7 +332,7 @@ namespace BTCPayServer.Payments.Bitcoin
var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin.Timestamp, paymentData, network.CryptoCode).ConfigureAwait(false); var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin.Timestamp, paymentData, network.CryptoCode).ConfigureAwait(false);
alreadyAccounted.Add(coin.Coin.Outpoint); alreadyAccounted.Add(coin.Coin.Outpoint);
if (payment != null) if (payment != null)
invoice = await ReceivedPayment(wallet, invoice.Id, payment, strategy); invoice = await ReceivedPayment(wallet, invoice, payment, strategy);
totalPayment++; totalPayment++;
} }
} }
@ -346,10 +346,10 @@ namespace BTCPayServer.Payments.Bitcoin
.FirstOrDefault(); .FirstOrDefault();
} }
private async Task<InvoiceEntity> ReceivedPayment(BTCPayWallet wallet, string invoiceId, PaymentEntity payment, DerivationStrategyBase strategy) private async Task<InvoiceEntity> ReceivedPayment(BTCPayWallet wallet, InvoiceEntity invoice, PaymentEntity payment, DerivationStrategyBase strategy)
{ {
var paymentData = (BitcoinLikePaymentData)payment.GetCryptoPaymentData(); var paymentData = (BitcoinLikePaymentData)payment.GetCryptoPaymentData();
var invoice = (await UpdatePaymentStates(wallet, invoiceId)); invoice = (await UpdatePaymentStates(wallet, invoice.Id));
var paymentMethod = invoice.GetPaymentMethod(wallet.Network, PaymentTypes.BTCLike, _ExplorerClients.NetworkProviders); var paymentMethod = invoice.GetPaymentMethod(wallet.Network, PaymentTypes.BTCLike, _ExplorerClients.NetworkProviders);
if (paymentMethod != null && if (paymentMethod != null &&
paymentMethod.GetPaymentMethodDetails() is BitcoinLikeOnChainPaymentMethod btc && paymentMethod.GetPaymentMethodDetails() is BitcoinLikeOnChainPaymentMethod btc &&
@ -358,13 +358,13 @@ namespace BTCPayServer.Payments.Bitcoin
{ {
var address = await wallet.ReserveAddressAsync(strategy); var address = await wallet.ReserveAddressAsync(strategy);
btc.DepositAddress = address.ToString(); btc.DepositAddress = address.ToString();
await _InvoiceRepository.NewAddress(invoiceId, btc, wallet.Network); await _InvoiceRepository.NewAddress(invoice.Id, btc, wallet.Network);
_Aggregator.Publish(new InvoiceNewAddressEvent(invoiceId, address.ToString(), wallet.Network)); _Aggregator.Publish(new InvoiceNewAddressEvent(invoice.Id, address.ToString(), wallet.Network));
paymentMethod.SetPaymentMethodDetails(btc); paymentMethod.SetPaymentMethodDetails(btc);
invoice.SetPaymentMethod(paymentMethod); invoice.SetPaymentMethod(paymentMethod);
} }
wallet.InvalidateCache(strategy); wallet.InvalidateCache(strategy);
_Aggregator.Publish(new InvoiceEvent(invoiceId, 1002, "invoice_receivedPayment")); _Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, "invoice_receivedPayment"));
return invoice; return invoice;
} }
public Task StopAsync(CancellationToken cancellationToken) public Task StopAsync(CancellationToken cancellationToken)

View file

@ -46,7 +46,7 @@ namespace BTCPayServer.Payments.Lightning
{ {
if (inv.Name == "invoice_created") if (inv.Name == "invoice_created")
{ {
await EnsureListening(inv.InvoiceId, false); await EnsureListening(inv.Invoice.Id, false);
} }
})); }));
@ -189,8 +189,12 @@ namespace BTCPayServer.Payments.Lightning
BOLT11 = notification.BOLT11, BOLT11 = notification.BOLT11,
Amount = notification.Amount Amount = notification.Amount
}, network.CryptoCode, accounted: true); }, network.CryptoCode, accounted: true);
if(payment != null) if (payment != null)
_Aggregator.Publish(new InvoiceEvent(listenedInvoice.InvoiceId, 1002, "invoice_receivedPayment")); {
var invoice = await _InvoiceRepository.GetInvoice(null, listenedInvoice.InvoiceId);
if(invoice != null)
_Aggregator.Publish(new InvoiceEvent(invoice.EntityToDTO(_NetworkProvider), 1002, "invoice_receivedPayment"));
}
} }
List<Task> _ListeningLightning = new List<Task>(); List<Task> _ListeningLightning = new List<Task>();

View file

@ -10,8 +10,8 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p> <p>
Some of your nodes are still synching...<br /> Some of your nodes are still synchronizing...<br />
BTCPay Server will not work correctly until it is over. BTCPay Server will not create invoices with those cryptocurrencies.
</p> </p>
@foreach (var line in dashboard.GetAll()) @foreach (var line in dashboard.GetAll())
{ {
@ -47,12 +47,12 @@
} }
else if (line.Status.BitcoinStatus.IsSynched) else if (line.Status.BitcoinStatus.IsSynched)
{ {
<li>The node is synched (Height: @line.Status.BitcoinStatus.Headers)</li> <li>The node is synchronized (Height: @line.Status.BitcoinStatus.Headers)</li>
@if (line.Status.BitcoinStatus.IsSynched && @if (line.Status.BitcoinStatus.IsSynched &&
line.Status.SyncHeight.HasValue && line.Status.SyncHeight.HasValue &&
line.Status.SyncHeight.Value < line.Status.BitcoinStatus.Headers) line.Status.SyncHeight.Value < line.Status.BitcoinStatus.Headers)
{ {
<li>NBXplorer is synching... (Height: @line.Status.SyncHeight.Value)</li> <li>NBXplorer is synchronizing... (Height: @line.Status.SyncHeight.Value)</li>
} }
} }
else else

View file

@ -17,7 +17,7 @@
If your Ledger wallet is not detected: If your Ledger wallet is not detected:
</p> </p>
<ul> <ul>
<li>Make sure you are running the Ledger Bitcoin or Litecoin app with version superior or equal to 1.2.4</li> <li>Make sure you are running the Ledger app with version superior or equal to 1.2.4</li>
<li>Use a browser supporting the <a href="https://www.yubico.com/support/knowledge-base/categories/articles/browsers-support-u2f/">U2F protocol</a></li> <li>Use a browser supporting the <a href="https://www.yubico.com/support/knowledge-base/categories/articles/browsers-support-u2f/">U2F protocol</a></li>
</ul> </ul>
<p id="hw-loading"><span class="fa fa-question-circle" style="color:orange"></span> <span>Detecting hardware wallet...</span></p> <p id="hw-loading"><span class="fa fa-question-circle" style="color:orange"></span> <span>Detecting hardware wallet...</span></p>

View file

@ -35,8 +35,8 @@ const locales_de = {
"What happened?": "Was ist passiert?", "What happened?": "Was ist passiert?",
"InvoiceExpired_Body_1": "Diese Rechnung ist abgelaufen. Eine Rechnung ist nur für {{maxTimeMinutes}} Minuten gültig. \ "InvoiceExpired_Body_1": "Diese Rechnung ist abgelaufen. Eine Rechnung ist nur für {{maxTimeMinutes}} Minuten gültig. \
Sie können zu {{storeName}} zurückkehren, wenn Sie Ihre Zahlung erneut senden möchten.", Sie können zu {{storeName}} zurückkehren, wenn Sie Ihre Zahlung erneut senden möchten.",
"InvoiceExpired_Body_2": "Wenn Sie versucht haben, eine Zahlung zu senden, wurde sie vom Bitcoin-Netzwerk noch nicht akzeptiert. Wir haben Ihre Gelder noch nicht erhalten.", "InvoiceExpired_Body_2": "Wenn Sie versucht haben, eine Zahlung zu senden, wurde sie vom Netzwerk noch nicht akzeptiert. Wir haben Ihre Gelder noch nicht erhalten.",
"InvoiceExpired_Body_3": "Wenn die Transaktion vom Bitcoin-Netzwerk nicht akzeptiert wird, ist das Geld wieder in Ihrer Wallet verfügbar. Abhängig von Ihrer Wallet, kann dies 48-72 Stunden dauern.", "InvoiceExpired_Body_3": "Wenn die Transaktion vom Netzwerk nicht akzeptiert wird, ist das Geld wieder in Ihrer Wallet verfügbar. Abhängig von Ihrer Wallet, kann dies 48-72 Stunden dauern.",
"Invoice ID": "Rechnungs ID", "Invoice ID": "Rechnungs ID",
"Order ID": "Auftrag ID", "Order ID": "Auftrag ID",
"Return to StoreName": "Zurück zu {{storeName}}", "Return to StoreName": "Zurück zu {{storeName}}",

View file

@ -35,8 +35,8 @@ const locales_en = {
"What happened?": "What happened?", "What happened?": "What happened?",
"InvoiceExpired_Body_1": "This invoice has expired. An invoice is only valid for {{maxTimeMinutes}} minutes. \ "InvoiceExpired_Body_1": "This invoice has expired. An invoice is only valid for {{maxTimeMinutes}} minutes. \
You can return to {{storeName}} if you would like to submit your payment again.", You can return to {{storeName}} if you would like to submit your payment again.",
"InvoiceExpired_Body_2": "If you tried to send a payment, it has not yet been accepted by the Bitcoin network. We have not yet received your funds.", "InvoiceExpired_Body_2": "If you tried to send a payment, it has not yet been accepted by the network. We have not yet received your funds.",
"InvoiceExpired_Body_3": "If the transaction is not accepted by the Bitcoin network, the funds will be spendable again in your wallet. Depending on your wallet, this may take 48-72 hours.", "InvoiceExpired_Body_3": "If the transaction is not accepted by the network, the funds will be spendable again in your wallet. Depending on your wallet, this may take 48-72 hours.",
"Invoice ID": "Invoice ID", "Invoice ID": "Invoice ID",
"Order ID": "Order ID", "Order ID": "Order ID",
"Return to StoreName": "Return to {{storeName}}", "Return to StoreName": "Return to {{storeName}}",

View file

@ -26,7 +26,7 @@ const locales_is = {
"Copied": "Afritað", "Copied": "Afritað",
// Conversion tab // Conversion tab
"ConversionTab_BodyTop": "Þú getur borgað {{btcDue}} {{cryptoCode}} með altcoins.", "ConversionTab_BodyTop": "Þú getur borgað {{btcDue}} {{cryptoCode}} með altcoins.",
"ConversionTab_BodyDesc": "Þessi þjónusta er veitt af þriðja aðila. Mundu að við höfum ekki stjórn á því hvað þeir gera við peningana. Reikningurinn verður aðeins móttekinn þegar {{cryptoCode}} greiðslan hefur verið staðfest á Bitcoin netinu.", "ConversionTab_BodyDesc": "Þessi þjónusta er veitt af þriðja aðila. Mundu að við höfum ekki stjórn á því hvað þeir gera við peningana. Reikningurinn verður aðeins móttekinn þegar {{cryptoCode}} greiðslan hefur verið staðfest á netinu.",
"Shapeshift_Button_Text": "Borga með Altcoins", "Shapeshift_Button_Text": "Borga með Altcoins",
"ConversionTab_Lightning": "Engir viðskiptaveitendur eru í boði fyrir Lightning Network greiðslur.", "ConversionTab_Lightning": "Engir viðskiptaveitendur eru í boði fyrir Lightning Network greiðslur.",
// Invoice expired // Invoice expired
@ -36,7 +36,7 @@ const locales_is = {
"InvoiceExpired_Body_1": "Þessi reikningur er útrunnin. Reikningurinn er aðeins gildur í {{maxTimeMinutes}} mínútur. \ "InvoiceExpired_Body_1": "Þessi reikningur er útrunnin. Reikningurinn er aðeins gildur í {{maxTimeMinutes}} mínútur. \
Þú getur farið aftur á {{storeName}} ef þú vilt reyna aftur.", Þú getur farið aftur á {{storeName}} ef þú vilt reyna aftur.",
"InvoiceExpired_Body_2": "Ef þú reyndir að senda greiðslu, þá hefur hún ekki verið samþykkt.", "InvoiceExpired_Body_2": "Ef þú reyndir að senda greiðslu, þá hefur hún ekki verið samþykkt.",
"InvoiceExpired_Body_3": "Ef viðskiptin eru ekki samþykkt af Bitcoin netinu verða fjármunirnir aðgengilegar aftur í veskinu þínu. Það fer eftir veskinu þínu og getur tekið 48-72 klukkustundir.", "InvoiceExpired_Body_3": "Ef viðskiptin eru ekki samþykkt af netinu verða fjármunirnir aðgengilegar aftur í veskinu þínu. Það fer eftir veskinu þínu og getur tekið 48-72 klukkustundir.",
"Invoice ID": "Innheimtu ID", "Invoice ID": "Innheimtu ID",
"Order ID": "Pöntun ID", "Order ID": "Pöntun ID",
"Return to StoreName": "Fara aftur á {{storeName}}", "Return to StoreName": "Fara aftur á {{storeName}}",

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View file

@ -20,6 +20,19 @@ This solution is for you if:
* You want to become a payment processor yourself and offer a BTCPay hosted solution to merchants * You want to become a payment processor yourself and offer a BTCPay hosted solution to merchants
* You want a way to support currencies other than those offered by Bitpay * You want a way to support currencies other than those offered by Bitpay
## We support altcoins!
In addition to Bitcoin, we support the following crypto currencies:
* BGold
* Dogecoin
* Feathercoin
* Groestlcoin
* Litecoin
* Monacoin
* Polis
* UFO
## Documentation ## Documentation
Please check out our [complete documentation](https://github.com/btcpayserver/btcpayserver-doc) for more details. Please check out our [complete documentation](https://github.com/btcpayserver/btcpayserver-doc) for more details.