diff --git a/bundle.js b/bundle.js index a4303605..97d6a846 100644 --- a/bundle.js +++ b/bundle.js @@ -94,6 +94,12 @@ var LedgerBridge = function () { case 'ledger-sign-typed-data': _this.signTypedData(replyAction, params.hdPath, params.domainSeparatorHex, params.hashStructMessageHex, messageId); break; + case 'ledger-start-polling': + _this.startConnectionPolling(replyAction, messageId); + break; + case 'ledger-stop-polling': + _this.stopConnectionPolling(replyAction, messageId); + break; } } }, false); @@ -187,30 +193,54 @@ var LedgerBridge = function () { this.app = new _hwAppEth2.default(this.transport); } - // The U2F transport is deprecated and the following block will - // throw an error in Firefox, so we cannot detect true - // connection status with U2F - if (this.transportType != SUPPORTED_TRANSPORT_TYPES.U2F) { - // Upon Ledger disconnect from user's machine, signal disconnect - this.transport.on('disconnect', function () { - return _this3.onDisconnect(); - }); - - // We need to poll for connection status because going into - // sleep mode doesn't trigger the "disconnect" event - var connected = await this.checkConnectionStatus(); - this.pollingInterval = setInterval(function () { - _this3.checkConnectionStatus(); - }, POLLING_INTERVAL); - } + // Upon Ledger disconnect from user's machine, signal disconnect + this.transport.on('disconnect', function () { + return _this3.onDisconnect(); + }); } catch (e) { console.log('LEDGER:::CREATE APP ERROR', e); throw e; } } + }, { + key: 'startConnectionPolling', + value: async function startConnectionPolling(replyAction, messageId) { + var _this4 = this; + + // Prevent the possibility that there could be more than one + // polling interval if stopConnectionPolling hasn't been called + if (this.pollingInterval) { + return false; + } + + // The U2F transport is deprecated and the following block will + // throw an error in Firefox, so we cannot detect true + // connection status with U2F + if (this.transportType !== SUPPORTED_TRANSPORT_TYPES.U2F) { + // We need to poll for connection status because going into + // sleep mode doesn't trigger the "disconnect" event + var connected = await this.checkConnectionStatus(); + this.pollingInterval = setInterval(function () { + _this4.checkConnectionStatus(); + }, POLLING_INTERVAL); + } + } + }, { + key: 'stopConnectionPolling', + value: function stopConnectionPolling(replyAction, messageId) { + if (this.pollingInterval) { + clearInterval(this.pollingInterval); + } + } }, { key: 'checkConnectionStatus', value: async function checkConnectionStatus() { + // If there's no app or transport, leave and signal disconnect + if (!this.app || !this.transport) { + this.onDisconnect(); + return false; + } + // Ensure the correct (Ethereum) app is open; if not, immediately kill // the connection as the wrong app is open and switching apps will call // a disconnect from within the Ledger API @@ -234,20 +264,21 @@ var LedgerBridge = function () { } else { // Wrong app this.onDisconnect(); + return false; } } catch (e) { console.log('LEDGER:::Transport check error', e); this.onDisconnect(); throw e; } - - return false; } }, { key: 'updateTransportTypePreference', value: function updateTransportTypePreference(replyAction, transportType, messageId) { - this.transportType = transportType; - this.cleanUp(); + if (transportType !== this.transportType) { + this.transportType = transportType; + this.cleanUp(); + } this.sendMessageToExtension({ action: replyAction, success: true, @@ -262,9 +293,6 @@ var LedgerBridge = function () { await this.transport.close(); this.transport = null; } - if (this.pollingInterval) { - clearInterval(this.pollingInterval); - } if (replyAction) { this.sendMessageToExtension({ action: replyAction, diff --git a/ledger-bridge.js b/ledger-bridge.js index c9938a07..c3654050 100644 --- a/ledger-bridge.js +++ b/ledger-bridge.js @@ -61,6 +61,12 @@ export default class LedgerBridge { case 'ledger-sign-typed-data': this.signTypedData(replyAction, params.hdPath, params.domainSeparatorHex, params.hashStructMessageHex, messageId) break + case 'ledger-start-polling': + this.startConnectionPolling(replyAction, messageId) + break + case 'ledger-stop-polling': + this.stopConnectionPolling(replyAction, messageId) + break } } }, false) @@ -143,27 +149,48 @@ export default class LedgerBridge { this.app = new LedgerEth(this.transport) } - // The U2F transport is deprecated and the following block will - // throw an error in Firefox, so we cannot detect true - // connection status with U2F - if (this.transportType != SUPPORTED_TRANSPORT_TYPES.U2F) { - // Upon Ledger disconnect from user's machine, signal disconnect - this.transport.on('disconnect', () => this.onDisconnect()) - - // We need to poll for connection status because going into - // sleep mode doesn't trigger the "disconnect" event - const connected = await this.checkConnectionStatus() - this.pollingInterval = setInterval(() => { - this.checkConnectionStatus() - }, POLLING_INTERVAL); - } + // Upon Ledger disconnect from user's machine, signal disconnect + this.transport.on('disconnect', () => this.onDisconnect()) } catch (e) { console.log('LEDGER:::CREATE APP ERROR', e) throw e } } + async startConnectionPolling(replyAction, messageId) { + // Prevent the possibility that there could be more than one + // polling interval if stopConnectionPolling hasn't been called + if(this.pollingInterval) { + return false + } + + // The U2F transport is deprecated and the following block will + // throw an error in Firefox, so we cannot detect true + // connection status with U2F + if (this.transportType !== SUPPORTED_TRANSPORT_TYPES.U2F) { + // We need to poll for connection status because going into + // sleep mode doesn't trigger the "disconnect" event + const connected = await this.checkConnectionStatus() + this.pollingInterval = setInterval(() => { + this.checkConnectionStatus() + }, POLLING_INTERVAL); + } + } + + stopConnectionPolling(replyAction, messageId) { + if (this.pollingInterval) { + clearInterval(this.pollingInterval) + } + } + async checkConnectionStatus() { + // If there's no app or transport, leave and signal disconnect + if(!this.app || !this.transport) { + this.onDisconnect(); + return false; + } + + // Ensure the correct (Ethereum) app is open; if not, immediately kill // the connection as the wrong app is open and switching apps will call // a disconnect from within the Ledger API @@ -187,6 +214,7 @@ export default class LedgerBridge { else { // Wrong app this.onDisconnect() + return false } } catch(e) { @@ -194,13 +222,13 @@ export default class LedgerBridge { this.onDisconnect() throw e } - - return false } updateTransportTypePreference (replyAction, transportType, messageId) { - this.transportType = transportType - this.cleanUp() + if (transportType !== this.transportType) { + this.transportType = transportType + this.cleanUp() + } this.sendMessageToExtension({ action: replyAction, success: true, @@ -214,9 +242,6 @@ export default class LedgerBridge { await this.transport.close() this.transport = null } - if (this.pollingInterval) { - clearInterval(this.pollingInterval) - } if (replyAction) { this.sendMessageToExtension({ action: replyAction,