diff --git a/common/components/WalletDecrypt/components/KeepKey.tsx b/common/components/WalletDecrypt/components/KeepKey.tsx index 9b055265..ccd57fa1 100644 --- a/common/components/WalletDecrypt/components/KeepKey.tsx +++ b/common/components/WalletDecrypt/components/KeepKey.tsx @@ -63,7 +63,7 @@ class KeepKeyDecryptClass extends PureComponent { Unlocking... ) : ( - translate('ADD_TREZOR_SCAN') + translate('ADD_KEEPKEY_SCAN') )} diff --git a/common/translations/lang/en.json b/common/translations/lang/en.json index af771fda..41f1d901 100644 --- a/common/translations/lang/en.json +++ b/common/translations/lang/en.json @@ -75,6 +75,7 @@ "X_TREZOR": "TREZOR ", "ADD_TREZOR_SCAN": "Connect to TREZOR ", "X_KEEPKEY": "KeepKey", + "ADD_KEEPKEY_SCAN": "Connect to KeepKey ", "X_PARITYSIGNER": "Parity Signer ", "ADD_PARITY_DESC": "Connect & sign via your Parity Signer mobile app ", "ADD_PARITY_1": "Transaction canceled ", diff --git a/package.json b/package.json index c0b7b59f..01090fc9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "bip39": "2.5.0", "bn.js": "4.11.8", "bootstrap-sass": "3.3.7", + "bytebuffer": "5.0.1", "classnames": "2.2.5", "electron-updater": "2.21.4", "ethereum-blockies-base64": "1.0.1", diff --git a/shared/enclave/server/wallets/keepkey/NodeHidHelper.ts b/shared/enclave/server/wallets/keepkey/NodeHidHelper.ts new file mode 100644 index 00000000..c0af04f1 --- /dev/null +++ b/shared/enclave/server/wallets/keepkey/NodeHidHelper.ts @@ -0,0 +1,19 @@ +import { DeviceClientManager } from '@keepkey/device-client/dist/device-client-manager'; +import { HidHelper } from '@keepkey/device-client/dist/hid-helper'; +import HID from 'node-hid'; +import NodeHidTransport from './NodeHidTransport'; + +const dcm = new DeviceClientManager(); + +export default class NodeHidHelper implements HidHelper { + public async getActiveClient() { + const devices = HID.devices(); + const device = devices.find(d => d.vendorId === 11044 && d.product === 'KeepKey'); + + if (!device) { + throw new Error('No KeepKey device found'); + } + + return dcm.factory(new NodeHidTransport(device)); + } +} diff --git a/shared/enclave/server/wallets/keepkey/NodeHidTransport.ts b/shared/enclave/server/wallets/keepkey/NodeHidTransport.ts new file mode 100644 index 00000000..08289684 --- /dev/null +++ b/shared/enclave/server/wallets/keepkey/NodeHidTransport.ts @@ -0,0 +1,55 @@ +import { Transport } from '@keepkey/device-client/dist/transport'; +import HID from 'node-hid'; +import ByteBuffer from 'bytebuffer'; + +export default class NodeHidTransport extends Transport { + private device: HID.HID | null; + + constructor(deviceData: HID.Device) { + super(deviceData); + + this.device = new HID.HID(deviceData.vendorId, deviceData.productId); + } + + protected async _write(msg: ByteBuffer) { + const device = this.getDevice(); + console.log('Writing', [...msg.buffer]); + device.write([...msg.buffer]); + // this.closeDevice(); + } + + protected async _read() { + return new Promise((resolve, reject) => { + const device = this.getDevice(); + device.read((err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + // this.closeDevice(); + }); + }); + } + + private getDevice() { + if (this.device) { + return this.device; + } + + try { + this.device = new HID.HID(this.vendorId, this.productId); + return this.device; + } catch (err) { + console.error('Could not open KeepKey HID:', err); + throw new Error('Could not open KeepKey wallet, it may be in use by another app'); + } + } + + private closeDevice() { + if (this.device) { + this.device.close(); + this.device = null; + } + } +} diff --git a/shared/enclave/server/wallets/keepkey.ts b/shared/enclave/server/wallets/keepkey/index.ts similarity index 89% rename from shared/enclave/server/wallets/keepkey.ts rename to shared/enclave/server/wallets/keepkey/index.ts index ada16324..5d641ddd 100644 --- a/shared/enclave/server/wallets/keepkey.ts +++ b/shared/enclave/server/wallets/keepkey/index.ts @@ -1,8 +1,11 @@ -import { WalletLib } from 'shared/enclave/types'; +/* tslint:disable max-classes-per-file */ import { DeviceClientManager } from '@keepkey/device-client/dist/device-client-manager'; import { NodeVector } from '@keepkey/device-client/dist/node-vector'; +import { WalletLib } from 'shared/enclave/types'; +import NodeHidHelper from './NodeHidHelper'; const dcm = new DeviceClientManager(); +dcm.hidHelper = new NodeHidHelper(); const KeepKey: WalletLib = { async getChainCode() {