Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
6d6b9e2ba6 | |||
fd915fdc5c | |||
59be813fe9 | |||
465fbdd47f | |||
f220abb716 |
@ -70,6 +70,7 @@ namespace BTCPayServer.Tests
|
||||
CryptoCurrency = cryptoCode,
|
||||
DerivationSchemeFormat = "BTCPay",
|
||||
DerivationScheme = DerivationScheme.ToString(),
|
||||
Confirmation = true
|
||||
}, "Save");
|
||||
return store;
|
||||
}
|
||||
@ -90,6 +91,7 @@ namespace BTCPayServer.Tests
|
||||
CryptoCurrency = crytoCode,
|
||||
DerivationSchemeFormat = crytoCode,
|
||||
DerivationScheme = derivation.ToString(),
|
||||
Confirmation = true
|
||||
}, "Save");
|
||||
}
|
||||
|
||||
|
@ -13,25 +13,27 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
// Unit test that generates temorary checkout Bitpay page
|
||||
// https://forkbitpay.slack.com/archives/C7M093Z55/p1508293682000217
|
||||
[Fact]
|
||||
public void BitpayCheckout()
|
||||
{
|
||||
var key = new Key(Encoders.Hex.DecodeData("7b70a06f35562873e3dcb46005ed0fe78e1991ad906e56adaaafa40ba861e056"));
|
||||
var url = new Uri("https://test.bitpay.com/");
|
||||
var btcpay = new Bitpay(key, url);
|
||||
var invoice = btcpay.CreateInvoice(new Invoice()
|
||||
{
|
||||
|
||||
Price = 5.0,
|
||||
Currency = "USD",
|
||||
PosData = "posData",
|
||||
OrderId = "cdfd8a5f-6928-4c3b-ba9b-ddf438029e73",
|
||||
ItemDesc = "Hello from the otherside"
|
||||
}, Facade.Merchant);
|
||||
// Testnet of Bitpay down
|
||||
//[Fact]
|
||||
//public void BitpayCheckout()
|
||||
//{
|
||||
// var key = new Key(Encoders.Hex.DecodeData("7b70a06f35562873e3dcb46005ed0fe78e1991ad906e56adaaafa40ba861e056"));
|
||||
// var url = new Uri("https://test.bitpay.com/");
|
||||
// var btcpay = new Bitpay(key, url);
|
||||
// var invoice = btcpay.CreateInvoice(new Invoice()
|
||||
// {
|
||||
|
||||
// go to invoice.Url
|
||||
Console.WriteLine(invoice.Url);
|
||||
}
|
||||
// Price = 5.0,
|
||||
// Currency = "USD",
|
||||
// PosData = "posData",
|
||||
// OrderId = "cdfd8a5f-6928-4c3b-ba9b-ddf438029e73",
|
||||
// ItemDesc = "Hello from the otherside"
|
||||
// }, Facade.Merchant);
|
||||
|
||||
// // go to invoice.Url
|
||||
// Console.WriteLine(invoice.Url);
|
||||
//}
|
||||
|
||||
// Generating Extended public key to use on http://localhost:14142/stores/{storeId}
|
||||
[Fact]
|
||||
|
@ -37,7 +37,7 @@ services:
|
||||
- postgres
|
||||
|
||||
nbxplorer:
|
||||
image: nicolasdorier/nbxplorer:1.0.1.10
|
||||
image: nicolasdorier/nbxplorer:1.0.1.11
|
||||
ports:
|
||||
- "32838:32838"
|
||||
expose:
|
||||
|
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Version>1.0.1.20</Version>
|
||||
<Version>1.0.1.21</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Build\dockerfiles\**" />
|
||||
|
@ -203,7 +203,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}/derivations")]
|
||||
public async Task<IActionResult> AddDerivationScheme(string storeId, DerivationSchemeViewModel vm, string command, string selectedScheme = null)
|
||||
public async Task<IActionResult> AddDerivationScheme(string storeId, DerivationSchemeViewModel vm, string selectedScheme = null)
|
||||
{
|
||||
selectedScheme = selectedScheme ?? "BTC";
|
||||
var store = await _Repo.FindStore(storeId, GetUserId());
|
||||
@ -224,16 +224,31 @@ namespace BTCPayServer.Controllers
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
if (command == "Save")
|
||||
|
||||
DerivationStrategyBase strategy = null;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(vm.DerivationScheme))
|
||||
{
|
||||
strategy = ParseDerivationStrategy(vm.DerivationScheme, vm.DerivationSchemeFormat, network);
|
||||
vm.DerivationScheme = strategy.ToString();
|
||||
}
|
||||
store.SetDerivationStrategy(network, vm.DerivationScheme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.DerivationScheme), "Invalid Derivation Scheme");
|
||||
vm.Confirmation = false;
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
|
||||
if (strategy == null || vm.Confirmation)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(vm.DerivationScheme))
|
||||
{
|
||||
var strategy = ParseDerivationStrategy(vm.DerivationScheme, vm.DerivationSchemeFormat, network);
|
||||
if (strategy != null)
|
||||
await wallet.TrackAsync(strategy);
|
||||
vm.DerivationScheme = strategy.ToString();
|
||||
}
|
||||
store.SetDerivationStrategy(network, vm.DerivationScheme);
|
||||
}
|
||||
catch
|
||||
@ -250,22 +265,15 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
if (!string.IsNullOrEmpty(vm.DerivationScheme))
|
||||
{
|
||||
try
|
||||
{
|
||||
var scheme = ParseDerivationStrategy(vm.DerivationScheme, vm.DerivationSchemeFormat, network);
|
||||
var line = scheme.GetLineFor(DerivationFeature.Deposit);
|
||||
var line = strategy.GetLineFor(DerivationFeature.Deposit);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var address = line.Derive((uint)i);
|
||||
vm.AddressSamples.Add((DerivationStrategyBase.GetKeyPath(DerivationFeature.Deposit).Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork).ToString()));
|
||||
}
|
||||
}
|
||||
catch
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.DerivationScheme), "Invalid Derivation Scheme");
|
||||
var address = line.Derive((uint)i);
|
||||
vm.AddressSamples.Add((DerivationStrategyBase.GetKeyPath(DerivationFeature.Deposit).Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork).ToString()));
|
||||
}
|
||||
}
|
||||
vm.Confirmation = true;
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
set;
|
||||
}
|
||||
|
||||
public bool Confirmation { get; set; }
|
||||
|
||||
public SelectList CryptoCurrencies { get; set; }
|
||||
public SelectList DerivationSchemeFormats { get; set; }
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
@ -72,24 +73,19 @@ namespace BTCPayServer.Services.Rates
|
||||
rates = (JObject)rates["symbols"];
|
||||
}
|
||||
return rates.Properties()
|
||||
.Where(p => p.Name.StartsWith(CryptoCode, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(p => p.Name.StartsWith(CryptoCode, StringComparison.OrdinalIgnoreCase) && TryToDecimal(p, out decimal unused))
|
||||
.ToDictionary(p => p.Name.Substring(CryptoCode.Length, p.Name.Length - CryptoCode.Length), p =>
|
||||
{
|
||||
if (Exchange == null)
|
||||
{
|
||||
return ToDecimal(p.Value["last"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ToDecimal(p.Value["bid"]);
|
||||
}
|
||||
TryToDecimal(p, out decimal v);
|
||||
return v;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private decimal ToDecimal(JToken token)
|
||||
private bool TryToDecimal(JProperty p, out decimal v)
|
||||
{
|
||||
return decimal.Parse(token.Value<string>(), System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowDecimalPoint);
|
||||
JToken token = p.Value[Exchange == null ? "last" : "bid"];
|
||||
return decimal.TryParse(token.Value<string>(), System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out v);
|
||||
}
|
||||
|
||||
public async Task<ICollection<Rate>> GetRatesAsync()
|
||||
|
@ -15,29 +15,26 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<h5>Derivation Scheme</h5>
|
||||
@if(Model.AddressSamples.Count == 0)
|
||||
{
|
||||
@if(!Model.Confirmation)
|
||||
{
|
||||
<div class="form-group">
|
||||
<h5>Derivation Scheme</h5>
|
||||
<span>The DerivationScheme represents the destination of the funds received by your invoice. It is generated by your wallet software. Please, verify that you are generating the right addresses by clicking on 'Check ExtPubKey'</span>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="CryptoCurrency"></label>
|
||||
<select asp-for="CryptoCurrency" asp-items="Model.CryptoCurrencies" class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="CryptoCurrency"></label>
|
||||
<select asp-for="CryptoCurrency" asp-items="Model.CryptoCurrencies" class="form-control"></select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input asp-for="DerivationScheme" class="form-control" />
|
||||
<span asp-validation-for="DerivationScheme" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="DerivationSchemeFormat"></label>
|
||||
<select asp-for="DerivationSchemeFormat" asp-items="Model.DerivationSchemeFormats" class="form-control"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@if(Model.AddressSamples.Count == 0)
|
||||
{
|
||||
<div class="form-group">
|
||||
<input asp-for="DerivationScheme" class="form-control" />
|
||||
<span asp-validation-for="DerivationScheme" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="DerivationSchemeFormat"></label>
|
||||
<select asp-for="DerivationSchemeFormat" asp-items="Model.DerivationSchemeFormats" class="form-control"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span>BTCPay format memo</span>
|
||||
<table class="table">
|
||||
<thead class="thead-inverse">
|
||||
@ -73,30 +70,39 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-info">Continue</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead class="thead-inverse">
|
||||
<div class="form-group">
|
||||
<h5>Confirm the addresses (@Model.CryptoCurrency)</h5>
|
||||
<span>Please check that your @Model.CryptoCurrency wallet is generating the same addresses as below.</span>
|
||||
</div>
|
||||
<input type="hidden" asp-for="CryptoCurrency" />
|
||||
<input type="hidden" asp-for="Confirmation" />
|
||||
<input type="hidden" asp-for="DerivationScheme" />
|
||||
<div class="form-group">
|
||||
<table class="table">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th>Key path</th>
|
||||
<th>Address</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach(var sample in Model.AddressSamples)
|
||||
{
|
||||
<tr>
|
||||
<th>Key path</th>
|
||||
<th>Address</th>
|
||||
<td>@sample.KeyPath</td>
|
||||
<td>@sample.Address</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach(var sample in Model.AddressSamples)
|
||||
{
|
||||
<tr>
|
||||
<td>@sample.KeyPath</td>
|
||||
<td>@sample.Address</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-success">Confirm</button>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
<button name="command" type="submit" class="btn btn-success" value="Save">Save</button>
|
||||
<button name="command" type="submit" class="btn btn-default" value="Check">Check ExtPubKey</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user