diff --git a/packages/ui-keyring/package.json b/packages/ui-keyring/package.json index bedc065e..1678dda2 100644 --- a/packages/ui-keyring/package.json +++ b/packages/ui-keyring/package.json @@ -10,14 +10,14 @@ "contributors": [], "license": "Apache-2.0", "browser": { - "@ledgerhq/hw-transport-node-hid": "@ledgerhq/hw-transport-u2f" + "./ledger/transportsNode": "./ledger/transportsEmpty" }, "react-native": { - "@ledgerhq/hw-transport-node-hid": "@ledgerhq/hw-transport-u2f" + "./ledger/transportsNode": "./ledger/transportsEmpty", + "./ledger/transportsWeb": "./ledger/transportsEmpty" }, "dependencies": { "@babel/runtime": "^7.6.0", - "@ledgerhq/hw-transport-node-hid": "^4.70.0", "@ledgerhq/hw-transport-u2f": "^4.70.0", "@ledgerhq/hw-transport-webusb": "^4.70.0", "@types/ledgerhq__hw-transport-node-hid": "^4.21.1", @@ -35,6 +35,9 @@ "@polkadot/types": "^0.93.0-beta.7", "@polkadot/util": "^1.4.1" }, + "optionalDependencies": { + "@ledgerhq/hw-transport-node-hid": "^4.70.0" + }, "peerDependencies": { "@polkadot/keyring": "*", "@polkadot/types": "*", diff --git a/packages/ui-keyring/src/ledger-polkadot.d.ts b/packages/ui-keyring/src/ledger-polkadot.d.ts deleted file mode 100644 index 28352b95..00000000 --- a/packages/ui-keyring/src/ledger-polkadot.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -declare module 'ledger-polkadot' { - import Transport from '@ledgerhq/hw-transport'; - - export interface ResponseBase { - error_message: string; - return_code: number; - } - - export interface ReponseAddress extends ResponseBase { - address: string; - pubKey: string; - } - - export interface ResponseVersion extends ResponseBase { - device_locked: boolean; - major: number; - minor: number; - patch: number; - test_mode: boolean; - } - - export interface ResponseSign extends ResponseBase { - signature: Buffer; - } - - declare class LedgerApp { - constructor (transport: Transport, scrambleKey?: string); - - getVersion (): Promise; - getAddress (account: number, change: number, addressIndex: number, requireConfirmation?: boolean): Promise; - signSendChunk (chunkIdx: number, chunkNum: number, chunk: Buffer): Promise; - sign (account: number, change: number, addressIndex: number, message: Buffer): Promise; - } - - export default LedgerApp; -} diff --git a/packages/ui-keyring/src/ledger.ts b/packages/ui-keyring/src/ledger/index.ts similarity index 76% rename from packages/ui-keyring/src/ledger.ts rename to packages/ui-keyring/src/ledger/index.ts index 8ddd13bf..cf692651 100644 --- a/packages/ui-keyring/src/ledger.ts +++ b/packages/ui-keyring/src/ledger/index.ts @@ -3,29 +3,13 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import Transport from '@ledgerhq/hw-transport'; -import LedgerHid from '@ledgerhq/hw-transport-node-hid'; -import LedgerU2F from '@ledgerhq/hw-transport-u2f'; -import LedgerWebUSB from '@ledgerhq/hw-transport-webusb'; +import { LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion, TransportDef } from './types'; + import LedgerApp, { ResponseBase } from 'ledger-polkadot'; import { assert, bufferToU8a, u8aToBuffer, u8aToHex } from '@polkadot/util'; -export type LedgerTypes = 'hid' | 'u2f' | 'webusb'; - -export interface LedgerAddress { - address: string; - publicKey: string; -} - -export interface LedgerSignature { - signature: string; -} - -export interface LedgerVersion { - isLocked: boolean; - isTestMode: boolean; - version: [number, number, number]; -} +import allNode from './transportsNode'; +import allWeb from './transportsWeb'; export const LEDGER_DEFAULT_ACCOUNT = 0x80000000; @@ -35,6 +19,8 @@ export const LEDGER_DEFAULT_INDEX = 0x80000000; const SUCCESS_CODE = 0x9000; +const transports = allNode.concat(allWeb); + // A very basic wrapper for a ledger app - // - it connects automatically, creating an app as required // - Promises return errors (instead of wrapper errors) @@ -50,17 +36,12 @@ export default class Ledger { private async getApp (): Promise { if (!this.app) { - let transport: Transport; + const def = transports.find(({ type }): boolean => type === this.type); - if (this.type === 'hid') { - transport = await LedgerHid.create(); - } else if (this.type === 'u2f') { - transport = await LedgerU2F.create(); - } else if (this.type === 'webusb') { - transport = await LedgerWebUSB.create(); - } else { - throw new Error(`Unable to create app for ${this.type}`); - } + assert(def, `Unable to find a transport for ${this.type}`); + + // we have checked for undefined in the assert + const transport = await (def as TransportDef).create(); this.app = new LedgerApp(transport); } diff --git a/packages/ui-keyring/src/ledgerhq_hw-transport-webusb.d.ts b/packages/ui-keyring/src/ledger/ledgerhq_hw-transport-webusb.d.ts similarity index 100% rename from packages/ui-keyring/src/ledgerhq_hw-transport-webusb.d.ts rename to packages/ui-keyring/src/ledger/ledgerhq_hw-transport-webusb.d.ts diff --git a/packages/ui-keyring/src/ledger/transportsEmpty.ts b/packages/ui-keyring/src/ledger/transportsEmpty.ts new file mode 100644 index 00000000..27d10faf --- /dev/null +++ b/packages/ui-keyring/src/ledger/transportsEmpty.ts @@ -0,0 +1,9 @@ +// Copyright 2017-2019 @polkadot/ui-keyring authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { TransportDef } from './types'; + +const transports: TransportDef[] = []; + +export default transports; diff --git a/packages/ui-keyring/src/ledger/transportsNode.ts b/packages/ui-keyring/src/ledger/transportsNode.ts new file mode 100644 index 00000000..e7986acd --- /dev/null +++ b/packages/ui-keyring/src/ledger/transportsNode.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2019 @polkadot/ui-keyring authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { TransportDef } from './types'; + +import Transport from '@ledgerhq/hw-transport'; +import LedgerHid from '@ledgerhq/hw-transport-node-hid'; + +const transports: TransportDef[] = [ + { + create: (): Promise => + LedgerHid.create(), + type: 'hid' + } +]; + +export default transports; diff --git a/packages/ui-keyring/src/ledger/transportsWeb.ts b/packages/ui-keyring/src/ledger/transportsWeb.ts new file mode 100644 index 00000000..6455baba --- /dev/null +++ b/packages/ui-keyring/src/ledger/transportsWeb.ts @@ -0,0 +1,24 @@ +// Copyright 2017-2019 @polkadot/ui-keyring authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { TransportDef } from './types'; + +import Transport from '@ledgerhq/hw-transport'; +import LedgerU2F from '@ledgerhq/hw-transport-u2f'; +import LedgerWebUSB from '@ledgerhq/hw-transport-webusb'; + +const transports: TransportDef[] = [ + { + create: (): Promise => + LedgerU2F.create(), + type: 'u2f' + }, + { + create: (): Promise => + LedgerWebUSB.create(), + type: 'webusb' + } +]; + +export default transports; diff --git a/packages/ui-keyring/src/ledger/types.ts b/packages/ui-keyring/src/ledger/types.ts new file mode 100644 index 00000000..f75868e1 --- /dev/null +++ b/packages/ui-keyring/src/ledger/types.ts @@ -0,0 +1,27 @@ +// Copyright 2017-2019 @polkadot/ui-keyring authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import Transport from '@ledgerhq/hw-transport'; + +export type LedgerTypes = 'hid' | 'u2f' | 'webusb'; + +export interface LedgerAddress { + address: string; + publicKey: string; +} + +export interface LedgerSignature { + signature: string; +} + +export interface LedgerVersion { + isLocked: boolean; + isTestMode: boolean; + version: [number, number, number]; +} + +export interface TransportDef { + create (): Promise; + type: LedgerTypes; +}