Revert back to original transaction if payjoined tx does not work

This commit is contained in:
Kukks
2020-03-26 15:42:54 +01:00
parent 10fcfab233
commit 065be9be64
8 changed files with 46 additions and 13 deletions

View File

@@ -209,7 +209,8 @@ namespace BTCPayServer.Controllers
{
Severity = StatusMessageModel.StatusSeverity.Info,
AllowDismiss = false,
Html = "This transaction has been coordinated between the receiver and you to create a <a href='https://en.bitcoin.it/wiki/PayJoin' target='_blank'>payjoin transaction</a> by adding inputs from the receiver. The amount being sent may appear higher but is in fact the same"
Html =
$"This transaction has been coordinated between the receiver and you to create a <a href='https://en.bitcoin.it/wiki/PayJoin' target='_blank'>payjoin transaction</a> by adding inputs from the receiver. The amount being sent may appear higher but is in fact the same"
});
return newPSBT;
}
@@ -225,12 +226,14 @@ namespace BTCPayServer.Controllers
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, string psbt = null,
string signingKey = null,
string signingKeyPath = null)
string signingKeyPath = null,
string originalPsbt = null)
{
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
var vm = new WalletPSBTReadyViewModel() { PSBT = psbt };
vm.SigningKey = signingKey;
vm.SigningKeyPath = signingKeyPath;
vm.OriginalPSBT = originalPsbt;
var derivationSchemeSettings = GetDerivationSchemeSettings(walletId);
if (derivationSchemeSettings == null)
return NotFound();
@@ -351,7 +354,7 @@ namespace BTCPayServer.Controllers
WalletId walletId, WalletPSBTReadyViewModel vm, string command = null)
{
if (command == null)
return await WalletPSBTReady(walletId, vm.PSBT, vm.SigningKey, vm.SigningKeyPath);
return await WalletPSBTReady(walletId, vm.PSBT, vm.SigningKey, vm.SigningKeyPath, vm.OriginalPSBT);
PSBT psbt = null;
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
try
@@ -367,6 +370,11 @@ namespace BTCPayServer.Controllers
vm.GlobalError = "Invalid PSBT";
return View(nameof(WalletPSBTReady),vm);
}
if (command == "use-original")
{
return await WalletPSBTReady(walletId, vm.OriginalPSBT, vm.SigningKey, vm.SigningKeyPath);
}
if (command == "broadcast")
{
if (!psbt.IsAllFinalized() && !psbt.TryFinalize(out var errors))
@@ -380,6 +388,17 @@ namespace BTCPayServer.Controllers
var broadcastResult = await ExplorerClientProvider.GetExplorerClient(network).BroadcastAsync(transaction);
if (!broadcastResult.Success)
{
if (!string.IsNullOrEmpty(vm.OriginalPSBT))
{
TempData.SetStatusMessageModel(new StatusMessageModel()
{
Severity = StatusMessageModel.StatusSeverity.Error,
AllowDismiss = false,
Html = $"The payjoin transaction could not be broadcast.<br/>({broadcastResult.RPCCode} {broadcastResult.RPCCodeMessage} {broadcastResult.RPCMessage}).<br/>The transaction has been reverted back to its original format and is ready to be broadcast."
});
return await WalletPSBTReady(walletId, vm.OriginalPSBT, vm.SigningKey, vm.SigningKeyPath);
}
vm.GlobalError = $"RPC Error while broadcasting: {broadcastResult.RPCCode} {broadcastResult.RPCCodeMessage} {broadcastResult.RPCMessage}";
return View(nameof(WalletPSBTReady),vm);
}

View File

@@ -692,13 +692,14 @@ namespace BTCPayServer.Controllers
model.PayJoinEndpointUrl = null;
if (newPSBT != null)
{
model.OriginalPSBT = model.PSBT;
model.PSBT = newPSBT.ToBase64();
return View(nameof(WalletSendVault), model);
}
return RedirectToWalletPSBTReady(model.PSBT);
return RedirectToWalletPSBTReady(model.PSBT, originalPsbt: model.OriginalPSBT);
}
private IActionResult RedirectToWalletPSBTReady(string psbt, string signingKey= null, string signingKeyPath = null)
private IActionResult RedirectToWalletPSBTReady(string psbt, string signingKey= null, string signingKeyPath = null, string originalPsbt = null)
{
var vm = new PostRedirectViewModel()
{
@@ -707,6 +708,7 @@ namespace BTCPayServer.Controllers
Parameters =
{
new KeyValuePair<string, string>("psbt", psbt),
new KeyValuePair<string, string>("originalPsbt", originalPsbt),
new KeyValuePair<string, string>("SigningKey", signingKey),
new KeyValuePair<string, string>("SigningKeyPath", signingKeyPath)
}
@@ -851,10 +853,11 @@ namespace BTCPayServer.Controllers
viewModel.PayJoinEndpointUrl = null;
if (newPSBT != null)
{
viewModel.OriginalPSBT = psbt.ToBase64();
viewModel.PSBT = newPSBT.ToBase64();
return await SignWithSeed(walletId, viewModel);
}
return RedirectToWalletPSBTReady(psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath?.ToString());
return RedirectToWalletPSBTReady(psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath?.ToString(), viewModel.OriginalPSBT);
}
private bool PSBTChanged(PSBT psbt, Action act)

View File

@@ -7,6 +7,7 @@ namespace BTCPayServer.Models.WalletViewModels
{
public class SignWithSeedViewModel
{
public string OriginalPSBT { get; set; }
public string PayJoinEndpointUrl { get; set; }
[Required]
public string PSBT { get; set; }

View File

@@ -8,6 +8,7 @@ namespace BTCPayServer.Models.WalletViewModels
{
public class WalletPSBTReadyViewModel
{
public string OriginalPSBT { get; set; }
public string PSBT { get; set; }
public string SigningKey { get; set; }
public string SigningKeyPath { get; set; }

View File

@@ -7,6 +7,7 @@ namespace BTCPayServer.Models.WalletViewModels
{
public class WalletSendVaultModel
{
public string OriginalPSBT { get; set; }
public string WalletId { get; set; }
public string PSBT { get; set; }
public string WebsocketPath { get; set; }

View File

@@ -27,6 +27,7 @@
<div class="col-md-10">
<div asp-validation-summary="All" class="text-danger"></div>
<form method="post" asp-action="SignWithSeed" asp-route-walletId="@this.Context.GetRouteValue("walletId")">
<input type="hidden" asp-for="OriginalPSBT" />
<input type="hidden" asp-for="PSBT" />
<input type="hidden" asp-for="PayJoinEndpointUrl" />
<div class="form-group">

View File

@@ -137,7 +137,8 @@
<div class="row">
<div class="col-lg-12 text-center">
<form method="post" asp-action="WalletPSBTReady" asp-route-walletId="@this.Context.GetRouteValue("walletId")">
<input type="hidden" asp-for="PSBT"/>
<input type="hidden" asp-for="PSBT" value="@Model.PSBT"/>
<input type="hidden" asp-for="OriginalPSBT"/>
<input type="hidden" asp-for="SigningKey"/>
<input type="hidden" asp-for="SigningKeyPath"/>
@if (!Model.HasErrors)
@@ -146,6 +147,11 @@
<span> or </span>
}
<button type="submit" class="btn btn-secondary" name="command" value="analyze-psbt">Export as PSBT</button>
@if (!string.IsNullOrEmpty(Model.OriginalPSBT))
{
<span> or </span>
<button type="submit" class="btn btn-secondary" name="command" value="use-original">Skip payjoin</button>
}
</form>
</div>
</div>

View File

@@ -23,6 +23,7 @@
<form id="broadcastForm" asp-action="WalletSendVault" asp-route-walletId="@this.Context.GetRouteValue("walletId")" method="post" style="display:none;">
<input type="hidden" id="WalletId" asp-for="WalletId" />
<input type="hidden" id="PSBT" asp-for="PSBT" value="@Model.PSBT"/>
<input type="hidden" id="OriginalPSBT" asp-for="OriginalPSBT" value="@Model.OriginalPSBT"/>
<input type="hidden" asp-for="WebsocketPath" />
<input type="hidden" asp-for="PayJoinEndpointUrl" />
</form>