Skip to content

Commit 62bae55

Browse files
committed
Reimplement polling for connected status
1 parent 58ddedf commit 62bae55

File tree

2 files changed

+98
-52
lines changed

2 files changed

+98
-52
lines changed

bundle.js

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ var SUPPORTED_TRANSPORT_TYPES = {
4242
var TRANSPORT_CHECK_DELAY = 1000;
4343
var TRANSPORT_CHECK_LIMIT = 120;
4444

45+
var POLLING_INTERVAL = 5000;
46+
4547
var LedgerBridge = function () {
4648
function LedgerBridge() {
4749
_classCallCheck(this, LedgerBridge);
@@ -189,39 +191,57 @@ var LedgerBridge = function () {
189191
// throw an error in Firefox, so we cannot detect true
190192
// connection status with U2F
191193
if (this.transportType != SUPPORTED_TRANSPORT_TYPES.U2F) {
192-
// Ensure the correct (Ethereum) app is open; if not, immediately kill
193-
// the connection as the wrong app is open and switching apps will call
194-
// a disconnect from within the Ledger API
195-
try {
196-
var sampleSendResult = await this.transport.send(0xb0, 0x01, 0x00, 0x00);
197-
var bufferResult = Buffer.from(sampleSendResult).toString();
198-
// Ensures the correct app is open
199-
if (bufferResult.includes('Ethereum')) {
200-
// Ensure the device is unlocked by requesting an account
201-
// An error of `6b0c` will throw if locked
202-
var _ref = await this.app.getAddress('44\'/60\'/0\'/0', false, true),
203-
address = _ref.address;
204-
205-
if (address) {
206-
this.sendConnectionMessage(true);
207-
this.transport.on('disconnect', function () {
208-
return _this3.onDisconnect();
209-
});
210-
} else {
211-
this.onDisconnect();
212-
throw Error('LEDGER:::Device appears to be locked');
213-
}
214-
}
215-
} catch (e) {
216-
console.log('LEDGER:::Transport check error', e);
194+
// Upon Ledger disconnect from user's machine, signal disconnect
195+
this.transport.on('disconnect', function () {
196+
return _this3.onDisconnect();
197+
});
198+
199+
// We need to poll for connection status because going into
200+
// sleep mode doesn't trigger the "disconnect" event
201+
var connected = await this.checkConnectionStatus();
202+
this.pollingInterval = setInterval(function () {
203+
_this3.checkConnectionStatus();
204+
}, POLLING_INTERVAL);
205+
}
206+
} catch (e) {
207+
console.log('LEDGER:::CREATE APP ERROR', e);
208+
throw e;
209+
}
210+
}
211+
}, {
212+
key: 'checkConnectionStatus',
213+
value: async function checkConnectionStatus() {
214+
// Ensure the correct (Ethereum) app is open; if not, immediately kill
215+
// the connection as the wrong app is open and switching apps will call
216+
// a disconnect from within the Ledger API
217+
try {
218+
var sampleSendResult = await this.transport.send(0xb0, 0x01, 0x00, 0x00);
219+
var bufferResult = Buffer.from(sampleSendResult).toString();
220+
// Ensures the correct app is open
221+
if (bufferResult.includes('Ethereum')) {
222+
// Ensure the device is unlocked by requesting an account
223+
// An error of `6b0c` will throw if locked
224+
var _ref = await this.app.getAddress('44\'/60\'/0\'/0', false, true),
225+
address = _ref.address;
226+
227+
if (address) {
228+
this.sendConnectionMessage(true);
229+
return true;
230+
} else {
217231
this.onDisconnect();
218-
throw e;
232+
throw Error('LEDGER:::Device appears to be locked');
219233
}
234+
} else {
235+
// Wrong app
236+
this.onDisconnect();
220237
}
221238
} catch (e) {
222-
console.log('LEDGER:::CREATE APP ERROR', e);
239+
console.log('LEDGER:::Transport check error', e);
240+
this.onDisconnect();
223241
throw e;
224242
}
243+
244+
return false;
225245
}
226246
}, {
227247
key: 'updateTransportTypePreference',
@@ -360,6 +380,9 @@ var LedgerBridge = function () {
360380
key: 'onDisconnect',
361381
value: function onDisconnect() {
362382
this.cleanUp();
383+
if (this.pollingInterval) {
384+
clearInterval(this.pollingInterval);
385+
}
363386
this.sendConnectionMessage(false);
364387
}
365388
}, {

ledger-bridge.js

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const BRIDGE_URL = 'ws://localhost:8435'
1919
const TRANSPORT_CHECK_DELAY = 1000
2020
const TRANSPORT_CHECK_LIMIT = 120
2121

22+
const POLLING_INTERVAL = 5000
23+
2224
export default class LedgerBridge {
2325
constructor () {
2426
this.addEventListeners()
@@ -145,37 +147,55 @@ export default class LedgerBridge {
145147
// throw an error in Firefox, so we cannot detect true
146148
// connection status with U2F
147149
if (this.transportType != SUPPORTED_TRANSPORT_TYPES.U2F) {
148-
// Ensure the correct (Ethereum) app is open; if not, immediately kill
149-
// the connection as the wrong app is open and switching apps will call
150-
// a disconnect from within the Ledger API
151-
try {
152-
const sampleSendResult = await this.transport.send(0xb0, 0x01, 0x00, 0x00)
153-
const bufferResult = Buffer.from(sampleSendResult).toString()
154-
// Ensures the correct app is open
155-
if(bufferResult.includes('Ethereum')) {
156-
// Ensure the device is unlocked by requesting an account
157-
// An error of `6b0c` will throw if locked
158-
const { address } = await this.app.getAddress(`44'/60'/0'/0`, false, true)
159-
if (address) {
160-
this.sendConnectionMessage(true)
161-
this.transport.on('disconnect', () => this.onDisconnect())
162-
}
163-
else {
164-
this.onDisconnect()
165-
throw Error('LEDGER:::Device appears to be locked')
166-
}
167-
}
150+
// Upon Ledger disconnect from user's machine, signal disconnect
151+
this.transport.on('disconnect', () => this.onDisconnect())
152+
153+
// We need to poll for connection status because going into
154+
// sleep mode doesn't trigger the "disconnect" event
155+
const connected = await this.checkConnectionStatus()
156+
this.pollingInterval = setInterval(() => {
157+
this.checkConnectionStatus()
158+
}, POLLING_INTERVAL);
159+
}
160+
} catch (e) {
161+
console.log('LEDGER:::CREATE APP ERROR', e)
162+
throw e
163+
}
164+
}
165+
166+
async checkConnectionStatus() {
167+
// Ensure the correct (Ethereum) app is open; if not, immediately kill
168+
// the connection as the wrong app is open and switching apps will call
169+
// a disconnect from within the Ledger API
170+
try {
171+
const sampleSendResult = await this.transport.send(0xb0, 0x01, 0x00, 0x00)
172+
const bufferResult = Buffer.from(sampleSendResult).toString()
173+
// Ensures the correct app is open
174+
if(bufferResult.includes('Ethereum')) {
175+
// Ensure the device is unlocked by requesting an account
176+
// An error of `6b0c` will throw if locked
177+
const { address } = await this.app.getAddress(`44'/60'/0'/0`, false, true)
178+
if (address) {
179+
this.sendConnectionMessage(true)
180+
return true
168181
}
169-
catch(e) {
170-
console.log('LEDGER:::Transport check error', e)
182+
else {
171183
this.onDisconnect()
172-
throw e
184+
throw Error('LEDGER:::Device appears to be locked')
173185
}
174186
}
175-
} catch (e) {
176-
console.log('LEDGER:::CREATE APP ERROR', e)
187+
else {
188+
// Wrong app
189+
this.onDisconnect()
190+
}
191+
}
192+
catch(e) {
193+
console.log('LEDGER:::Transport check error', e)
194+
this.onDisconnect()
177195
throw e
178196
}
197+
198+
return false
179199
}
180200

181201
updateTransportTypePreference (replyAction, transportType, messageId) {
@@ -311,6 +331,9 @@ export default class LedgerBridge {
311331

312332
onDisconnect() {
313333
this.cleanUp()
334+
if (this.pollingInterval) {
335+
clearInterval(this.pollingInterval)
336+
}
314337
this.sendConnectionMessage(false)
315338
}
316339

0 commit comments

Comments
 (0)