Trying to handle Trezor T correctly

This commit is contained in:
nicolas.dorier 2019-12-04 17:16:37 +09:00
parent 3e08581e9b
commit 1559c510be
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
2 changed files with 84 additions and 9 deletions

View file

@ -80,16 +80,28 @@ namespace BTCPayServer.Controllers
return true;
}
if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPinSent is true)
&& !pinProvided
// Trezor T always show the pin on screen
&& (deviceEntry.Model != HardwareWalletModels.Trezor_T || deviceEntry.Model != HardwareWalletModels.Trezor_T_Simulator))
&& !pinProvided)
{
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
if (IsTrezorT(deviceEntry))
{
await websocketHelper.Send("{ \"error\": \"need-pin-on-device\"}", cancellationToken);
}
else
{
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
}
return true;
}
if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPassphraseSent is true) && password == null)
{
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
if (IsTrezorT(deviceEntry))
{
await websocketHelper.Send("{ \"error\": \"need-passphrase-on-device\"}", cancellationToken);
}
else
{
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
}
return true;
}
return false;
@ -247,18 +259,25 @@ namespace BTCPayServer.Controllers
ScriptPubKeyType = ScriptPubKeyType.Legacy
});
}
else
{
await websocketHelper.Send("{ \"error\": \"invalid-addresstype\"}", cancellationToken);
continue;
}
result.Add(new JProperty("strategy", strategy.ToString()));
result.Add(new JProperty("accountKey", xpub.ToString()));
result.Add(new JProperty("keyPath", keyPath.ToString()));
await websocketHelper.Send(result.ToString(), cancellationToken);
break;
case "refresh-device":
case "ask-device":
DeviceSelector deviceSelector = (command == "refresh-device" && deviceEntry != null ? deviceEntry.DeviceSelector : null);
password = null;
pinProvided = false;
deviceEntry = null;
device = null;
var entries = (await hwi.EnumerateEntriesAsync(cancellationToken)).ToList();
deviceEntry = entries.FirstOrDefault();
deviceEntry = entries.Where(h => deviceSelector == null || SameSelector(deviceSelector, h.DeviceSelector)).FirstOrDefault();
if (deviceEntry == null)
{
await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken);
@ -304,6 +323,27 @@ namespace BTCPayServer.Controllers
return new EmptyResult();
}
private bool SameSelector(DeviceSelector a, DeviceSelector b)
{
var aargs = new List<string>();
a.AddArgs(aargs);
var bargs = new List<string>();
b.AddArgs(bargs);
if (aargs.Count != bargs.Count)
return false;
for (int i = 0; i < aargs.Count; i++)
{
if (aargs[i] != bargs[i])
return false;
}
return true;
}
private static bool IsTrezorT(HwiEnumerateEntry deviceEntry)
{
return (deviceEntry.Model != HardwareWalletModels.Trezor_T || deviceEntry.Model != HardwareWalletModels.Trezor_T_Simulator);
}
public StoreData CurrentStore
{
get

View file

@ -42,11 +42,13 @@ var vaultui = (function () {
unexpectedError: new VaultFeedback("failed", "An unexpected error happened.", "vault-feedback3", "unknown-error"),
invalidNetwork: new VaultFeedback("failed", "The device is targetting a different chain.", "vault-feedback3", "invalid-network"),
needPin: new VaultFeedback("?", "Enter the pin.", "vault-feedback3", "need-pin"),
needPinOnDevice: new VaultFeedback("?", "Please, enter the pin on the device.", "vault-feedback3", "need-pin-on-device"),
incorrectPin: new VaultFeedback("failed", "Incorrect pin code.", "vault-feedback3", "incorrect-pin"),
invalidPasswordConfirmation: new VaultFeedback("failed", "Invalid password confirmation.", "vault-feedback3", "invalid-password-confirm"),
wrongWallet: new VaultFeedback("failed", "This device can't sign the transaction. (Wrong device, wrong passphrase or wrong device fingerprint in your wallet settings)", "vault-feedback3", "wrong-wallet"),
wrongKeyPath: new VaultFeedback("failed", "This device can't sign the transaction. (The wallet keypath in your wallet settings seems incorrect)", "vault-feedback3", "wrong-keypath"),
needPassphrase: new VaultFeedback("?", "Enter the passphrase.", "vault-feedback3", "need-passphrase"),
needPassphraseOnDevice: new VaultFeedback("?", "Please, enter the passphrase on the device.", "vault-feedback3", "need-passphrase-on-device"),
signingTransaction: new VaultFeedback("?", "Signing the transaction...", "vault-feedback3", "ask-signing"),
signingRejected: new VaultFeedback("failed", "The user refused to sign the transaction", "vault-feedback3", "user-reject"),
};
@ -123,6 +125,23 @@ var vaultui = (function () {
if (await self.askForPassphrase())
return true;
}
if (json.error === "need-pin-on-device" || json.error === "need-passphrase-on-device") {
handled = true;
if (json.error === "need-pin-on-device") {
showError(VaultFeedbacks.needPinOnDevice);
} else {
showError(VaultFeedbacks.needPassphraseOnDevice);
}
await waitClickContinue();
self.bridge.socket.send("refresh-device");
var json = await self.bridge.waitBackendMessage();
if (json.hasOwnProperty("error")) {
showError(json);
return false;
}
return true;
}
if (!handled) {
showError(json);
}
@ -203,7 +222,6 @@ var vaultui = (function () {
$("#vault-confirm").css("display", "block");
$("#vault-confirm").text("Confirm");
return new Promise(function (resolve, reject) {
var pinCode = "";
$("#vault-confirm").click(async function (e) {
e.preventDefault();
$("#vault-xpub").css("display", "none");
@ -212,7 +230,24 @@ var vaultui = (function () {
resolve({
addressType: $("select[name=\"addressType\"]").val(),
accountNumber: parseInt($("select[name=\"accountNumber\"]").val())
});
});
});
});
};
/**
* @returns {Promise}
*/
this.waitClickContinue = function () {
$("#vault-confirm").css("display", "block");
$("#vault-confirm").text("Continue");
return new Promise(function (resolve, reject) {
$("#vault-confirm").click(async function (e) {
e.preventDefault();
$("#vault-confirm").css("display", "none");
$(this).unbind();
resolve("");
});
});
};
@ -287,7 +322,7 @@ var vaultui = (function () {
this.askForPin = async function () {
if (!await self.ensureConnectedToBackend())
return false;
self.bridge.socket.send("ask-pin");
var json = await self.bridge.waitBackendMessage();
if (json.hasOwnProperty("error")) {