diff --git a/README.md b/README.md index c1495a0d5..7cfa9d57a 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ import AppBtc from "@ledgerhq/hw-app-btc"; const getBtcAddress = async () => { const transport = await Transport.create(); const btc = new AppBtc(transport); - const result = await btc.getWalletPublicKey("44'/0'/0'/0"); + const result = await btc.getWalletPublicKey("44'/0'/0'/0/0"); return result.bitcoinAddress; }; getBtcAddress().then(a => console.log(a)); diff --git a/lerna.json b/lerna.json index d42eb9322..63ab55010 100644 --- a/lerna.json +++ b/lerna.json @@ -3,7 +3,7 @@ "packages": [ "packages/*" ], - "version": "4.16.0", + "version": "4.19.1", "npmClient": "yarn", "useWorkspaces": true } diff --git a/packages/example-browser/package.json b/packages/example-browser/package.json index 415cc4ded..6024f986a 100644 --- a/packages/example-browser/package.json +++ b/packages/example-browser/package.json @@ -6,9 +6,9 @@ "build": "cross-env NODE_ENV=production parcel build index.html --no-minify --public-url /" }, "dependencies": { - "@ledgerhq/hw-app-btc": "^4.15.0", - "@ledgerhq/hw-app-eth": "^4.15.0", - "@ledgerhq/hw-transport-u2f": "^4.15.0", + "@ledgerhq/hw-app-btc": "^4.19.0", + "@ledgerhq/hw-app-eth": "^4.19.0", + "@ledgerhq/hw-transport-u2f": "^4.19.0", "react": "^16.2.0", "react-dom": "^16.2.0" }, @@ -19,5 +19,5 @@ "parcel-bundler": "^1.6.2" }, "private": true, - "version": "4.15.0" + "version": "4.19.0" } diff --git a/packages/example-node/package.json b/packages/example-node/package.json index 1f898254a..f663a1d96 100644 --- a/packages/example-node/package.json +++ b/packages/example-node/package.json @@ -1,13 +1,13 @@ { "private": true, "name": "@ledgerhq/example-node", - "version": "4.16.0", + "version": "4.19.1", "main": "index.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-app-btc": "^4.15.0", - "@ledgerhq/hw-app-eth": "^4.15.0", - "@ledgerhq/hw-transport-node-hid": "^4.16.0" + "@ledgerhq/hw-app-btc": "^4.19.0", + "@ledgerhq/hw-app-eth": "^4.19.0", + "@ledgerhq/hw-transport-node-hid": "^4.19.1" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/hw-app-ada/package.json b/packages/hw-app-ada/package.json index dba51c558..ede7cebdc 100644 --- a/packages/hw-app-ada/package.json +++ b/packages/hw-app-ada/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-app-ada", - "version": "4.16.0", + "version": "4.19.1", "description": "Ledger Hardware Wallet Cardano ADA API", "main": "lib/Ada.js", "repository": "git+ssh://git@github.com/LedgerHQ/ledgerjs.git", @@ -17,11 +17,11 @@ "author": "HiddenField Ltd ", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "node-int64": "^0.4.0" }, "devDependencies": { - "@ledgerhq/hw-transport-node-hid": "^4.16.0", + "@ledgerhq/hw-transport-node-hid": "^4.19.1", "chai": "^4.1.2", "chalk": "^2.3.1", "flow-bin": "^0.68.0", diff --git a/packages/hw-app-btc/package.json b/packages/hw-app-btc/package.json index 380837a56..4a54cf6a5 100644 --- a/packages/hw-app-btc/package.json +++ b/packages/hw-app-btc/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-app-btc", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Bitcoin Application API", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/Btc.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "create-hash": "^1.1.3" }, "devDependencies": { diff --git a/packages/hw-app-btc/src/Btc.js b/packages/hw-app-btc/src/Btc.js index 13b84f380..d45a310d6 100644 --- a/packages/hw-app-btc/src/Btc.js +++ b/packages/hw-app-btc/src/Btc.js @@ -254,13 +254,15 @@ export default class Btc { newTransaction: boolean, firstRound: boolean, transactionData: Buffer, - bip143?: boolean = false + bip143?: boolean = false, + overwinter?: boolean = false ) { + const p2 = bip143 ? (overwinter ? 0x04 : 0x02) : 0x00; return this.transport.send( 0xe0, 0x44, firstRound ? 0x00 : 0x80, - newTransaction ? (bip143 ? 0x02 : 0x00) : 0x80, + newTransaction ? p2 : 0x80, transactionData ); } @@ -269,18 +271,21 @@ export default class Btc { newTransaction: boolean, transaction: Transaction, inputs: Array<{ trustedInput: boolean, value: Buffer }>, - bip143?: boolean = false + bip143?: boolean = false, + overwinter?: boolean = false ) { let data = Buffer.concat([ transaction.version, transaction.timestamp || Buffer.alloc(0), + transaction.nVersionGroupId || Buffer.alloc(0), this.createVarint(transaction.inputs.length) ]); return this.startUntrustedHashTransactionInputRaw( newTransaction, true, data, - bip143 + bip143, + overwinter ).then(() => { let i = 0; return eachSeries(transaction.inputs, input => { @@ -303,7 +308,8 @@ export default class Btc { newTransaction, false, data, - bip143 + bip143, + overwinter ).then(() => { let scriptBlocks = []; let offset = 0; @@ -335,7 +341,8 @@ export default class Btc { newTransaction, false, scriptBlock, - bip143 + bip143, + overwinter ); }).then(() => { i++; @@ -376,23 +383,34 @@ export default class Btc { signTransaction( path: string, lockTime?: number = DEFAULT_LOCKTIME, - sigHashType?: number = SIGHASH_ALL + sigHashType?: number = SIGHASH_ALL, + expiryHeight?: Buffer ): Promise { const paths = splitPath(path); - const buffer = Buffer.alloc(1 + paths.length * 4 + 1 + 4 + 1); // TODO shouldn't have to calc that, just use buffer concat all the way down let offset = 0; - buffer[offset++] = paths.length; + const pathsBuffer = Buffer.alloc(paths.length * 4); paths.forEach(element => { - buffer.writeUInt32BE(element, offset); + pathsBuffer.writeUInt32BE(element, offset); offset += 4; }); - buffer[offset++] = 0x00; // authorization length - buffer.writeUInt32BE(lockTime, offset); - offset += 4; - buffer[offset++] = sigHashType; + const lockTimeBuffer = Buffer.alloc(4); + lockTimeBuffer.writeUInt32BE(lockTime, 0); + let buffer = Buffer.concat([ + Buffer.from([paths.length]), + pathsBuffer, + Buffer.from([0x00]), + lockTimeBuffer, + Buffer.from([sigHashType]) + ]); + if (expiryHeight) { + buffer = Buffer.concat([buffer, expiryHeight]); + } return this.transport.send(0xe0, 0x48, 0x00, 0x00, buffer).then(result => { - result[0] = 0x30; - return result.slice(0, result.length - 2); + if (result.length > 0) { + result[0] = 0x30; + return result.slice(0, result.length - 2); + } + return result; }); } @@ -479,9 +497,10 @@ export default class Btc { * @param outputScriptHex is the hexadecimal serialized outputs of the transaction to sign * @param lockTime is the optional lockTime of the transaction to sign, or default (0) * @param sigHashType is the hash type of the transaction to sign, or default (all) - * @param segwit is a boolean indicating wether to use segwit or not - * @param initialTimestamp is the timestamp when the function is called, not the one that the tx will include + * @param segwit is an optional boolean indicating wether to use segwit or not + * @param initialTimestamp is an optional timestamp of the function call to use for coins that necessitate timestamps only, (not the one that the tx will include) * @param additionals list of additionnal options ("abc" for bch, "gold" for btg, "bipxxx" for using BIPxxx) + * @param expiryHeight is an optional Buffer for zec overwinter Txs * @return the signed transaction ready to be broadcast * @example btc.createPaymentTransactionNew( @@ -500,7 +519,8 @@ btc.createPaymentTransactionNew( sigHashType?: number = SIGHASH_ALL, segwit?: boolean = false, initialTimestamp?: number, - additionals?: Array + additionals?: Array, + expiryHeight?: Buffer ) { const hasTimestamp = initialTimestamp !== undefined; let startTime = Date.now(); @@ -509,13 +529,16 @@ btc.createPaymentTransactionNew( (!!additionals && (additionals.includes("abc") || additionals.includes("gold") || - additionals.includes("bip143"))); + additionals.includes("bip143"))) || + !!expiryHeight; // Inputs are provided as arrays of [transaction, output_index, optional redeem script, optional sequence] // associatedKeysets are provided as arrays of [path] const nullScript = Buffer.alloc(0); const nullPrevout = Buffer.alloc(0); const defaultVersion = Buffer.alloc(4); - defaultVersion.writeUInt32LE(1, 0); + expiryHeight + ? defaultVersion.writeUInt32LE(0x80000003, 0) + : defaultVersion.writeUInt32LE(1, 0); const trustedInputs: Array<*> = []; const regularOutputs: Array = []; const signatures = []; @@ -548,13 +571,26 @@ btc.createPaymentTransactionNew( sequence }); }) - ).then(() => { - const { outputs } = input[0]; - const index = input[1]; - if (outputs && index <= outputs.length - 1) { - regularOutputs.push(outputs[index]); - } - }); + ) + .then(() => { + const { outputs } = input[0]; + const index = input[1]; + if (outputs && index <= outputs.length - 1) { + regularOutputs.push(outputs[index]); + } + }) + .then(() => { + if (expiryHeight) { + targetTransaction.nVersionGroupId = Buffer.from([ + 0x70, + 0x82, + 0xc4, + 0x03 + ]); + targetTransaction.nExpiryHeight = expiryHeight; + targetTransaction.extraData = Buffer.from([0x00]); + } + }); }) .then(() => { for (let i = 0; i < inputs.length; i++) { @@ -604,7 +640,8 @@ btc.createPaymentTransactionNew( true, targetTransaction, trustedInputs, - true + true, + !!expiryHeight ).then(() => doIf(!resuming && typeof changePath != "undefined", () => { // $FlowFixMe @@ -613,6 +650,11 @@ btc.createPaymentTransactionNew( ) ) ) + .then(() => + doIf(!!expiryHeight, () => + this.signTransaction("", undefined, SIGHASH_ALL, expiryHeight) + ) + ) .then(() => // Do the second run with the individual transaction foreach(inputs, (input, i) => { @@ -627,8 +669,10 @@ btc.createPaymentTransactionNew( Buffer.from([OP_EQUALVERIFY, OP_CHECKSIG]) ]); let pseudoTX = Object.assign({}, targetTransaction); - let pseudoTrustedInputs = segwit ? [trustedInputs[i]] : trustedInputs; - if (segwit) { + let pseudoTrustedInputs = useBip143 + ? [trustedInputs[i]] + : trustedInputs; + if (useBip143) { pseudoTX.inputs = [{ ...pseudoTX.inputs[i], script }]; } else { pseudoTX.inputs[i].script = script; @@ -637,7 +681,8 @@ btc.createPaymentTransactionNew( !useBip143 && firstRun, pseudoTX, pseudoTrustedInputs, - useBip143 + useBip143, + !!expiryHeight ) .then(() => doIf(!useBip143, () => @@ -648,7 +693,12 @@ btc.createPaymentTransactionNew( ) ) .then(() => - this.signTransaction(associatedKeysets[i], lockTime, sigHashType) + this.signTransaction( + associatedKeysets[i], + lockTime, + sigHashType, + expiryHeight + ) ) .then(signature => { signatures.push(signature); @@ -713,6 +763,13 @@ btc.createPaymentTransactionNew( } result = Buffer.concat([result, witness]); } + if (expiryHeight) { + result = Buffer.concat([ + result, + targetTransaction.nExpiryHeight || Buffer.alloc(0), + targetTransaction.extraData || Buffer.alloc(0) + ]); + } result = Buffer.concat([result, lockTimeBuffer]); @@ -875,8 +932,12 @@ const tx1 = btc.splitTransaction("01000000014ea60aeac5252c14291d428915bd7ccd1bfc var witness = false; let offset = 0; let timestamp = Buffer.alloc(0); + let nExpiryHeight = Buffer.alloc(0); + let nVersionGroupId = Buffer.alloc(0); + let extraData = Buffer.alloc(0); const transaction = Buffer.from(transactionHex, "hex"); const version = transaction.slice(offset, offset + 4); + const overwinter = version.equals(Buffer.from([0x03, 0x00, 0x00, 0x80])); offset += 4; if ( !hasTimestamp && @@ -890,6 +951,10 @@ const tx1 = btc.splitTransaction("01000000014ea60aeac5252c14291d428915bd7ccd1bfc timestamp = transaction.slice(offset, 4 + offset); offset += 4; } + if (overwinter) { + nVersionGroupId = transaction.slice(offset, 4 + offset); + offset += 4; + } let varint = this.getVarint(transaction, offset); const numberInputs = varint[0]; offset += varint[1]; @@ -923,13 +988,22 @@ const tx1 = btc.splitTransaction("01000000014ea60aeac5252c14291d428915bd7ccd1bfc } else { locktime = transaction.slice(offset, offset + 4); } + if (overwinter) { + offset += 4; + nExpiryHeight = transaction.slice(offset, offset + 4); + offset += 4; + extraData = transaction.slice(offset); + } return { version, inputs, outputs, locktime, witness: witnessScript, - timestamp + timestamp, + nVersionGroupId, + nExpiryHeight, + extraData }; } @@ -985,13 +1059,16 @@ const outputScript = btc.serializeTransactionOutputs(tx1).toString('hex'); outputBuffer = Buffer.concat([ outputBuffer, (useWitness && transaction.witness) || Buffer.alloc(0), - transaction.locktime + transaction.locktime, + transaction.nExpiryHeight || Buffer.alloc(0), + transaction.extraData || Buffer.alloc(0) ]); } return Buffer.concat([ transaction.version, timestamp ? timestamp : Buffer.alloc(0), + transaction.nVersionGroupId || Buffer.alloc(0), useWitness ? Buffer.from("0001", "hex") : Buffer.alloc(0), this.createVarint(transaction.inputs.length), inputBuffer, @@ -1045,5 +1122,8 @@ type Transaction = { outputs?: TransactionOutput[], locktime?: Buffer, witness?: Buffer, - timestamp?: Buffer + timestamp?: Buffer, + nVersionGroupId?: Buffer, + nExpiryHeight?: Buffer, + extraData?: Buffer }; diff --git a/packages/hw-app-eth/package.json b/packages/hw-app-eth/package.json index 720fff2c1..6e971e046 100644 --- a/packages/hw-app-eth/package.json +++ b/packages/hw-app-eth/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-app-eth", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Ethereum Application API", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/Eth.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0" + "@ledgerhq/hw-transport": "^4.19.0" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/hw-app-str/package.json b/packages/hw-app-str/package.json index 821bcfe02..398bd9cb2 100644 --- a/packages/hw-app-str/package.json +++ b/packages/hw-app-str/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-app-str", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Stellar Application API", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/Str.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "base32.js": "^0.1.0", "sha.js": "^2.3.6", "tweetnacl": "^1.0.0" diff --git a/packages/hw-app-xrp/package.json b/packages/hw-app-xrp/package.json index 51e84388a..020bff632 100644 --- a/packages/hw-app-xrp/package.json +++ b/packages/hw-app-xrp/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-app-xrp", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Ripple Application API", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/Xrp.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "bip32-path": "0.4.2" }, "devDependencies": { diff --git a/packages/hw-hid-cli/package.json b/packages/hw-hid-cli/package.json index 4cd422d5e..a42a363be 100644 --- a/packages/hw-hid-cli/package.json +++ b/packages/hw-hid-cli/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-hid-cli", - "version": "4.16.0", + "version": "4.19.1", "description": "Ledger Hardware Wallet cli utility to send apdu to hid", "keywords": [ "Ledger", @@ -29,7 +29,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport-node-hid": "^4.16.0" + "@ledgerhq/hw-transport-node-hid": "^4.19.1" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/hw-http-proxy-devserver/package.json b/packages/hw-http-proxy-devserver/package.json index a80c641d3..77fb8937c 100644 --- a/packages/hw-http-proxy-devserver/package.json +++ b/packages/hw-http-proxy-devserver/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-http-proxy-devserver", - "version": "4.16.0", + "version": "4.19.1", "description": "Ledger Hardware Wallet debug communication layer http proxy (for development only)", "keywords": [ "Ledger", @@ -29,7 +29,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport-node-hid": "^4.16.0", + "@ledgerhq/hw-transport-node-hid": "^4.19.1", "body-parser": "^1.18.2", "cors": "^2.8.4", "express": "^4.16.3" diff --git a/packages/hw-transport-http/package.json b/packages/hw-transport-http/package.json index 7bea7289f..7637a511f 100644 --- a/packages/hw-transport-http/package.json +++ b/packages/hw-transport-http/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-transport-http", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet communication layer over http", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/HttpTransport.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0" + "@ledgerhq/hw-transport": "^4.19.0" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/hw-transport-mocker/package.json b/packages/hw-transport-mocker/package.json index 43f5a7209..db6c2d9a2 100644 --- a/packages/hw-transport-mocker/package.json +++ b/packages/hw-transport-mocker/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-transport-mocker", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet mocker utilities used for tests", "keywords": [ "Ledger", @@ -23,7 +23,7 @@ "main": "lib/index.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0" + "@ledgerhq/hw-transport": "^4.19.0" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/hw-transport-node-hid/package.json b/packages/hw-transport-node-hid/package.json index 339684882..96f1e8ae4 100644 --- a/packages/hw-transport-node-hid/package.json +++ b/packages/hw-transport-node-hid/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-transport-node-hid", - "version": "4.16.0", + "version": "4.19.1", "description": "Ledger Hardware Wallet Node implementation of the communication layer, using node-hid", "keywords": [ "Ledger", @@ -25,7 +25,7 @@ "main": "lib/TransportNodeHid.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "node-hid": "^0.7.2" }, "devDependencies": { diff --git a/packages/hw-transport-node-hid/src/TransportNodeHid.js b/packages/hw-transport-node-hid/src/TransportNodeHid.js index 45dfe54e4..1e86aff9d 100644 --- a/packages/hw-transport-node-hid/src/TransportNodeHid.js +++ b/packages/hw-transport-node-hid/src/TransportNodeHid.js @@ -26,7 +26,8 @@ function defer(): Defer { return { promise, resolve, reject }; } -let listenDevicesPollingInterval = 100; +let listenDevicesPollingInterval = 500; +let listenDevicesPollingSkip = () => false; /** * node-hid Transport implementation @@ -39,21 +40,18 @@ export default class TransportNodeHid extends Transport { device: HID.HID; ledgerTransport: boolean; timeout: number; - debug: boolean; exchangeStack: Array<*>; constructor( device: HID.HID, - ledgerTransport: boolean = true, - timeout: number = 0, - debug: boolean = false + ledgerTransport: boolean = true, // FIXME not used? + timeout: number = 0 // FIXME not used? ) { super(); this.device = device; this.ledgerTransport = ledgerTransport; this.timeout = timeout; this.exchangeStack = []; - this.debug = debug; } static isSupported = (): Promise => @@ -66,6 +64,10 @@ export default class TransportNodeHid extends Transport { listenDevicesPollingInterval = delay; }; + static setListenDevicesPollingSkip = (conditionToSkip: () => boolean) => { + listenDevicesPollingSkip = conditionToSkip; + }; + /** */ static listen = ( @@ -81,7 +83,10 @@ export default class TransportNodeHid extends Transport { } } }); - const { events, stop } = listenDevices(listenDevicesPollingInterval); + const { events, stop } = listenDevices( + listenDevicesPollingInterval, + listenDevicesPollingSkip + ); const onAdd = device => { if (unsubscribed || !device) return; @@ -238,8 +243,9 @@ export default class TransportNodeHid extends Transport { const deferred = this.exchangeStack[0]; const send = content => { - if (this.debug) { - console.log("=>" + content.toString("hex")); + const { debug } = this; + if (debug) { + debug("=>" + content.toString("hex")); } const data = [0x00]; for (let i = 0; i < content.length; i++) { @@ -255,8 +261,9 @@ export default class TransportNodeHid extends Transport { if (err || !res) reject(err); else { const buffer = Buffer.from(res); - if (this.debug) { - console.log("<=" + buffer.toString("hex")); + const { debug } = this; + if (debug) { + debug("<=" + buffer.toString("hex")); } resolve(buffer); } diff --git a/packages/hw-transport-node-hid/src/listenDevices.js b/packages/hw-transport-node-hid/src/listenDevices.js index dc877f1e8..582fe64d9 100644 --- a/packages/hw-transport-node-hid/src/listenDevices.js +++ b/packages/hw-transport-node-hid/src/listenDevices.js @@ -4,7 +4,8 @@ import EventEmitter from "events"; import getDevices from "./getDevices"; export default ( - delay: number = 100 + delay: number, + listenDevicesPollingSkip: () => boolean ): { events: EventEmitter, stop: () => void @@ -27,7 +28,7 @@ export default ( let lastDevices = getFlatDevices(); const checkDevices = () => { - timeoutDetection = setTimeout(() => { + if (!listenDevicesPollingSkip()) { const currentDevices = getFlatDevices(); const newDevices = currentDevices.filter(d => !lastDevices.includes(d)); @@ -48,12 +49,11 @@ export default ( } lastDevices = currentDevices; - - checkDevices(); - }, delay); + } + setTimeout(checkDevices, delay); }; - checkDevices(); + timeoutDetection = setTimeout(checkDevices, delay); return { stop: () => { diff --git a/packages/hw-transport-u2f/package.json b/packages/hw-transport-u2f/package.json index 9e0f7b963..3388964cb 100644 --- a/packages/hw-transport-u2f/package.json +++ b/packages/hw-transport-u2f/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-transport-u2f", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Web implementation of the communication layer, using U2F api", "keywords": [ "Ledger", @@ -26,7 +26,7 @@ "main": "lib/TransportU2F.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "u2f-api": "0.2.7" }, "devDependencies": { diff --git a/packages/hw-transport-u2f/src/TransportU2F.js b/packages/hw-transport-u2f/src/TransportU2F.js index 7deaac5d3..e4e7b28c7 100644 --- a/packages/hw-transport-u2f/src/TransportU2F.js +++ b/packages/hw-transport-u2f/src/TransportU2F.js @@ -33,7 +33,7 @@ const normal64 = (base64: string) => function attemptExchange( apdu: Buffer, timeoutMillis: number, - debug: boolean, + debug: *, scrambleKey: Buffer ): Promise { const keyHandle = wrapApdu(apdu, scrambleKey); @@ -48,7 +48,7 @@ function attemptExchange( appId: location.origin }; if (debug) { - console.log("=> " + apdu.toString("hex")); + debug("=> " + apdu.toString("hex")); } return sign(signRequest, timeoutMillis / 1000).then(response => { const { signatureData } = response; @@ -56,7 +56,7 @@ function attemptExchange( const data = Buffer.from(normal64(signatureData), "base64"); const result = data.slice(5); if (debug) { - console.log("<= " + result.toString("hex")); + debug("<= " + result.toString("hex")); } return result; } else { diff --git a/packages/hw-transport/package.json b/packages/hw-transport/package.json index ba535860c..4c9a0265e 100644 --- a/packages/hw-transport/package.json +++ b/packages/hw-transport/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/hw-transport", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet common interface of the communication layer", "keywords": [ "Ledger", diff --git a/packages/hw-transport/src/Transport.js b/packages/hw-transport/src/Transport.js index 566bbcc6d..7bceaa3a1 100644 --- a/packages/hw-transport/src/Transport.js +++ b/packages/hw-transport/src/Transport.js @@ -121,7 +121,7 @@ TransportStatusError.prototype = new Error(); * it can be for instance an ID, an file path, a URL,... */ export default class Transport { - debug: boolean = false; + debug: ?(log: string) => void = null; exchangeTimeout: number = 30000; /** @@ -221,8 +221,13 @@ TransportFoo.open(descriptor).then(transport => ...) /** * Enable or not logs of the binary exchange */ - setDebugMode(debug: boolean) { - this.debug = debug; + setDebugMode(debug: boolean | ((log: string) => void)) { + this.debug = + typeof debug === "function" + ? debug + : debug + ? log => console.log(log) + : null; } /** diff --git a/packages/react-native-hid/package.json b/packages/react-native-hid/package.json index cc7dff64c..80caed013 100755 --- a/packages/react-native-hid/package.json +++ b/packages/react-native-hid/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/react-native-hid", - "version": "4.15.0", + "version": "4.19.0", "nativePackage": true, "description": "Ledger Hardware Wallet Web implementation of the communication layer, using U2F api", "keywords": [ @@ -27,7 +27,7 @@ "main": "lib/index.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0" + "@ledgerhq/hw-transport": "^4.19.0" }, "devDependencies": { "flow-bin": "^0.68.0", diff --git a/packages/react-native-hw-transport-ble/package.json b/packages/react-native-hw-transport-ble/package.json index 76c1308d7..55848152b 100644 --- a/packages/react-native-hw-transport-ble/package.json +++ b/packages/react-native-hw-transport-ble/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/react-native-hw-transport-ble", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet bluetooth BLE implementation of the transport layer", "keywords": [ "Ledger", @@ -26,7 +26,7 @@ "react-native-ble-plx": "^0.8.0" }, "dependencies": { - "@ledgerhq/hw-transport": "^4.15.0", + "@ledgerhq/hw-transport": "^4.19.0", "invariant": "^2.2.4" }, "devDependencies": { diff --git a/packages/test/package.json b/packages/test/package.json index 5d91d35c1..ddfc805c2 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,17 +1,17 @@ { "private": true, "name": "@ledgerhq/test", - "version": "4.16.0", + "version": "4.19.1", "main": "index.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-app-ada": "^4.16.0", - "@ledgerhq/hw-app-btc": "^4.15.0", - "@ledgerhq/hw-app-eth": "^4.15.0", - "@ledgerhq/hw-app-str": "^4.15.0", - "@ledgerhq/hw-app-xrp": "^4.15.0", - "@ledgerhq/hw-transport-mocker": "^4.15.0", - "@ledgerhq/hw-transport-node-hid": "^4.16.0", + "@ledgerhq/hw-app-ada": "^4.19.1", + "@ledgerhq/hw-app-btc": "^4.19.0", + "@ledgerhq/hw-app-eth": "^4.19.0", + "@ledgerhq/hw-app-str": "^4.19.0", + "@ledgerhq/hw-app-xrp": "^4.19.0", + "@ledgerhq/hw-transport-mocker": "^4.19.0", + "@ledgerhq/hw-transport-node-hid": "^4.19.1", "budo": "^11.0.1" }, "devDependencies": { diff --git a/packages/web3-subprovider/package.json b/packages/web3-subprovider/package.json index c0f1f4830..4345e1873 100644 --- a/packages/web3-subprovider/package.json +++ b/packages/web3-subprovider/package.json @@ -1,6 +1,6 @@ { "name": "@ledgerhq/web3-subprovider", - "version": "4.15.0", + "version": "4.19.0", "description": "Ledger Hardware Wallet Ethereum Web3 subprovider", "keywords": [ "Ledger", @@ -28,9 +28,9 @@ "main": "lib/index.js", "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-app-eth": "^4.15.0", - "@ledgerhq/hw-transport": "^4.15.0", - "@ledgerhq/hw-transport-u2f": "^4.15.0", + "@ledgerhq/hw-app-eth": "^4.19.0", + "@ledgerhq/hw-transport": "^4.19.0", + "@ledgerhq/hw-transport-u2f": "^4.19.0", "ethereumjs-tx": "^1.3.3", "strip-hex-prefix": "^1.0.0", "web3-provider-engine": "^14.0.2" diff --git a/yarn.lock b/yarn.lock index 6794b7b4d..e62e20fe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -285,8 +285,8 @@ aproba@^1.0.3: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -1828,6 +1828,17 @@ budo@^11.0.1: ws "^1.1.1" xtend "^4.0.0" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + +buffer-alloc@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-equal@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" @@ -1836,6 +1847,10 @@ buffer-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + buffer-from@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" @@ -3019,6 +3034,10 @@ deep-equal@^1.0.1, deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -4135,8 +4154,8 @@ expand-range@^1.8.1: fill-range "^2.1.0" expand-template@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.0.tgz#e09efba977bf98f9ee0ed25abd0c692e02aec3fc" + version "1.1.1" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" @@ -4555,6 +4574,10 @@ from2@^2.0.3: inherits "^2.0.1" readable-stream "^2.0.0" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + fs-extra@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" @@ -7266,7 +7289,7 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.0.5, nan@^2.0.7, nan@^2.2.1, nan@^2.3.0, nan@^2.6.2, nan@^2.9.2: +nan@^2.0.5, nan@^2.0.7, nan@^2.10.0, nan@^2.2.1, nan@^2.3.0, nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -7322,8 +7345,8 @@ no-case@^2.2.0: lower-case "^1.1.1" node-abi@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.3.0.tgz#f3d554d6ac72a9ee16f0f4dc9548db7c08de4986" + version "2.4.3" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.3.tgz#43666b7b17e57863e572409edbb82115ac7af28b" dependencies: semver "^5.4.1" @@ -7347,12 +7370,12 @@ node-forge@^0.7.1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" node-hid@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-0.7.2.tgz#15025cdea2e9756aca2de7266529996d40e52c56" + version "0.7.3" + resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-0.7.3.tgz#736e9a4dee5eec96c20fbe301e0311bb185cb2f4" dependencies: bindings "^1.3.0" - nan "^2.6.2" - prebuild-install "^2.2.2" + nan "^2.10.0" + prebuild-install "^4.0.0" node-int64@^0.4.0: version "0.4.0" @@ -8435,9 +8458,9 @@ posthtml@^0.11.2, posthtml@^0.11.3: posthtml-parser "^0.3.3" posthtml-render "^1.1.0" -prebuild-install@^2.2.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.5.1.tgz#0f234140a73760813657c413cdccdda58296b1da" +prebuild-install@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-4.0.0.tgz#206ce8106ce5efa4b6cf062fc8a0a7d93c17f3a8" dependencies: detect-libc "^1.0.3" expand-template "^1.0.2" @@ -8720,7 +8743,7 @@ raw-body@~1.1.0: bytes "1" string_decoder "0.10" -rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: +rc@^1.0.1, rc@^1.1.7: version "1.2.6" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092" dependencies: @@ -8729,6 +8752,15 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +rc@^1.1.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-dev-utils@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613" @@ -8893,7 +8925,7 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@~2.3.3: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@~2.3.3: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -9633,8 +9665,8 @@ simple-concat@^1.0.0: resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" simple-get@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.7.0.tgz#ad37f926d08129237ff08c4f2edfd6f10e0380b5" + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" dependencies: decompress-response "^3.3.0" once "^1.3.1" @@ -9987,7 +10019,7 @@ string-width@^1.0.0, string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -10266,8 +10298,8 @@ tape@^4.4.0, tape@^4.6.3, tape@^4.8.0: through "~2.3.8" tar-fs@^1.13.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.0.tgz#e877a25acbcc51d8c790da1c57c9cf439817b896" + version "1.16.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" dependencies: chownr "^1.0.1" mkdirp "^0.5.1" @@ -10288,12 +10320,15 @@ tar-pack@^3.4.0: uid-number "^0.0.6" tar-stream@^1.1.2: - version "1.5.5" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" + version "1.6.1" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395" dependencies: bl "^1.0.0" + buffer-alloc "^1.1.0" end-of-stream "^1.0.0" - readable-stream "^2.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.0" xtend "^4.0.0" tar@^2.2.1: @@ -10458,6 +10493,10 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" +to-buffer@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -11326,10 +11365,10 @@ which@^1.2.12, which@^1.2.14, which@^1.2.4, which@^1.2.9, which@^1.3.0: isexe "^2.0.0" wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" dependencies: - string-width "^1.0.2" + string-width "^1.0.2 || 2" widest-line@^2.0.0: version "2.0.0"