@onekeyfe/hd-transport-web-device 1.2.8-alpha.3 → 1.2.8-alpha.4

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.
@@ -182,30 +182,16 @@ describe('ElectronBleTransport protocol detection', () => {
182
182
  jest.clearAllMocks();
183
183
  });
184
184
 
185
- test.each([
186
- { errorCode: HardwareErrorCode.BleLocationError, message: 'Permission denied' },
187
- { code: HardwareErrorCode.BleLocationError },
188
- { message: 'Bluetooth unauthorized' },
189
- ])('preserves Bluetooth permission failures from the native bridge: %j', async error => {
190
- const nobleBle = createNobleBle();
191
- nobleBle.enumerate.mockRejectedValueOnce(error);
192
- const bleTransport = configureTransport(nobleBle);
193
-
194
- await expect(bleTransport.enumerate()).rejects.toMatchObject({
195
- errorCode: HardwareErrorCode.BleLocationError,
196
- });
197
- });
198
-
199
185
  test('does not treat an error envelope from a legacy preload as a successful connect', async () => {
200
- const device = { id: 'legacy-error-id', name: 'OneKey Pro 2' };
186
+ const device = { id: 'stale-bond-id', name: 'OneKey Pro 2' };
201
187
  const nobleBle = createNobleBle(device);
202
188
  nobleBle.connect.mockResolvedValue({
203
189
  type: 'NobleBleIpcError',
204
190
  success: false,
205
191
  error: {
206
192
  name: 'HardwareError',
207
- message: 'Bluetooth connection failed',
208
- errorCode: HardwareErrorCode.BleConnectedError,
193
+ message: 'Bluetooth pairing information is no longer valid',
194
+ errorCode: HardwareErrorCode.BleBondInvalid,
209
195
  },
210
196
  } as never);
211
197
  const bleTransport = configureTransport(nobleBle);
@@ -213,7 +199,7 @@ describe('ElectronBleTransport protocol detection', () => {
213
199
  await expect(
214
200
  bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
215
201
  ).rejects.toMatchObject({
216
- errorCode: HardwareErrorCode.BleConnectedError,
202
+ errorCode: HardwareErrorCode.BleBondInvalid,
217
203
  });
218
204
  expect(nobleBle.subscribe).not.toHaveBeenCalled();
219
205
  expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
@@ -656,13 +642,14 @@ describe('ElectronBleTransport protocol detection', () => {
656
642
  expect(transport.getProtocolType(device.id)).toBeUndefined();
657
643
  });
658
644
 
659
- test('fails Protocol V2 acquire immediately when subscribe reports a connection error', async () => {
660
- const device = { id: 'subscribe-error-pro2-id', name: 'OneKey Pro 2' };
645
+ test('fails Protocol V2 acquire immediately when subscribe reports insufficient encryption', async () => {
646
+ const device = { id: 'stale-bond-pro2-id', name: 'OneKey Pro 2' };
661
647
  const nobleBle = createNobleBle(device);
662
648
  nobleBle.subscribe.mockRejectedValue({
663
649
  name: 'HardwareError',
664
- message: 'Bluetooth connection failed',
665
- errorCode: HardwareErrorCode.BleConnectedError,
650
+ message: 'Bluetooth pairing information is no longer valid',
651
+ errorCode: HardwareErrorCode.BleBondInvalid,
652
+ params: { nativeErrorMessage: 'Encryption is insufficient' },
666
653
  });
667
654
  const transport = configureTransport(nobleBle);
668
655
  const probe = jest.spyOn(transport as any, 'probeProtocolV2');
@@ -670,7 +657,7 @@ describe('ElectronBleTransport protocol detection', () => {
670
657
  await expect(
671
658
  transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
672
659
  ).rejects.toMatchObject({
673
- errorCode: HardwareErrorCode.BleConnectedError,
660
+ errorCode: HardwareErrorCode.BleBondInvalid,
674
661
  });
675
662
 
676
663
  expect(probe).not.toHaveBeenCalled();
@@ -678,19 +665,21 @@ describe('ElectronBleTransport protocol detection', () => {
678
665
  expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
679
666
  });
680
667
 
681
- test('rehydrates a structured connection error before the protocol is known', async () => {
668
+ test('rehydrates a structured stale-bond error before the protocol is known', async () => {
682
669
  const device = { id: 'reset-unknown-protocol-id', name: 'OneKey Pro 2' };
683
670
  const nobleBle = createNobleBle(device);
684
671
  nobleBle.connect.mockRejectedValue({
685
672
  name: 'HardwareError',
686
- message: 'Bluetooth connection failed',
687
- errorCode: HardwareErrorCode.BleConnectedError,
673
+ message: 'Bluetooth pairing information is no longer valid',
674
+ errorCode: HardwareErrorCode.BleBondInvalid,
675
+ params: { nativeErrorMessage: 'CBErrorDomain:14 native message' },
688
676
  });
689
677
  const transport = configureTransport(nobleBle);
690
678
 
691
679
  await expect(transport.acquire({ uuid: device.id })).rejects.toMatchObject({
692
680
  name: 'HardwareError',
693
- errorCode: HardwareErrorCode.BleConnectedError,
681
+ errorCode: HardwareErrorCode.BleBondInvalid,
682
+ params: { nativeErrorMessage: 'CBErrorDomain:14 native message' },
694
683
  });
695
684
  });
696
685
 
@@ -710,7 +699,7 @@ describe('ElectronBleTransport protocol detection', () => {
710
699
  }
711
700
  });
712
701
 
713
- test('preserves a generic macOS connection failure', async () => {
702
+ test('does not classify a generic macOS connection failure as a stale bond', async () => {
714
703
  const device = { id: 'offline-pro2-macos-id', name: 'OneKey Pro 2' };
715
704
  const nobleBle = createNobleBle(device);
716
705
  nobleBle.connect.mockRejectedValue(new Error('connection failed'));
@@ -726,7 +715,7 @@ describe('ElectronBleTransport protocol detection', () => {
726
715
  }
727
716
  });
728
717
 
729
- test('preserves a native subscribe failure during Protocol V1 acquire', async () => {
718
+ test('keeps stale-bond subscribe mapping out of Protocol V1 acquire', async () => {
730
719
  const device = { id: 'classic-v1-id', name: 'OneKey Classic' };
731
720
  const nobleBle = createNobleBle(device);
732
721
  nobleBle.subscribe.mockRejectedValue(new Error('Encryption is insufficient'));
@@ -791,19 +780,19 @@ describe('ElectronBleTransport protocol detection', () => {
791
780
  }
792
781
  );
793
782
 
794
- test('preserves a native connection error during an expected Protocol V2 probe', async () => {
795
- const device = { id: 'connection-error-probe-id', name: 'OneKey Pro 2' };
783
+ test('preserves a native stale-bond error during an expected Protocol V2 probe', async () => {
784
+ const device = { id: 'stale-bond-probe-id', name: 'OneKey Pro 2' };
796
785
  const nobleBle = createNobleBle(device);
797
786
  nobleBle.write.mockRejectedValue({
798
787
  name: 'HardwareError',
799
- message: 'Bluetooth connection failed',
800
- errorCode: HardwareErrorCode.BleConnectedError,
788
+ message: 'Bluetooth pairing information is no longer valid',
789
+ errorCode: HardwareErrorCode.BleBondInvalid,
801
790
  });
802
791
  const transport = configureTransport(nobleBle);
803
792
 
804
793
  await expect(
805
794
  transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
806
- ).rejects.toMatchObject({ errorCode: HardwareErrorCode.BleConnectedError });
795
+ ).rejects.toMatchObject({ errorCode: HardwareErrorCode.BleBondInvalid });
807
796
 
808
797
  expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
809
798
  expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
@@ -64,127 +64,6 @@ describe('WebUsbTransport protocol probe cache', () => {
64
64
  }
65
65
  );
66
66
 
67
- test('reports claimInterface failures as WebUSB device access errors', async () => {
68
- const webusb = new WebUsbTransport();
69
- const path = 'connected-usb-device';
70
- const claimError = Object.assign(new Error('Unable to claim interface'), {
71
- name: 'NetworkError',
72
- });
73
- const device = {
74
- opened: true,
75
- configuration: { configurationValue: 1 },
76
- configurations: [],
77
- claimInterface: jest.fn().mockRejectedValue(claimError),
78
- };
79
- jest.spyOn(webusb, 'findDevice').mockResolvedValue(device as unknown as USBDevice);
80
- jest.spyOn(webusb, 'getConnectedDevices').mockResolvedValue([]);
81
- const state = webusb as unknown as { deviceProtocol: Map<string, 'V1' | 'V2'> };
82
- state.deviceProtocol.set(path, 'V1');
83
-
84
- await expect(webusb.connectToDevice(path, false)).rejects.toMatchObject({
85
- errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
86
- params: {
87
- operation: 'claimInterface',
88
- nativeErrorName: 'NetworkError',
89
- nativeErrorMessage: 'Unable to claim interface',
90
- },
91
- });
92
- });
93
-
94
- test('reports transferIn failures as WebUSB device access errors', async () => {
95
- const webusb = new WebUsbTransport() as any;
96
- const path = 'connected-usb-device';
97
- const transferError = Object.assign(new Error('Transfer endpoint is unavailable'), {
98
- name: 'NetworkError',
99
- });
100
- webusb.findDevice = jest.fn().mockResolvedValue({
101
- opened: true,
102
- transferIn: jest.fn().mockRejectedValue(transferError),
103
- });
104
-
105
- await expect(webusb.transferInWithRetry(path, 64)).rejects.toMatchObject({
106
- errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
107
- params: {
108
- operation: 'transferIn',
109
- nativeErrorName: 'NetworkError',
110
- nativeErrorMessage: 'Transfer endpoint is unavailable',
111
- },
112
- });
113
- });
114
-
115
- test.each(['LIBUSB_ERROR_ACCESS', "Failed to execute 'open' on 'USBDevice': Access denied."])(
116
- 'reports USB open permission failure: %s',
117
- async message => {
118
- const webusb = new WebUsbTransport();
119
- const device = {
120
- opened: false,
121
- open: jest
122
- .fn()
123
- .mockRejectedValue(Object.assign(new Error(message), { name: 'SecurityError' })),
124
- };
125
- jest.spyOn(webusb, 'findDevice').mockResolvedValue(device as unknown as USBDevice);
126
- await expect(webusb.connect('mock-usb', true)).rejects.toMatchObject({
127
- errorCode: HardwareErrorCode.BridgeNeedsPermission,
128
- params: {
129
- operation: 'open',
130
- nativeErrorName: 'SecurityError',
131
- nativeErrorMessage: message,
132
- },
133
- });
134
- expect(device.open).toHaveBeenCalledTimes(1);
135
- }
136
- );
137
-
138
- test('does not classify protected-interface SecurityError as missing OS permission', async () => {
139
- const webusb = new WebUsbTransport();
140
- const device = {
141
- opened: false,
142
- open: jest
143
- .fn()
144
- .mockRejectedValue(
145
- Object.assign(new Error('Protected interface'), { name: 'SecurityError' })
146
- ),
147
- };
148
- jest.spyOn(webusb, 'findDevice').mockResolvedValue(device as unknown as USBDevice);
149
- await expect(webusb.connectToDevice('mock-usb', true)).rejects.toMatchObject({
150
- errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
151
- });
152
- });
153
-
154
- test.each(['claimInterface', 'transferIn', 'transferOut'] as const)(
155
- 'preserves USB permission failures during %s',
156
- async operation => {
157
- const webusb = new WebUsbTransport() as unknown as {
158
- throwWebUsbIoError(path: string, operation: string, error: unknown): Promise<never>;
159
- };
160
- await expect(
161
- webusb.throwWebUsbIoError('mock-usb', operation, new Error('LIBUSB_ERROR_ACCESS'))
162
- ).rejects.toMatchObject({
163
- errorCode: HardwareErrorCode.BridgeNeedsPermission,
164
- params: { operation, nativeErrorMessage: 'LIBUSB_ERROR_ACCESS' },
165
- });
166
- }
167
- );
168
-
169
- test('fails a stalled USB write without replaying the packet', async () => {
170
- const webusb = new WebUsbTransport();
171
- const device = {
172
- opened: true,
173
- transferOut: jest.fn().mockResolvedValue({ status: 'stall', bytesWritten: 0 }),
174
- };
175
- jest.spyOn(webusb, 'findDevice').mockResolvedValue(device as unknown as USBDevice);
176
- const state = webusb as unknown as {
177
- transferOutWithRetry(path: string, packet: Uint8Array): Promise<void>;
178
- };
179
- await expect(state.transferOutWithRetry('mock-usb', new Uint8Array([1]))).rejects.toMatchObject(
180
- {
181
- errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
182
- params: { operation: 'transferOut', nativeErrorMessage: 'transferOut status: stall' },
183
- }
184
- );
185
- expect(device.transferOut).toHaveBeenCalledTimes(1);
186
- });
187
-
188
67
  test('acquire skips the wire probe when the protocol is already cached', async () => {
189
68
  const webusb = buildAcquirableTransport();
190
69
  const path = 'pro-webusb';
@@ -238,15 +238,9 @@ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
238
238
  webusb.resetConnectionAfterProbe = jest.fn();
239
239
  await webusb.rotateProtocolV2UsbGeneration(path, 'test connection');
240
240
 
241
- await expect(
242
- webusb.callProtocolV2(path, 'Ping', { message: 'read-error' })
243
- ).rejects.toMatchObject({
244
- errorCode: HardwareErrorCode.BridgeDeviceDisconnected,
245
- params: {
246
- operation: 'transferIn',
247
- nativeErrorMessage: 'NetworkError: transferIn device disconnected',
248
- },
249
- });
241
+ await expect(webusb.callProtocolV2(path, 'Ping', { message: 'read-error' })).rejects.toThrow(
242
+ 'NetworkError'
243
+ );
250
244
 
251
245
  expect(webusb.readProtocolV2UsbPacket).toHaveBeenCalledTimes(1);
252
246
  expect(webusb.resetProtocolV2UsbNativeLink).toHaveBeenCalledWith(
@@ -1 +1 @@
1
- {"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -118,7 +118,7 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
118
118
  /**
119
119
  * Connect to device with retry mechanism
120
120
  */
121
- connect(path: string, first: boolean): Promise<undefined>;
121
+ connect(path: string, first: boolean): Promise<void>;
122
122
  /**
123
123
  * Discover vendor-class (0xFF) interface and its IN/OUT endpoint numbers from USB descriptors.
124
124
  * Falls back to legacy hardcoded values if no vendor interface is found.
@@ -128,7 +128,7 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
128
128
  * Connect to specific device.
129
129
  * Discovers interface/endpoint numbers from USB descriptors on first connection.
130
130
  */
131
- connectToDevice(path: string, first: boolean): Promise<undefined>;
131
+ connectToDevice(path: string, first: boolean): Promise<void>;
132
132
  private closeOpenDevice;
133
133
  private clearEndpointHalt;
134
134
  /**
@@ -141,11 +141,6 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
141
141
  private assertAcquired;
142
142
  post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
143
143
  private getErrorMessage;
144
- private getErrorName;
145
- private isWebUsbIoHardwareError;
146
- private isDeviceStillEnumerated;
147
- private throwWebUsbIoError;
148
- private isWebUsbPermissionDeniedMessage;
149
144
  private isRetryablePacketIoError;
150
145
  private reconnectForPacketIoRetry;
151
146
  private getTransferInData;
package/dist/index.js CHANGED
@@ -332,9 +332,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
332
332
  return yield this.connectToDevice(path, first);
333
333
  }
334
334
  catch (e) {
335
- if (e instanceof hdShared.HardwareError && e.errorCode === hdShared.HardwareErrorCode.BridgeNeedsPermission) {
336
- throw e;
337
- }
338
335
  if (i === maxRetries - 1) {
339
336
  throw e;
340
337
  }
@@ -376,12 +373,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
376
373
  return __awaiter(this, void 0, void 0, function* () {
377
374
  let device = yield this.findDevice(path);
378
375
  if (!device.opened) {
379
- try {
380
- yield device.open();
381
- }
382
- catch (error) {
383
- return this.throwWebUsbIoError(path, 'open', error);
384
- }
376
+ yield device.open();
385
377
  }
386
378
  if (first || this.deviceProtocol.get(path) !== 'V1') {
387
379
  try {
@@ -394,12 +386,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
394
386
  yield this.getConnectedDevices();
395
387
  device = yield this.findDevice(path);
396
388
  if (!device.opened) {
397
- try {
398
- yield device.open();
399
- }
400
- catch (error) {
401
- return this.throwWebUsbIoError(path, 'open', error);
402
- }
389
+ yield device.open();
403
390
  }
404
391
  if (first ||
405
392
  !device.configuration ||
@@ -408,12 +395,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
408
395
  }
409
396
  const endpoints = this.discoverEndpoints(device);
410
397
  this.deviceEndpoints.set(path, endpoints);
411
- try {
412
- yield device.claimInterface(endpoints.interfaceNumber);
413
- }
414
- catch (error) {
415
- return this.throwWebUsbIoError(path, 'claimInterface', error);
416
- }
398
+ yield device.claimInterface(endpoints.interfaceNumber);
417
399
  yield this.clearEndpointHalt(device, 'in', endpoints.endpointIn);
418
400
  yield this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
419
401
  });
@@ -477,76 +459,8 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
477
459
  }
478
460
  return String(error);
479
461
  }
480
- getErrorName(error) {
481
- if (typeof error === 'object' && error && 'name' in error) {
482
- const { name } = error;
483
- return typeof name === 'string' ? name : String(name !== null && name !== void 0 ? name : '');
484
- }
485
- return '';
486
- }
487
- isWebUsbIoHardwareError(error) {
488
- return (error instanceof hdShared.HardwareError &&
489
- (error.errorCode === hdShared.HardwareErrorCode.BridgeDeviceDisconnected ||
490
- error.errorCode === hdShared.HardwareErrorCode.BridgeNeedsPermission ||
491
- error.errorCode === hdShared.HardwareErrorCode.WebUsbDeviceAccessError));
492
- }
493
- isDeviceStillEnumerated(path) {
494
- var _a;
495
- return __awaiter(this, void 0, void 0, function* () {
496
- if (!this.usb)
497
- return undefined;
498
- try {
499
- const devices = yield this.usb.getDevices();
500
- return devices.some(device => hdShared.resolveOneKeyUsbDevicePath(device) === path);
501
- }
502
- catch (error) {
503
- (_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[WebUsbTransport] failed to verify WebUSB device presence:', error);
504
- return undefined;
505
- }
506
- });
507
- }
508
- throwWebUsbIoError(path, operation, error) {
509
- var _a;
510
- return __awaiter(this, void 0, void 0, function* () {
511
- if (this.isWebUsbIoHardwareError(error))
512
- throw error;
513
- if (error instanceof transport.ProtocolV2LinkError && error.code !== 'io')
514
- throw error;
515
- const nativeError = error instanceof transport.ProtocolV2LinkError ? (_a = error.cause) !== null && _a !== void 0 ? _a : error : error;
516
- if (this.isWebUsbIoHardwareError(nativeError))
517
- throw nativeError;
518
- const nativeErrorName = this.getErrorName(nativeError);
519
- const nativeErrorMessage = this.getErrorMessage(nativeError);
520
- if (this.isWebUsbPermissionDeniedMessage(nativeErrorMessage)) {
521
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BridgeNeedsPermission, nativeErrorMessage, {
522
- operation,
523
- nativeErrorName: nativeErrorName || undefined,
524
- nativeErrorMessage,
525
- });
526
- }
527
- const disconnectedByMessage = /(?:device )?disconnected|device not found|action was interrupted/i.test(`${nativeErrorName}: ${nativeErrorMessage}`);
528
- const stillEnumerated = disconnectedByMessage
529
- ? false
530
- : yield this.isDeviceStillEnumerated(path);
531
- const errorCode = disconnectedByMessage || stillEnumerated === false
532
- ? hdShared.HardwareErrorCode.BridgeDeviceDisconnected
533
- : hdShared.HardwareErrorCode.WebUsbDeviceAccessError;
534
- throw hdShared.ERRORS.TypedError(errorCode, nativeErrorMessage || undefined, {
535
- operation,
536
- nativeErrorName: nativeErrorName || undefined,
537
- nativeErrorMessage: nativeErrorMessage || undefined,
538
- });
539
- });
540
- }
541
- isWebUsbPermissionDeniedMessage(message) {
542
- return /LIBUSB_ERROR_ACCESS|\b(?:access|permission) denied\b/i.test(message);
543
- }
544
462
  isRetryablePacketIoError(error) {
545
- if (this.isWebUsbIoHardwareError(error))
546
- return false;
547
463
  const message = this.getErrorMessage(error).toLowerCase();
548
- if (this.isWebUsbPermissionDeniedMessage(message))
549
- return false;
550
464
  return (message.includes('transferout') ||
551
465
  message.includes('transferin') ||
552
466
  message.includes('usbdevice') ||
@@ -611,7 +525,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
611
525
  lastError = error;
612
526
  const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
613
527
  if (!shouldRetry) {
614
- return this.throwWebUsbIoError(path, 'transferOut', error);
528
+ throw error;
615
529
  }
616
530
  try {
617
531
  yield this.reconnectForPacketIoRetry(path, 'out', attempt, error);
@@ -622,7 +536,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
622
536
  }
623
537
  }
624
538
  }
625
- return this.throwWebUsbIoError(path, 'transferOut', lastError);
539
+ throw lastError;
626
540
  });
627
541
  }
628
542
  transferOutOnce(path, packet) {
@@ -635,10 +549,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
635
549
  const endpoints = this.deviceEndpoints.get(path);
636
550
  const endpointOut = (_a = endpoints === null || endpoints === void 0 ? void 0 : endpoints.endpointOut) !== null && _a !== void 0 ? _a : this.endpointId;
637
551
  const transferBuffer = this.toArrayBuffer(packet.buffer.slice(packet.byteOffset, packet.byteOffset + packet.byteLength));
638
- const result = yield device.transferOut(endpointOut, transferBuffer);
639
- if (result.status !== 'ok') {
640
- return this.throwWebUsbIoError(path, 'transferOut', new Error(`transferOut status: ${String(result.status)}`));
641
- }
552
+ yield device.transferOut(endpointOut, transferBuffer);
642
553
  });
643
554
  }
644
555
  transferInWithRetry(path, length, cancelToken) {
@@ -666,7 +577,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
666
577
  }
667
578
  const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
668
579
  if (!shouldRetry) {
669
- return this.throwWebUsbIoError(path, 'transferIn', error);
580
+ throw error;
670
581
  }
671
582
  try {
672
583
  yield this.reconnectForPacketIoRetry(path, 'in', attempt, error);
@@ -677,7 +588,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
677
588
  }
678
589
  }
679
590
  }
680
- return this.throwWebUsbIoError(path, 'transferIn', lastError);
591
+ throw lastError;
681
592
  });
682
593
  }
683
594
  transferInOnce(path, length) {
@@ -754,9 +665,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
754
665
  });
755
666
  return true;
756
667
  }
757
- catch (error) {
758
- if (this.isWebUsbIoHardwareError(error))
759
- throw error;
668
+ catch (_error) {
760
669
  return false;
761
670
  }
762
671
  });
@@ -771,7 +680,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
771
680
  timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT,
772
681
  logger: this.Log,
773
682
  logPrefix: 'ProtocolV2 WebUSB',
774
- shouldRethrow: error => this.isWebUsbIoHardwareError(error),
775
683
  });
776
684
  });
777
685
  }
@@ -818,15 +726,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
818
726
  }
819
727
  callProtocolV2(path, name, data, options) {
820
728
  return __awaiter(this, void 0, void 0, function* () {
821
- try {
822
- return yield this.callProtocolV2Usb(path, name, data, options);
823
- }
824
- catch (error) {
825
- if (!(error instanceof transport.ProtocolV2LinkError) || error.code !== 'io')
826
- throw error;
827
- const operation = error.message.includes(' USB write failed:') ? 'transferOut' : 'transferIn';
828
- return this.throwWebUsbIoError(path, operation, error);
829
- }
729
+ return this.callProtocolV2Usb(path, name, data, options);
830
730
  });
831
731
  }
832
732
  receiveData(path, timeoutMs) {
@@ -1001,14 +901,11 @@ class ElectronBleTransport {
1001
901
  if (error.code === hdShared.HardwareErrorCode.BlePermissionError) {
1002
902
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError);
1003
903
  }
1004
- if (error.code === hdShared.HardwareErrorCode.BleLocationError) {
1005
- return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleLocationError);
1006
- }
1007
904
  }
1008
905
  const errorMessage = error.message || String(error);
1009
906
  const poweredOffMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BlePoweredOff];
1010
907
  const unsupportedMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BleUnsupported];
1011
- const permissionMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BleLocationError];
908
+ const permissionMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BlePermissionError];
1012
909
  if (errorMessage.includes(poweredOffMessage) || errorMessage.includes('poweredOff')) {
1013
910
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePoweredOff);
1014
911
  }
@@ -1016,7 +913,7 @@ class ElectronBleTransport {
1016
913
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleUnsupported);
1017
914
  }
1018
915
  if (errorMessage.includes(permissionMessage) || errorMessage.includes('unauthorized')) {
1019
- return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleLocationError);
916
+ return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError);
1020
917
  }
1021
918
  }
1022
919
  return error;
@@ -1392,7 +1289,9 @@ class ElectronBleTransport {
1392
1289
  (_a = this.v2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1393
1290
  this.resetProtocolV2Frames(uuid);
1394
1291
  },
1395
- shouldRethrow: error => expectedProtocol === 'V2' || transport.isProtocolV2LinkDisabledError(error),
1292
+ shouldRethrow: error => expectedProtocol === 'V2' ||
1293
+ hdShared.isBleStaleBondHardwareError(error) ||
1294
+ transport.isProtocolV2LinkDisabledError(error),
1396
1295
  });
1397
1296
  if (!detected) {
1398
1297
  this.clearProbeProtocol(uuid, 'V2');
package/dist/webusb.d.ts CHANGED
@@ -44,19 +44,14 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
44
44
  private createProtocolDetectionError;
45
45
  private detectProtocol;
46
46
  findDevice(path: string): Promise<USBDevice>;
47
- connect(path: string, first: boolean): Promise<undefined>;
47
+ connect(path: string, first: boolean): Promise<void>;
48
48
  private discoverEndpoints;
49
- connectToDevice(path: string, first: boolean): Promise<undefined>;
49
+ connectToDevice(path: string, first: boolean): Promise<void>;
50
50
  private closeOpenDevice;
51
51
  private clearEndpointHalt;
52
52
  private assertAcquired;
53
53
  post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
54
54
  private getErrorMessage;
55
- private getErrorName;
56
- private isWebUsbIoHardwareError;
57
- private isDeviceStillEnumerated;
58
- private throwWebUsbIoError;
59
- private isWebUsbPermissionDeniedMessage;
60
55
  private isRetryablePacketIoError;
61
56
  private reconnectForPacketIoRetry;
62
57
  private getTransferInData;
@@ -1 +1 @@
1
- {"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-web-device",
3
- "version": "1.2.8-alpha.3",
3
+ "version": "1.2.8-alpha.4",
4
4
  "author": "OneKey",
5
5
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
6
6
  "license": "MIT",
@@ -21,13 +21,13 @@
21
21
  "lint:fix": "eslint . --fix"
22
22
  },
23
23
  "dependencies": {
24
- "@onekeyfe/hd-shared": "1.2.8-alpha.3",
25
- "@onekeyfe/hd-transport": "1.2.8-alpha.3"
24
+ "@onekeyfe/hd-shared": "1.2.8-alpha.4",
25
+ "@onekeyfe/hd-transport": "1.2.8-alpha.4"
26
26
  },
27
27
  "devDependencies": {
28
- "@onekeyfe/hd-transport-electron": "1.2.8-alpha.3",
28
+ "@onekeyfe/hd-transport-electron": "1.2.8-alpha.4",
29
29
  "@types/w3c-web-usb": "^1.0.6",
30
30
  "@types/web-bluetooth": "^0.0.17"
31
31
  },
32
- "gitHead": "18c57239359413a079fffa730b36149c8516aa85"
32
+ "gitHead": "82fcab32fa1a37d1b82f73da825e39360624e0c9"
33
33
  }
@@ -18,6 +18,7 @@ import {
18
18
  HardwareErrorCode,
19
19
  HardwareErrorCodeMessage,
20
20
  createDeferred,
21
+ isBleStaleBondHardwareError,
21
22
  isHeaderChunk,
22
23
  } from '@onekeyfe/hd-shared';
23
24
 
@@ -202,14 +203,11 @@ export default class ElectronBleTransport {
202
203
  if (error.code === HardwareErrorCode.BlePermissionError) {
203
204
  return ERRORS.TypedError(HardwareErrorCode.BlePermissionError);
204
205
  }
205
- if (error.code === HardwareErrorCode.BleLocationError) {
206
- return ERRORS.TypedError(HardwareErrorCode.BleLocationError);
207
- }
208
206
  }
209
207
  const errorMessage = error.message || String(error);
210
208
  const poweredOffMessage = HardwareErrorCodeMessage[HardwareErrorCode.BlePoweredOff];
211
209
  const unsupportedMessage = HardwareErrorCodeMessage[HardwareErrorCode.BleUnsupported];
212
- const permissionMessage = HardwareErrorCodeMessage[HardwareErrorCode.BleLocationError];
210
+ const permissionMessage = HardwareErrorCodeMessage[HardwareErrorCode.BlePermissionError];
213
211
 
214
212
  if (errorMessage.includes(poweredOffMessage) || errorMessage.includes('poweredOff')) {
215
213
  return ERRORS.TypedError(HardwareErrorCode.BlePoweredOff);
@@ -218,7 +216,7 @@ export default class ElectronBleTransport {
218
216
  return ERRORS.TypedError(HardwareErrorCode.BleUnsupported);
219
217
  }
220
218
  if (errorMessage.includes(permissionMessage) || errorMessage.includes('unauthorized')) {
221
- return ERRORS.TypedError(HardwareErrorCode.BleLocationError);
219
+ return ERRORS.TypedError(HardwareErrorCode.BlePermissionError);
222
220
  }
223
221
  }
224
222
  return error;
@@ -678,7 +676,10 @@ export default class ElectronBleTransport {
678
676
  this.resetProtocolV2Frames(uuid);
679
677
  },
680
678
  // A declared V2 protocol needs no fallback; preserve the actual link failure.
681
- shouldRethrow: error => expectedProtocol === 'V2' || isProtocolV2LinkDisabledError(error),
679
+ shouldRethrow: error =>
680
+ expectedProtocol === 'V2' ||
681
+ isBleStaleBondHardwareError(error) ||
682
+ isProtocolV2LinkDisabledError(error),
682
683
  });
683
684
  if (!detected) {
684
685
  this.clearProbeProtocol(uuid, 'V2');
package/src/webusb.ts CHANGED
@@ -13,7 +13,6 @@ import transport, {
13
13
  } from '@onekeyfe/hd-transport';
14
14
  import {
15
15
  ERRORS,
16
- HardwareError,
17
16
  HardwareErrorCode,
18
17
  ONEKEY_WEBUSB_FILTER,
19
18
  inferProtocolHintFromUsbId,
@@ -71,8 +70,6 @@ interface TransferCancelToken {
71
70
  cancelled: boolean;
72
71
  }
73
72
 
74
- type WebUsbOperation = 'open' | 'claimInterface' | 'transferIn' | 'transferOut';
75
-
76
73
  /**
77
74
  * The navigator.usb disconnect listener is module-scoped and attached at most
78
75
  * once: listeners on navigator.usb are global and never garbage collected, so a
@@ -519,9 +516,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
519
516
  try {
520
517
  return await this.connectToDevice(path, first);
521
518
  } catch (e) {
522
- if (e instanceof HardwareError && e.errorCode === HardwareErrorCode.BridgeNeedsPermission) {
523
- throw e;
524
- }
525
519
  if (i === maxRetries - 1) {
526
520
  throw e;
527
521
  }
@@ -570,11 +564,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
570
564
  async connectToDevice(path: string, first: boolean) {
571
565
  let device: USBDevice = await this.findDevice(path);
572
566
  if (!device.opened) {
573
- try {
574
- await device.open();
575
- } catch (error) {
576
- return this.throwWebUsbIoError(path, 'open', error);
577
- }
567
+ await device.open();
578
568
  }
579
569
  // A V1 packet retry continues an in-flight exchange. Preserve its endpoint
580
570
  // state as in the legacy transport; probing and V2 recovery still reset.
@@ -588,11 +578,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
588
578
  await this.getConnectedDevices();
589
579
  device = await this.findDevice(path);
590
580
  if (!device.opened) {
591
- try {
592
- await device.open();
593
- } catch (error) {
594
- return this.throwWebUsbIoError(path, 'open', error);
595
- }
581
+ await device.open();
596
582
  }
597
583
 
598
584
  if (
@@ -606,11 +592,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
606
592
  // Discover endpoints from USB descriptors; descriptors are not used for protocol selection.
607
593
  const endpoints = this.discoverEndpoints(device);
608
594
  this.deviceEndpoints.set(path, endpoints);
609
- try {
610
- await device.claimInterface(endpoints.interfaceNumber);
611
- } catch (error) {
612
- return this.throwWebUsbIoError(path, 'claimInterface', error);
613
- }
595
+ await device.claimInterface(endpoints.interfaceNumber);
614
596
  await this.clearEndpointHalt(device, 'in', endpoints.endpointIn);
615
597
  await this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
616
598
  }
@@ -680,82 +662,8 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
680
662
  return String(error);
681
663
  }
682
664
 
683
- private getErrorName(error: unknown) {
684
- if (typeof error === 'object' && error && 'name' in error) {
685
- const { name } = error as { name?: unknown };
686
- return typeof name === 'string' ? name : String(name ?? '');
687
- }
688
- return '';
689
- }
690
-
691
- private isWebUsbIoHardwareError(error: unknown): error is HardwareError {
692
- return (
693
- error instanceof HardwareError &&
694
- (error.errorCode === HardwareErrorCode.BridgeDeviceDisconnected ||
695
- error.errorCode === HardwareErrorCode.BridgeNeedsPermission ||
696
- error.errorCode === HardwareErrorCode.WebUsbDeviceAccessError)
697
- );
698
- }
699
-
700
- private async isDeviceStillEnumerated(path: string): Promise<boolean | undefined> {
701
- if (!this.usb) return undefined;
702
- try {
703
- const devices = await this.usb.getDevices();
704
- return devices.some(device => resolveOneKeyUsbDevicePath(device) === path);
705
- } catch (error) {
706
- this.Log?.debug('[WebUsbTransport] failed to verify WebUSB device presence:', error);
707
- return undefined;
708
- }
709
- }
710
-
711
- private async throwWebUsbIoError(
712
- path: string,
713
- operation: WebUsbOperation,
714
- error: unknown
715
- ): Promise<never> {
716
- if (this.isWebUsbIoHardwareError(error)) throw error;
717
- if (error instanceof ProtocolV2LinkError && error.code !== 'io') throw error;
718
-
719
- const nativeError = error instanceof ProtocolV2LinkError ? error.cause ?? error : error;
720
- if (this.isWebUsbIoHardwareError(nativeError)) throw nativeError;
721
-
722
- const nativeErrorName = this.getErrorName(nativeError);
723
- const nativeErrorMessage = this.getErrorMessage(nativeError);
724
- // SecurityError alone may indicate a protected interface, not OS permissions.
725
- if (this.isWebUsbPermissionDeniedMessage(nativeErrorMessage)) {
726
- throw ERRORS.TypedError(HardwareErrorCode.BridgeNeedsPermission, nativeErrorMessage, {
727
- operation,
728
- nativeErrorName: nativeErrorName || undefined,
729
- nativeErrorMessage,
730
- });
731
- }
732
- const disconnectedByMessage =
733
- /(?:device )?disconnected|device not found|action was interrupted/i.test(
734
- `${nativeErrorName}: ${nativeErrorMessage}`
735
- );
736
- const stillEnumerated = disconnectedByMessage
737
- ? false
738
- : await this.isDeviceStillEnumerated(path);
739
- const errorCode =
740
- disconnectedByMessage || stillEnumerated === false
741
- ? HardwareErrorCode.BridgeDeviceDisconnected
742
- : HardwareErrorCode.WebUsbDeviceAccessError;
743
-
744
- throw ERRORS.TypedError(errorCode, nativeErrorMessage || undefined, {
745
- operation,
746
- nativeErrorName: nativeErrorName || undefined,
747
- nativeErrorMessage: nativeErrorMessage || undefined,
748
- });
749
- }
750
-
751
- private isWebUsbPermissionDeniedMessage(message: string) {
752
- return /LIBUSB_ERROR_ACCESS|\b(?:access|permission) denied\b/i.test(message);
753
- }
754
-
755
665
  private isRetryablePacketIoError(error: unknown) {
756
- if (this.isWebUsbIoHardwareError(error)) return false;
757
666
  const message = this.getErrorMessage(error).toLowerCase();
758
- if (this.isWebUsbPermissionDeniedMessage(message)) return false;
759
667
  return (
760
668
  message.includes('transferout') ||
761
669
  message.includes('transferin') ||
@@ -834,7 +742,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
834
742
  lastError = error;
835
743
  const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
836
744
  if (!shouldRetry) {
837
- return this.throwWebUsbIoError(path, 'transferOut', error);
745
+ throw error;
838
746
  }
839
747
  try {
840
748
  await this.reconnectForPacketIoRetry(path, 'out', attempt, error);
@@ -848,7 +756,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
848
756
  }
849
757
  }
850
758
  }
851
- return this.throwWebUsbIoError(path, 'transferOut', lastError);
759
+ throw lastError;
852
760
  }
853
761
 
854
762
  private async transferOutOnce(path: string, packet: Uint8Array) {
@@ -861,14 +769,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
861
769
  const transferBuffer = this.toArrayBuffer(
862
770
  packet.buffer.slice(packet.byteOffset, packet.byteOffset + packet.byteLength)
863
771
  );
864
- const result = await device.transferOut(endpointOut, transferBuffer);
865
- if (result.status !== 'ok') {
866
- return this.throwWebUsbIoError(
867
- path,
868
- 'transferOut',
869
- new Error(`transferOut status: ${String(result.status)}`)
870
- );
871
- }
772
+ await device.transferOut(endpointOut, transferBuffer);
872
773
  }
873
774
 
874
775
  private async transferInWithRetry(
@@ -897,7 +798,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
897
798
  }
898
799
  const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
899
800
  if (!shouldRetry) {
900
- return this.throwWebUsbIoError(path, 'transferIn', error);
801
+ throw error;
901
802
  }
902
803
  try {
903
804
  await this.reconnectForPacketIoRetry(path, 'in', attempt, error);
@@ -911,7 +812,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
911
812
  }
912
813
  }
913
814
  }
914
- return this.throwWebUsbIoError(path, 'transferIn', lastError);
815
+ throw lastError;
915
816
  }
916
817
 
917
818
  private async transferInOnce(path: string, length: number): Promise<DataView> {
@@ -993,8 +894,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
993
894
  }
994
895
  );
995
896
  return true;
996
- } catch (error) {
997
- if (this.isWebUsbIoHardwareError(error)) throw error;
897
+ } catch (_error) {
998
898
  return false;
999
899
  }
1000
900
  }
@@ -1009,7 +909,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
1009
909
  timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT,
1010
910
  logger: this.Log,
1011
911
  logPrefix: 'ProtocolV2 WebUSB',
1012
- shouldRethrow: error => this.isWebUsbIoHardwareError(error),
1013
912
  });
1014
913
  }
1015
914
 
@@ -1087,13 +986,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
1087
986
  data: Record<string, unknown>,
1088
987
  options?: TransportCallOptions
1089
988
  ) {
1090
- try {
1091
- return await this.callProtocolV2Usb(path, name, data, options);
1092
- } catch (error) {
1093
- if (!(error instanceof ProtocolV2LinkError) || error.code !== 'io') throw error;
1094
- const operation = error.message.includes(' USB write failed:') ? 'transferOut' : 'transferIn';
1095
- return this.throwWebUsbIoError(path, operation, error);
1096
- }
989
+ return this.callProtocolV2Usb(path, name, data, options);
1097
990
  }
1098
991
 
1099
992
  /**