public HwiDeviceClient(HwiClient hwiClient, DeviceSelector deviceSelector, HardwareWalletModels model, HDFingerprint?fingerprint) { HwiClient = hwiClient ?? throw new ArgumentNullException(nameof(hwiClient)); DeviceSelector = deviceSelector ?? throw new ArgumentNullException(nameof(deviceSelector)); Model = model; Fingerprint = fingerprint; }
// DeviceSelector is keijiro's library. // injected with zenject binding on hierarchy // TODO: simple data flow public TimecodeDecoderRepository(DeviceSelector audioDeviceSelector) { this.deviceSelector = audioDeviceSelector; audioDeviceSelector.Initialize(); SetSavedValuesToDropdown(); // because of dropdown initialization is not stable order }
internal async Task <string> SendCommandAsync(DeviceSelector deviceSelector, IEnumerable <HwiOption> options, HwiCommands?command, string[] commandArguments, CancellationToken cancel) { try { return(await SendCommandCoreAsync(deviceSelector, options, command, commandArguments, cancel).ConfigureAwait(false)); } catch (Exception ex) when(ex is OperationCanceledException || ex is TaskCanceledException || ex is TimeoutException) { throw new OperationCanceledException($"'hwi operation is canceled.", ex); } // HWI is inconsistent with error codes here. catch (HwiException ex) when(ex.ErrorCode == HwiErrorCode.DeviceConnError || ex.ErrorCode == HwiErrorCode.DeviceNotReady) { // Probably didn't find device with specified fingerprint. // Enumerate and call again, but not forever. if (!(deviceSelector is FingerprintDeviceSelector)) { throw; } IEnumerable <HwiEnumerateEntry> hwiEntries = await EnumerateEntriesAsync(cancel); // Trezor T won't give Fingerprint info so we'll assume that the first device that doesn't give fingerprint is what we need. HwiEnumerateEntry firstNoFingerprintEntry = hwiEntries.Where(x => x.Fingerprint is null).FirstOrDefault(); if (firstNoFingerprintEntry is null) { throw; } deviceSelector = DeviceSelectors.FromDeviceType(firstNoFingerprintEntry.Model, firstNoFingerprintEntry.Path); return(await SendCommandCoreAsync(deviceSelector, options, command, commandArguments, cancel).ConfigureAwait(false)); } }
private async Task <string> SendCommandCoreAsync(DeviceSelector deviceSelector = null, IEnumerable <HwiOption> options = null, HwiCommands?command = null, string[] commandArguments = null, CancellationToken cancellationToken = default) { var arguments = HwiParser.ToArgumentString(deviceSelector, Network, options, command, commandArguments); var response = await Transport.SendCommandAsync(arguments, cancellationToken).ConfigureAwait(false); ThrowIfError(response); return(response); }
private async void Page_Loaded(object sender, RoutedEventArgs e) { var devices = await _capture.GetDevicesAsync(); var binding = new Binding { Mode = BindingMode.OneTime, Source = devices }; BridgeSelector.IsEnabled = false; DeviceSelector.SetBinding(ComboBox.ItemsSourceProperty, binding); }
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); }
public HwiEnumerateEntry( HardwareWalletModels model, string path, string serialNumber, HDFingerprint?fingerprint, bool?needsPinSent, bool?needsPassphraseSent, string error, HwiErrorCode?code) { Model = model; Path = path; SerialNumber = serialNumber; Fingerprint = fingerprint; NeedsPinSent = needsPinSent; NeedsPassphraseSent = needsPassphraseSent; Error = error; Code = code; DeviceSelector = fingerprint is HDFingerprint fp?DeviceSelectors.FromFingerprint(fp) : DeviceSelectors.FromDeviceType(Model, path); }
internal static string[] ToArgumentString(DeviceSelector deviceSelector, Network network, IEnumerable <HwiOption> options, HwiCommands?command, string[] commandArguments) { List <string> arguments = new List <string>(); options ??= Enumerable.Empty <HwiOption>(); var fullOptions = new List <HwiOption>(options); chainNames.TryGetValue(network.ChainName, out var val); val ??= network.ChainName.ToString().ToLowerInvariant(); arguments.Add("--chain"); arguments.Add(val); foreach (var option in fullOptions) { arguments.Add($"--{option.Type.ToString().ToLowerInvariant()}"); if (!string.IsNullOrEmpty(option.Arguments)) { arguments.Add(option.Arguments); } } deviceSelector?.AddArgs(arguments); if (command != null) { arguments.Add(command.ToString().ToLowerInvariant()); } if (commandArguments != null) { foreach (var commandArgument in commandArguments) { arguments.Add(commandArgument); } } return(arguments.ToArray()); }
internal static string[] ToArgumentString(DeviceSelector deviceSelector, Network network, IEnumerable <HwiOption> options, HwiCommands?command, string[] commandArguments) { List <string> arguments = new List <string>(); options ??= Enumerable.Empty <HwiOption>(); var fullOptions = new List <HwiOption>(options); if (network.NetworkType != NetworkType.Mainnet) { fullOptions.Insert(0, HwiOption.TestNet); } foreach (var option in fullOptions) { arguments.Add($"--{option.Type.ToString().ToLowerInvariant()}"); if (!string.IsNullOrEmpty(option.Arguments)) { arguments.Add(option.Arguments); } } deviceSelector?.AddArgs(arguments); if (command != null) { arguments.Add(command.ToString().ToLowerInvariant()); } if (commandArguments != null) { foreach (var commandArgument in commandArguments) { arguments.Add(commandArgument); } } return(arguments.ToArray()); }
public async Task <IActionResult> VaultBridgeConnection(string cryptoCode = null, [ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId = null) { if (!HttpContext.WebSockets.IsWebSocketRequest) { return(NotFound()); } cryptoCode = cryptoCode ?? walletId.CryptoCode; using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10))) { var cancellationToken = cts.Token; var network = Networks.GetNetwork <BTCPayNetwork>(cryptoCode); if (network == null) { return(NotFound()); } var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var hwi = new Hwi.HwiClient(network.NBitcoinNetwork) { Transport = new HwiWebSocketTransport(websocket) }; Hwi.HwiDeviceClient device = null; HwiEnumerateEntry deviceEntry = null; HDFingerprint? fingerprint = null; string password = null; bool pinProvided = false; var websocketHelper = new WebSocketHelper(websocket); async Task <bool> RequireDeviceUnlocking() { if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); return(true); } if (deviceEntry.Code is HwiErrorCode.DeviceNotInitialized) { await websocketHelper.Send("{ \"error\": \"need-initialized\"}", cancellationToken); return(true); } if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPinSent is true) && !pinProvided) { if (!IsTrezorT(deviceEntry)) { await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken); return(true); } else { try { // On trezor T this will prompt the password! (https://github.com/bitcoin-core/HWI/issues/283) await device.GetXPubAsync(new KeyPath("44'"), cancellationToken); } catch (HwiException ex) when(ex.ErrorCode == HwiErrorCode.DeviceAlreadyUnlocked) { pinProvided = true; } await websocketHelper.Send("{ \"error\": \"need-passphrase-on-device\"}", cancellationToken); return(true); } } if ((deviceEntry.Code is HwiErrorCode.DeviceNotReady || deviceEntry.NeedsPassphraseSent is true) && password == null) { if (IsTrezorT(deviceEntry)) { await websocketHelper.Send("{ \"error\": \"need-passphrase-on-device\"}", cancellationToken); } else { await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken); } return(true); } return(false); } JObject o = null; try { while (true) { var command = await websocketHelper.NextMessageAsync(cancellationToken); switch (command) { case "set-passphrase": device.Password = await websocketHelper.NextMessageAsync(cancellationToken); password = device.Password; break; case "ask-sign": if (await RequireDeviceUnlocking()) { continue; } if (walletId == null) { await websocketHelper.Send("{ \"error\": \"invalid-walletId\"}", cancellationToken); continue; } if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken); o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); var authorization = await _authorizationService.AuthorizeAsync(User, Policies.CanModifyStoreSettings.Key); if (!authorization.Succeeded) { await websocketHelper.Send("{ \"error\": \"not-authorized\"}", cancellationToken); continue; } var psbt = PSBT.Parse(o["psbt"].Value <string>(), network.NBitcoinNetwork); var derivationSettings = GetDerivationSchemeSettings(walletId); derivationSettings.RebaseKeyPaths(psbt); var signing = derivationSettings.GetSigningAccountKeySettings(); if (signing.GetRootedKeyPath()?.MasterFingerprint != fingerprint) { await websocketHelper.Send("{ \"error\": \"wrong-wallet\"}", cancellationToken); continue; } var signableInputs = psbt.Inputs .SelectMany(i => i.HDKeyPaths) .Where(i => i.Value.MasterFingerprint == fingerprint) .ToArray(); if (signableInputs.Length > 0) { var actualPubKey = (await device.GetXPubAsync(signableInputs[0].Value.KeyPath)).GetPublicKey(); if (actualPubKey != signableInputs[0].Key) { await websocketHelper.Send("{ \"error\": \"wrong-keypath\"}", cancellationToken); continue; } } try { psbt = await device.SignPSBTAsync(psbt, cancellationToken); } catch (Hwi.HwiException) { await websocketHelper.Send("{ \"error\": \"user-reject\"}", cancellationToken); continue; } o = new JObject(); o.Add("psbt", psbt.ToBase64()); await websocketHelper.Send(o.ToString(), cancellationToken); break; case "ask-pin": if (device == null) { await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken); continue; } 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 { await websocketHelper.Send("{ \"error\": \"incorrect-pin\"}", cancellationToken); continue; } break; case "ask-xpub": if (await RequireDeviceUnlocking()) { continue; } await websocketHelper.Send("{ \"info\": \"ok\"}", cancellationToken); var askedXpub = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); var addressType = askedXpub["addressType"].Value <string>(); var accountNumber = askedXpub["accountNumber"].Value <int>(); JObject result = new JObject(); var factory = network.NBXplorerNetwork.DerivationStrategyFactory; if (fingerprint is null) { fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint; } result["fingerprint"] = fingerprint.Value.ToString(); DerivationStrategyBase strategy = null; KeyPath keyPath = null; BitcoinExtPubKey xpub = null; if (!network.NBitcoinNetwork.Consensus.SupportSegwit && addressType != "legacy") { await websocketHelper.Send("{ \"error\": \"segwit-notsupported\"}", cancellationToken); continue; } if (addressType == "segwit") { keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.Segwit }); } else if (addressType == "segwitWrapped") { keyPath = new KeyPath("49'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { ScriptPubKeyType = ScriptPubKeyType.SegwitP2SH }); } else if (addressType == "legacy") { keyPath = new KeyPath("44'").Derive(network.CoinType).Derive(accountNumber, true); xpub = await device.GetXPubAsync(keyPath); strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions() { 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.Where(h => deviceSelector == null || SameSelector(deviceSelector, h.DeviceSelector)).FirstOrDefault(); if (deviceEntry == null) { await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken); continue; } device = new HwiDeviceClient(hwi, deviceEntry.DeviceSelector, deviceEntry.Model, deviceEntry.Fingerprint); fingerprint = device.Fingerprint; JObject json = new JObject(); json.Add("model", device.Model.ToString()); json.Add("fingerprint", device.Fingerprint?.ToString()); await websocketHelper.Send(json.ToString(), cancellationToken); break; } } } catch (FormatException ex) { JObject obj = new JObject(); obj.Add("error", "invalid-network"); obj.Add("details", ex.ToString()); try { await websocketHelper.Send(obj.ToString(), cancellationToken); } catch { } } catch (Exception ex) { JObject obj = new JObject(); obj.Add("error", "unknown-error"); obj.Add("message", ex.Message); obj.Add("details", ex.ToString()); try { await websocketHelper.Send(obj.ToString(), cancellationToken); } catch { } } finally { await websocketHelper.DisposeAsync(cancellationToken); } } return(new EmptyResult()); }
/// <summary> /// Erzeugt ein neues Auswahlfenster. /// </summary> /// <param name="parameters">Die aktuelle Wahl der Parameter.</param> public AdditionalFilterSelector(List <ProfileParameter> parameters) { // Load designer stuff InitializeComponent(); // Load the supression mode switch (GetSuppression(null, parameters)) { case SuppressionMode.Complete: ckReset.Checked = true; ckResetTune.Checked = false; break; case SuppressionMode.Startup: ckReset.Checked = true; break; default: ckResetTune.Enabled = false; break; } // Load flag bool disableOnChange; if (bool.TryParse(parameters.GetParameter(CancelEncryptionOnChangedStream), out disableOnChange)) { ckDisableOnChange.Checked = disableOnChange; } else { ckDisableOnChange.Checked = false; } // Load delay int delay; if (int.TryParse(parameters.GetParameter(DelayOnChangedStream), out delay)) { udChangeDelay.Value = Math.Max(Math.Min(delay, udChangeDelay.Maximum), udChangeDelay.Minimum); } else { udChangeDelay.Value = udChangeDelay.Minimum; } // Load foreach (var information in DeviceAndFilterInformations.Cache.AllFilters) { selFilter.Items.Add(new DeviceSelector(information)); } // Check for done selFilter.Enabled = (selFilter.Items.Count > 0); if (!selFilter.Enabled) { return; } // Forget about sorting selFilter.Sorted = false; // Add a null option selFilter.Items.Insert(0, Properties.Resources.Select_NoDevice); // Pre select selFilter.SelectedIndex = 0; // Load name var displayName = parameters.GetParameter(FilterName); if (string.IsNullOrEmpty(displayName)) { return; } // Load flag bool flag; if (bool.TryParse(parameters.GetParameter(IgnoreMoniker), out flag)) { ckDisplayOnly.Checked = flag; } // Load moniker var moniker = flag ? null : parameters.GetParameter(FilterMoniker); // Try to re-select DeviceSelector.Select(selFilter, displayName, moniker); }
public TimecodeDecoderDataStore(DeviceSelector audioDeviceSelector) { this.deviceSelector = audioDeviceSelector; }