Skip to content
This repository has been archived by the owner on Aug 7, 2019. It is now read-only.

Reinitialize potentially disconnected keepkeys, add disconnectAll method, attempt to open/close regardless of keepkey state #30

Merged
merged 7 commits into from
Feb 13, 2019
6 changes: 5 additions & 1 deletion src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import messageTypeRegistry from './messageTypeRegistry'
import { makeEvent } from './event'

export default abstract class Device {
public abstract queue?: any
public abstract events: eventemitter2.EventEmitter2

public abstract get isInitialized (): boolean
Expand Down Expand Up @@ -45,7 +46,10 @@ export default abstract class Device {
// If error, throw with response message
if (responseTypeEnum === Messages.MessageType.MESSAGETYPE_FAILURE) {
const errorResponse = responseMsg as Messages.Failure
throw new Error(errorResponse.getMessage())

if (errorResponse.getCode() !== 4) {
majorhayes marked this conversation as resolved.
Show resolved Hide resolved
majorhayes marked this conversation as resolved.
Show resolved Hide resolved
throw new Error(errorResponse.getMessage()) // We want to know what this error is
} else console.error(errorResponse.getMessage()) // otherwise we don't really care, it's most likely been aborted
}
if (responseTypeEnum === Messages.MessageType.MESSAGETYPE_BUTTONREQUEST) {
return this.exchange(
Expand Down
14 changes: 12 additions & 2 deletions src/keepkeyManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ export default class KeepKeyManager {
): Promise<number> {
if (!window.navigator.usb) throw new Error('WebUSB not supported in your browser!')

const devicesToInitialize = devices || (await window.navigator.usb.getDevices())
.filter((dev) => !(this.keepkeys[dev.serialNumber]))
const devicesToInitialize = devices || await window.navigator.usb.getDevices()

for (const usbDevice of devicesToInitialize) {
if (this.keepkeys[usbDevice.serialNumber]) {
await this.get(usbDevice.serialNumber).initialize()
continue
}
let k = KeepKey.withWebUSB({ usbDevice, ...webusbConfig })
const features = await k.initialize()
if (features) this.add(k, usbDevice.serialNumber)
Expand Down Expand Up @@ -94,6 +97,13 @@ export default class KeepKeyManager {
await Promise.all(Object.keys(this.keepkeys).map(this.remove))
}

public disconnectAll (): void {
Object.values(this.keepkeys).forEach(k => {
if (k.device.queue) k.device.queue.clear()
k.device.disconnect().catch(console.log)
})
}

public decorateEvents (deviceID: string, events: eventemitter2.EventEmitter2): void {
events.onAny((e: string, ...values: any[]) => this.deviceEvents.emit([e, deviceID], [deviceID, ...values]))
}
Expand Down
13 changes: 5 additions & 8 deletions src/webUSBDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface WebUSBDeviceConfig {
const SEGMENT_SIZE = 63

export default class WebUSBDevice extends Device {
private queue: PQueue
public queue: PQueue
public usbDevice: USBDevice
public events: eventemitter2.EventEmitter2

Expand All @@ -36,18 +36,15 @@ export default class WebUSBDevice extends Device {
}

public async initialize (): Promise<void> {
if (!this.isInitialized) {
await this.usbDevice.open()
if (this.usbDevice.configuration === null) await this.usbDevice.selectConfiguration(1)
await this.usbDevice.claimInterface(0)
}
await this.usbDevice.open()
if (this.usbDevice.configuration === null) await this.usbDevice.selectConfiguration(1)
await this.usbDevice.claimInterface(0)
}

public async disconnect (): Promise<void> {
if (!this.usbDevice.opened) return
try {
// If the device is disconnected, this will fail and throw, which is fine.
await this.usbDevice.releaseInterface(0)
await this.usbDevice.close()
majorhayes marked this conversation as resolved.
Show resolved Hide resolved
} catch (e) {
console.log(e)
}
Expand Down