diff --git a/BTCPayServer/Controllers/VaultController.cs b/BTCPayServer/Controllers/VaultController.cs index 673a436bb..7f6679ba2 100644 --- a/BTCPayServer/Controllers/VaultController.cs +++ b/BTCPayServer/Controllers/VaultController.cs @@ -64,7 +64,7 @@ namespace BTCPayServer.Controllers HwiEnumerateEntry deviceEntry = null; HDFingerprint? fingerprint = null; string password = null; - int? pin = null; + bool pinProvided = false; var websocketHelper = new WebSocketHelper(websocket); async Task RequireDeviceUnlocking() @@ -80,7 +80,7 @@ namespace BTCPayServer.Controllers return true; } if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPinSent is true) - && pin is null + && !pinProvided // Trezor T always show the pin on screen && (deviceEntry.Model != HardwareWalletModels.Trezor_T || deviceEntry.Model != HardwareWalletModels.Trezor_T_Simulator)) { @@ -157,11 +157,21 @@ namespace BTCPayServer.Controllers await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); continue; } - await device.PromptPinAsync(cancellationToken); - await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken); - pin = int.Parse(await websocketHelper.NextMessageAsync(cancellationToken), CultureInfo.InvariantCulture); - if (await device.SendPinAsync(pin.Value, cancellationToken)) + try { + await device.PromptPinAsync(cancellationToken); + } + catch (HwiException ex) when (ex.ErrorCode == HwiErrorCode.DeviceAlreadyUnlocked) + { + pinProvided = true; + await websocketHelper.Send("{ \"error\": \"device-already-unlocked\"}", cancellationToken); + continue; + } + await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken); + var pin = int.Parse(await websocketHelper.NextMessageAsync(cancellationToken), CultureInfo.InvariantCulture); + if (await device.SendPinAsync(pin, cancellationToken)) + { + pinProvided = true; await websocketHelper.Send("{ \"info\": \"the pin is correct\"}", cancellationToken); } else @@ -207,7 +217,7 @@ namespace BTCPayServer.Controllers break; case "ask-device": password = null; - pin = null; + pinProvided = false; deviceEntry = null; device = null; var entries = (await hwi.EnumerateEntriesAsync(cancellationToken)).ToList(); diff --git a/BTCPayServer/Controllers/WalletsController.cs b/BTCPayServer/Controllers/WalletsController.cs index 5ea4e2d9d..13010aec5 100644 --- a/BTCPayServer/Controllers/WalletsController.cs +++ b/BTCPayServer/Controllers/WalletsController.cs @@ -728,7 +728,7 @@ namespace BTCPayServer.Controllers { try { - return (await wallet.GetBalance(derivationStrategy, cts.Token)).ToString(); + return (await wallet.GetBalance(derivationStrategy, cts.Token)).ToString(CultureInfo.InvariantCulture); } catch { diff --git a/BTCPayServer/wwwroot/js/vaultbridge.ui.js b/BTCPayServer/wwwroot/js/vaultbridge.ui.js index 69b93382b..7ed83e603 100644 --- a/BTCPayServer/wwwroot/js/vaultbridge.ui.js +++ b/BTCPayServer/wwwroot/js/vaultbridge.ui.js @@ -256,6 +256,8 @@ var vaultui = (function () { self.bridge.socket.send("ask-pin"); var json = await self.bridge.waitBackendMessage(); if (json.hasOwnProperty("error")) { + if (json.error == "device-already-unlocked") + return true; if (await needRetry(json)) return await self.askForPin(); return false;