Improve wallet nav (#3921)

* Fix rescan nav highlighting

* Wallet send wizard

* Wallet receive wizard

* Consistent wizard back button behaviour
This commit is contained in:
d11n
2022-07-04 06:20:08 +02:00
committed by GitHub
parent f30ddbf175
commit 181d4d5ea4
23 changed files with 606 additions and 429 deletions

View File

@@ -31,6 +31,7 @@ using NBitcoin;
using BTCPayServer.Client.Models;
using BTCPayServer.Logging;
using BTCPayServer.Services.Wallets.Export;
using Microsoft.AspNetCore.Http;
using NBXplorer;
using NBXplorer.Client;
using NBXplorer.DerivationStrategy;
@@ -349,7 +350,8 @@ namespace BTCPayServer.Controllers
}
[HttpGet("{walletId}/receive")]
public IActionResult WalletReceive([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId)
public IActionResult WalletReceive([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
[FromQuery] string returnUrl = null)
{
if (walletId?.StoreId == null)
return NotFound();
@@ -369,26 +371,26 @@ namespace BTCPayServer.Controllers
Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint",
new { walletId.CryptoCode })));
}
return View(new WalletReceiveViewModel()
return View(new WalletReceiveViewModel
{
CryptoCode = walletId.CryptoCode,
Address = address?.ToString(),
CryptoImage = GetImage(paymentMethod.PaymentId, network),
PaymentLink = bip21.ToString()
PaymentLink = bip21.ToString(),
ReturnUrl = returnUrl ?? HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath
});
}
[HttpPost]
[Route("{walletId}/receive")]
[HttpPost("{walletId}/receive")]
public async Task<IActionResult> WalletReceive([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
WalletReceiveViewModel viewModel, string command)
WalletReceiveViewModel vm, string command)
{
if (walletId?.StoreId == null)
return NotFound();
DerivationSchemeSettings paymentMethod = GetDerivationSchemeSettings(walletId);
if (paymentMethod == null)
return NotFound();
var network = this.NetworkProvider.GetNetwork<BTCPayNetwork>(walletId?.CryptoCode);
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId?.CryptoCode);
if (network == null)
return NotFound();
switch (command)
@@ -397,7 +399,7 @@ namespace BTCPayServer.Controllers
var address = await _walletReceiveService.UnReserveAddress(walletId);
if (!string.IsNullOrEmpty(address))
{
TempData.SetStatusMessageModel(new StatusMessageModel()
TempData.SetStatusMessageModel(new StatusMessageModel
{
AllowDismiss = true,
Message = $"Address {address} was unreserved.",
@@ -414,7 +416,7 @@ namespace BTCPayServer.Controllers
await SendFreeMoney(cheater, walletId, paymentMethod);
break;
}
return RedirectToAction(nameof(WalletReceive), new { walletId });
return RedirectToAction(nameof(WalletReceive), new { walletId, returnUrl = vm.ReturnUrl });
}
private async Task SendFreeMoney(Cheater cheater, WalletId walletId, DerivationSchemeSettings paymentMethod)
@@ -458,8 +460,9 @@ namespace BTCPayServer.Controllers
[HttpGet("{walletId}/send")]
public async Task<IActionResult> WalletSend(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, string defaultDestination = null, string defaultAmount = null, string[] bip21 = null)
[ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
string defaultDestination = null, string defaultAmount = null, string[] bip21 = null,
[FromQuery] string returnUrl = null)
{
if (walletId?.StoreId == null)
return NotFound();
@@ -475,7 +478,12 @@ namespace BTCPayServer.Controllers
rateRules.Spread = 0.0m;
var currencyPair = new Rating.CurrencyPair(paymentMethod.PaymentId.CryptoCode, storeData.DefaultCurrency);
double.TryParse(defaultAmount, out var amount);
var model = new WalletSendModel() { CryptoCode = walletId.CryptoCode };
var model = new WalletSendModel
{
CryptoCode = walletId.CryptoCode,
ReturnUrl = returnUrl ?? HttpContext.Request.GetTypedHeaders().Referer?.AbsolutePath
};
if (bip21?.Any() is true)
{
foreach (var link in bip21)
@@ -590,6 +598,7 @@ namespace BTCPayServer.Controllers
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId?.CryptoCode);
if (network == null || network.ReadonlyWallet)
return NotFound();
vm.SupportRBF = network.SupportRBF;
vm.NBXSeedAvailable = await GetSeed(walletId, network) != null;
if (!string.IsNullOrEmpty(bip21))
@@ -857,7 +866,12 @@ namespace BTCPayServer.Controllers
switch (command)
{
case "sign":
return await WalletSign(walletId, new WalletPSBTViewModel() { SigningContext = signingContext });
return await WalletSign(walletId, new WalletPSBTViewModel
{
SigningContext = signingContext,
ReturnUrl = vm.ReturnUrl,
BackUrl = vm.BackUrl
});
case "analyze-psbt":
var name =
$"Send-{string.Join('_', vm.Outputs.Select(output => $"{output.Amount}->{output.DestinationAddress}{(output.SubtractFeesFromOutput ? "-Fees" : string.Empty)}"))}.psbt";
@@ -920,24 +934,30 @@ namespace BTCPayServer.Controllers
ModelState.Clear();
}
private IActionResult ViewVault(WalletId walletId, SigningContextModel signingContext)
private IActionResult ViewVault(WalletId walletId, WalletPSBTViewModel vm)
{
return View(nameof(WalletSendVault),
new WalletSendVaultModel()
new WalletSendVaultModel
{
SigningContext = signingContext,
SigningContext = vm.SigningContext,
WalletId = walletId.ToString(),
WebsocketPath = this.Url.Action(nameof(UIVaultController.VaultBridgeConnection), "UIVault",
new { walletId = walletId.ToString() })
WebsocketPath = Url.Action(nameof(UIVaultController.VaultBridgeConnection), "UIVault",
new { walletId = walletId.ToString() }),
ReturnUrl = vm.ReturnUrl,
BackUrl = vm.BackUrl
});
}
[HttpPost]
[Route("{walletId}/vault")]
[HttpPost("{walletId}/vault")]
public IActionResult WalletSendVault([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
WalletSendVaultModel model)
{
return RedirectToWalletPSBTReady(new WalletPSBTReadyViewModel() { SigningContext = model.SigningContext });
return RedirectToWalletPSBTReady(new WalletPSBTReadyViewModel
{
SigningContext = model.SigningContext,
ReturnUrl = model.ReturnUrl,
BackUrl = model.BackUrl
});
}
private IActionResult RedirectToWalletPSBTReady(WalletPSBTReadyViewModel vm)
@@ -962,9 +982,13 @@ namespace BTCPayServer.Controllers
redirectVm.FormParameters.Remove("command");
redirectVm.FormParameters.Add("command", "broadcast");
}
if (this.HttpContext.Request.Query["returnUrl"].FirstOrDefault() is string returnUrl)
if (vm.ReturnUrl != null)
{
redirectVm.RouteParameters.Add("returnUrl", returnUrl);
redirectVm.FormParameters.Add("returnUrl", vm.ReturnUrl);
}
if (vm.BackUrl != null)
{
redirectVm.FormParameters.Add("backUrl", vm.BackUrl);
}
return View("PostRedirect", redirectVm);
}
@@ -987,17 +1011,29 @@ namespace BTCPayServer.Controllers
{
AspController = "UIWallets",
AspAction = nameof(WalletPSBT),
RouteParameters = { { "walletId", this.RouteData?.Values["walletId"]?.ToString() } },
FormParameters = { { "psbt", vm.PSBT }, { "fileName", vm.FileName }, { "command", "decode" }, }
RouteParameters = { { "walletId", RouteData.Values["walletId"]?.ToString() } },
FormParameters =
{
{ "psbt", vm.PSBT },
{ "fileName", vm.FileName },
{ "backUrl", vm.BackUrl },
{ "returnUrl", vm.ReturnUrl },
{ "command", "decode" }
}
};
return View("PostRedirect", redirectVm);
}
[HttpGet("{walletId}/psbt/seed")]
public IActionResult SignWithSeed([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId,
SigningContextModel signingContext)
SigningContextModel signingContext, string returnUrl, string backUrl)
{
return View(nameof(SignWithSeed), new SignWithSeedViewModel { SigningContext = signingContext });
return View(nameof(SignWithSeed), new SignWithSeedViewModel
{
SigningContext = signingContext,
ReturnUrl = returnUrl,
BackUrl = backUrl
});
}
[HttpPost("{walletId}/psbt/seed")]
@@ -1082,7 +1118,9 @@ namespace BTCPayServer.Controllers
{
SigningKey = signingKey.GetWif(network.NBitcoinNetwork).ToString(),
SigningKeyPath = rootedKeyPath?.ToString(),
SigningContext = viewModel.SigningContext
SigningContext = viewModel.SigningContext,
ReturnUrl = viewModel.ReturnUrl,
BackUrl = viewModel.BackUrl
});
}
@@ -1225,12 +1263,14 @@ namespace BTCPayServer.Controllers
i++;
}
parameters.Add("returnUrl", Url.Action(nameof(WalletTransactions), new { walletId }));
var backUrl = Url.Action(nameof(WalletTransactions), new { walletId });
parameters.Add("returnUrl", backUrl);
parameters.Add("backUrl", backUrl);
return View("PostRedirect",
new PostRedirectViewModel
{
AspController = "UIWallets",
AspAction = nameof(UIWalletsController.WalletCPFP),
AspAction = nameof(WalletCPFP),
RouteParameters = { { "walletId", walletId.ToString() } },
FormParameters = parameters
});
@@ -1324,6 +1364,7 @@ namespace BTCPayServer.Controllers
public string CryptoCode { get; set; }
public string Address { get; set; }
public string PaymentLink { get; set; }
public string? ReturnUrl { get; set; }
}
public class SendToAddressResult