@onekeyfe/hd-transport-web-device 1.1.34-alpha.1 → 1.1.34-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -37,6 +37,7 @@ export default class ElectronBleTransport {
|
|
|
37
37
|
path: string;
|
|
38
38
|
}>;
|
|
39
39
|
release(id: string): Promise<void>;
|
|
40
|
+
disconnect(id: string): Promise<void>;
|
|
40
41
|
private handleNotificationData;
|
|
41
42
|
call(uuid: string, name: string, data: Record<string, unknown>): Promise<import("@onekeyfe/hd-transport").MessageFromOneKey>;
|
|
42
43
|
private processNotificationPacket;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAAA,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AASxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAKlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AASF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,OAAO,CAAC,gBAAgB,CAA0B;IAGlD,OAAO,CAAC,WAAW,CAAsE;IAGzF,OAAO,CAAC,oBAAoB,CAAsC;IAGlE,OAAO,CAAC,kBAAkB,CAAsC;IAGhE,OAAO,CAAC,oBAAoB;IAmC5B,OAAO,CAAC,kBAAkB;IAmB1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAexC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAEA,SAAS,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAcpD,OAAO,CAAC,KAAK,EAAE,eAAe;;;;
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAAA,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AASxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAKlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AASF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,OAAO,CAAC,gBAAgB,CAA0B;IAGlD,OAAO,CAAC,WAAW,CAAsE;IAGzF,OAAO,CAAC,oBAAoB,CAAsC;IAGlE,OAAO,CAAC,kBAAkB,CAAsC;IAGhE,OAAO,CAAC,oBAAoB;IAmC5B,OAAO,CAAC,kBAAkB;IAmB1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAexC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAEA,SAAS,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAcpD,OAAO,CAAC,KAAK,EAAE,eAAe;;;;IA4F9B,OAAO,CAAC,EAAE,EAAE,MAAM;IAoBlB,UAAU,CAAC,EAAE,EAAE,MAAM;IAsB3B,OAAO,CAAC,sBAAsB;IA2BxB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA2EpE,OAAO,CAAC,yBAAyB;CAyDlC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ declare class ElectronBleTransport {
|
|
|
75
75
|
path: string;
|
|
76
76
|
}>;
|
|
77
77
|
release(id: string): Promise<void>;
|
|
78
|
+
disconnect(id: string): Promise<void>;
|
|
78
79
|
private handleNotificationData;
|
|
79
80
|
call(uuid: string, name: string, data: Record<string, unknown>): Promise<transport.MessageFromOneKey>;
|
|
80
81
|
private processNotificationPacket;
|
package/dist/index.js
CHANGED
|
@@ -461,6 +461,7 @@ class ElectronBleTransport {
|
|
|
461
461
|
if (forceCleanRunPromise && this.runPromise) {
|
|
462
462
|
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
463
463
|
}
|
|
464
|
+
let step = 'getDevice';
|
|
464
465
|
try {
|
|
465
466
|
if (!((_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle)) {
|
|
466
467
|
throw new Error('Noble BLE API not available');
|
|
@@ -469,6 +470,7 @@ class ElectronBleTransport {
|
|
|
469
470
|
if (!device) {
|
|
470
471
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Device ${uuid} not found`);
|
|
471
472
|
}
|
|
473
|
+
step = 'connect';
|
|
472
474
|
try {
|
|
473
475
|
yield window.desktopApi.nobleBle.connect(uuid);
|
|
474
476
|
this.connectedDevices.add(uuid);
|
|
@@ -477,6 +479,7 @@ class ElectronBleTransport {
|
|
|
477
479
|
this.handleBluetoothError(error);
|
|
478
480
|
}
|
|
479
481
|
this.dataBuffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
482
|
+
step = 'subscribe';
|
|
480
483
|
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
481
484
|
const cleanup = window.desktopApi.nobleBle.onNotification((deviceId, data) => {
|
|
482
485
|
if (deviceId === uuid) {
|
|
@@ -487,6 +490,9 @@ class ElectronBleTransport {
|
|
|
487
490
|
const disconnectCleanup = window.desktopApi.nobleBle.onDeviceDisconnected((disconnectedDevice) => {
|
|
488
491
|
var _a;
|
|
489
492
|
if (disconnectedDevice.id === uuid) {
|
|
493
|
+
if (this.runPromise) {
|
|
494
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected));
|
|
495
|
+
}
|
|
490
496
|
this.cleanupDeviceState(uuid);
|
|
491
497
|
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
|
|
492
498
|
name: disconnectedDevice.name,
|
|
@@ -505,6 +511,9 @@ class ElectronBleTransport {
|
|
|
505
511
|
}
|
|
506
512
|
catch (error) {
|
|
507
513
|
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.error('[Transport] Noble BLE acquire failed:', error);
|
|
514
|
+
if (step === 'subscribe') {
|
|
515
|
+
yield this.disconnect(uuid);
|
|
516
|
+
}
|
|
508
517
|
throw error;
|
|
509
518
|
}
|
|
510
519
|
});
|
|
@@ -512,23 +521,33 @@ class ElectronBleTransport {
|
|
|
512
521
|
release(id) {
|
|
513
522
|
var _a, _b, _c;
|
|
514
523
|
return __awaiter(this, void 0, void 0, function* () {
|
|
524
|
+
this.cleanupDeviceState(id);
|
|
515
525
|
try {
|
|
516
|
-
|
|
517
|
-
if ((_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle) {
|
|
518
|
-
yield window.desktopApi.nobleBle.unsubscribe(id);
|
|
519
|
-
}
|
|
520
|
-
if ((_b = window.desktopApi) === null || _b === void 0 ? void 0 : _b.nobleBle) {
|
|
521
|
-
yield window.desktopApi.nobleBle.disconnect(id);
|
|
522
|
-
}
|
|
523
|
-
this.cleanupDeviceState(id);
|
|
524
|
-
}
|
|
526
|
+
yield ((_c = (_b = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle) === null || _b === void 0 ? void 0 : _b.release) === null || _c === void 0 ? void 0 : _c.call(_b, id));
|
|
525
527
|
}
|
|
526
|
-
catch (
|
|
527
|
-
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.error('[Transport] Noble BLE release failed:', error);
|
|
528
|
-
this.cleanupDeviceState(id);
|
|
528
|
+
catch (_d) {
|
|
529
529
|
}
|
|
530
530
|
});
|
|
531
531
|
}
|
|
532
|
+
disconnect(id) {
|
|
533
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
534
|
+
const bounded = (ms, run) => __awaiter(this, void 0, void 0, function* () {
|
|
535
|
+
try {
|
|
536
|
+
yield Promise.race([
|
|
537
|
+
Promise.resolve(run()),
|
|
538
|
+
new Promise(resolve => {
|
|
539
|
+
setTimeout(resolve, ms);
|
|
540
|
+
}),
|
|
541
|
+
]);
|
|
542
|
+
}
|
|
543
|
+
catch (_a) {
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
yield bounded(2000, () => { var _a, _b; return (_b = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle) === null || _b === void 0 ? void 0 : _b.unsubscribe(id); });
|
|
547
|
+
yield bounded(3000, () => { var _a, _b; return (_b = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle) === null || _b === void 0 ? void 0 : _b.disconnect(id); });
|
|
548
|
+
this.cleanupDeviceState(id);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
532
551
|
handleNotificationData(deviceId, hexData) {
|
|
533
552
|
var _a, _b;
|
|
534
553
|
if (hexData === 'PAIRING_REJECTED') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.1.34-alpha.
|
|
3
|
+
"version": "1.1.34-alpha.2",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"lint:fix": "eslint . --fix"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@onekeyfe/hd-shared": "1.1.34-alpha.
|
|
24
|
-
"@onekeyfe/hd-transport": "1.1.34-alpha.
|
|
23
|
+
"@onekeyfe/hd-shared": "1.1.34-alpha.2",
|
|
24
|
+
"@onekeyfe/hd-transport": "1.1.34-alpha.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@onekeyfe/hd-transport-electron": "1.1.34-alpha.
|
|
27
|
+
"@onekeyfe/hd-transport-electron": "1.1.34-alpha.2",
|
|
28
28
|
"@types/w3c-web-usb": "^1.0.6",
|
|
29
29
|
"@types/web-bluetooth": "^0.0.17"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "dee167c35d191f3f4e02c4cb6228e1f926f929ec"
|
|
32
32
|
}
|
|
@@ -162,6 +162,9 @@ export default class ElectronBleTransport {
|
|
|
162
162
|
this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise));
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
// `step` pins down where a failed acquire died (subscribe = the
|
|
166
|
+
// encryption-gated characteristic, the broken-OS-bond signature).
|
|
167
|
+
let step = 'getDevice';
|
|
165
168
|
try {
|
|
166
169
|
if (!window.desktopApi?.nobleBle) {
|
|
167
170
|
throw new Error('Noble BLE API not available');
|
|
@@ -174,6 +177,7 @@ export default class ElectronBleTransport {
|
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
// Connect to device
|
|
180
|
+
step = 'connect';
|
|
177
181
|
try {
|
|
178
182
|
await window.desktopApi.nobleBle.connect(uuid);
|
|
179
183
|
this.connectedDevices.add(uuid);
|
|
@@ -185,6 +189,7 @@ export default class ElectronBleTransport {
|
|
|
185
189
|
this.dataBuffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
186
190
|
|
|
187
191
|
// Subscribe to notifications
|
|
192
|
+
step = 'subscribe';
|
|
188
193
|
await window.desktopApi.nobleBle.subscribe(uuid);
|
|
189
194
|
|
|
190
195
|
// Set up notification listener
|
|
@@ -201,6 +206,10 @@ export default class ElectronBleTransport {
|
|
|
201
206
|
const disconnectCleanup = window.desktopApi.nobleBle.onDeviceDisconnected(
|
|
202
207
|
(disconnectedDevice: any) => {
|
|
203
208
|
if (disconnectedDevice.id === uuid) {
|
|
209
|
+
// Fail a call blocked on a dead link instead of hanging.
|
|
210
|
+
if (this.runPromise) {
|
|
211
|
+
this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleDeviceDisconnected));
|
|
212
|
+
}
|
|
204
213
|
this.cleanupDeviceState(uuid);
|
|
205
214
|
|
|
206
215
|
// Trigger disconnect event
|
|
@@ -224,31 +233,54 @@ export default class ElectronBleTransport {
|
|
|
224
233
|
return { uuid, path: uuid };
|
|
225
234
|
} catch (error) {
|
|
226
235
|
this.Log?.error('[Transport] Noble BLE acquire failed:', error);
|
|
236
|
+
if (step === 'subscribe') {
|
|
237
|
+
// Broken-bond signature: tear the link down so the next attempt
|
|
238
|
+
// cold-connects and macOS can re-negotiate the bond.
|
|
239
|
+
await this.disconnect(uuid);
|
|
240
|
+
}
|
|
227
241
|
throw error;
|
|
228
242
|
}
|
|
229
243
|
}
|
|
230
244
|
|
|
231
245
|
async release(id: string) {
|
|
246
|
+
// Logical release only — the link and subscription stay up for reuse; the
|
|
247
|
+
// main process idle timer does the physical disconnect. Hard teardown is
|
|
248
|
+
// `disconnect()`. Renderer listeners must still go, or the next acquire's
|
|
249
|
+
// fresh listeners would double-process every packet.
|
|
250
|
+
this.cleanupDeviceState(id);
|
|
251
|
+
// Signal logical end-of-operation so the main process starts its 60s idle
|
|
252
|
+
// countdown (during a run it holds the long busy backstop instead). Best-
|
|
253
|
+
// effort: the idle/backstop timer still bounds the link if this never lands.
|
|
232
254
|
try {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// Disconnect device
|
|
240
|
-
if (window.desktopApi?.nobleBle) {
|
|
241
|
-
await window.desktopApi.nobleBle.disconnect(id);
|
|
242
|
-
}
|
|
255
|
+
await window.desktopApi?.nobleBle?.release?.(id);
|
|
256
|
+
} catch {
|
|
257
|
+
// ignore — timers in the main process still bound the link
|
|
258
|
+
}
|
|
259
|
+
}
|
|
243
260
|
|
|
244
|
-
|
|
245
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Hard teardown for the SDK's error-recovery path (DeviceConnector
|
|
263
|
+
* .disconnect); normal release() deliberately does not come here.
|
|
264
|
+
*/
|
|
265
|
+
async disconnect(id: string) {
|
|
266
|
+
// Independent best-effort steps, each time-boxed: on a wedged link the
|
|
267
|
+
// underlying noble callbacks can simply never fire, and this is the
|
|
268
|
+
// error-RECOVERY path — it must never hang the retry ladder.
|
|
269
|
+
const bounded = async (ms: number, run: () => Promise<unknown> | undefined) => {
|
|
270
|
+
try {
|
|
271
|
+
await Promise.race([
|
|
272
|
+
Promise.resolve(run()),
|
|
273
|
+
new Promise<void>(resolve => {
|
|
274
|
+
setTimeout(resolve, ms);
|
|
275
|
+
}),
|
|
276
|
+
]);
|
|
277
|
+
} catch {
|
|
278
|
+
// ignore — recovery path, best effort
|
|
246
279
|
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
280
|
+
};
|
|
281
|
+
await bounded(2000, () => window.desktopApi?.nobleBle?.unsubscribe(id));
|
|
282
|
+
await bounded(3000, () => window.desktopApi?.nobleBle?.disconnect(id));
|
|
283
|
+
this.cleanupDeviceState(id);
|
|
252
284
|
}
|
|
253
285
|
|
|
254
286
|
// Handle notification data from Noble BLE
|