@onekeyfe/hd-transport-react-native 1.2.0-alpha.33 → 1.2.0-alpha.35

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.
package/src/index.ts CHANGED
@@ -23,7 +23,12 @@ import transport, {
23
23
  probeProtocolV2 as probeProtocolV2Helper,
24
24
  writeProtocolV2BleFrame,
25
25
  } from '@onekeyfe/hd-transport';
26
- import { ERRORS, HardwareErrorCode, createDeferred, isOnekeyDevice } from '@onekeyfe/hd-shared';
26
+ import {
27
+ ERRORS,
28
+ HardwareErrorCode,
29
+ createDeferred,
30
+ isOnekeyBluetoothDevice,
31
+ } from '@onekeyfe/hd-shared';
27
32
 
28
33
  import { getConnectedDeviceIds, onDeviceBondState, pairDevice } from './BleManager';
29
34
  import { hasWritableCapability, resolveProtocolV2PacketCapacity } from './bleStrategy';
@@ -31,7 +36,6 @@ import { subscribeBleOn } from './subscribeBleOn';
31
36
  import {
32
37
  ANDROID_PACKET_LENGTH,
33
38
  IOS_PACKET_LENGTH,
34
- getBleUuidKey,
35
39
  getBluetoothServiceUuids,
36
40
  getInfosForServiceUuid,
37
41
  isSameBleUuid,
@@ -56,13 +60,12 @@ const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = Platform.OS === 'ios' ? 4 : 5;
56
60
  const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = Platform.OS === 'ios' ? 8 : 10;
57
61
  const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = Platform.OS === 'ios' ? 24 : 30;
58
62
  const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
59
- const FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS = 2000;
60
63
  const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
61
64
  const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY =
62
65
  Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
63
66
  const ANDROID_GATT_CONGESTED_STATUS = 143;
64
67
 
65
- type FirmwareUploadWriteRetryType = 'congested' | 'reconnectable';
68
+ type FirmwareUploadWriteRetryType = 'congested';
66
69
  type ResolvedBleCharacteristics = {
67
70
  writeCharacteristic: Characteristic;
68
71
  notifyCharacteristic: Characteristic;
@@ -73,7 +76,9 @@ const delay = (ms: number) =>
73
76
  setTimeout(resolve, ms);
74
77
  });
75
78
 
76
- const getFirmwareUploadWriteRetryType = (error: unknown): FirmwareUploadWriteRetryType | null => {
79
+ export const getFirmwareUploadWriteRetryType = (
80
+ error: unknown
81
+ ): FirmwareUploadWriteRetryType | null => {
77
82
  if (!error || typeof error !== 'object') return null;
78
83
  const bleWriteError = error as {
79
84
  androidErrorCode?: unknown;
@@ -84,13 +89,6 @@ const getFirmwareUploadWriteRetryType = (error: unknown): FirmwareUploadWriteRet
84
89
  name?: unknown;
85
90
  };
86
91
 
87
- if (
88
- bleWriteError.errorCode === BleErrorCode.DeviceDisconnected ||
89
- bleWriteError.errorCode === BleErrorCode.CharacteristicNotFound
90
- ) {
91
- return 'reconnectable';
92
- }
93
-
94
92
  if (
95
93
  bleWriteError.androidErrorCode === ANDROID_GATT_CONGESTED_STATUS ||
96
94
  bleWriteError.status === ANDROID_GATT_CONGESTED_STATUS
@@ -162,16 +160,6 @@ function getDeviceDisplayName(device?: Device | null) {
162
160
  return device?.name || device?.localName || null;
163
161
  }
164
162
 
165
- function isGenericBleService(uuid?: string | null) {
166
- return ['1800', '1801', '180a'].includes(getBleUuidKey(uuid));
167
- }
168
-
169
- function hasKnownOneKeyService(device?: Device | null) {
170
- return (device?.serviceUUIDs ?? []).some(serviceUuid =>
171
- getInfosForServiceUuid(serviceUuid, 'classic')
172
- );
173
- }
174
-
175
163
  const ANDROID_REQUEST_MTU = 256;
176
164
 
177
165
  const connectOptions: Record<string, unknown> = {
@@ -259,6 +247,8 @@ export default class ReactNativeBleTransport {
259
247
 
260
248
  runPromise: Deferred<any> | null = null;
261
249
 
250
+ private runPromiseDeviceId: string | null = null;
251
+
262
252
  emitter?: EventEmitter;
263
253
 
264
254
  firmwareUploadWriteRecoveryIds = new Set<string>();
@@ -359,29 +349,15 @@ export default class ReactNativeBleTransport {
359
349
  }
360
350
  }
361
351
 
362
- let fallbackServiceUuid: string | undefined;
363
-
364
352
  if (!infos) {
365
353
  const services = await device.services();
366
354
  Log?.debug(
367
355
  '[ReactNativeBleTransport] Known OneKey service UUID not found, discovered services:',
368
356
  services?.map(service => service.uuid)
369
357
  );
370
-
371
- const knownService = services.find(service =>
372
- getInfosForServiceUuid(service.uuid, 'classic')
373
- );
374
- const fallbackService =
375
- knownService ?? services.find(service => !isGenericBleService(service.uuid)) ?? services[0];
376
-
377
- if (fallbackService) {
378
- fallbackServiceUuid = fallbackService.uuid;
379
- characteristics = await device.characteristicsForService(fallbackService.uuid);
380
- Log?.debug('[ReactNativeBleTransport] Using fallback BLE service:', fallbackService.uuid);
381
- }
382
358
  }
383
359
 
384
- if (!infos && !fallbackServiceUuid) {
360
+ if (!infos) {
385
361
  try {
386
362
  Log?.debug('cancel connection when service not found');
387
363
  await device.cancelConnection();
@@ -391,9 +367,7 @@ export default class ReactNativeBleTransport {
391
367
  throw ERRORS.TypedError(HardwareErrorCode.BleServiceNotFound);
392
368
  }
393
369
 
394
- const serviceUuid = infos?.serviceUuid ?? fallbackServiceUuid;
395
- const writeUuid = infos?.writeUuid ?? '00000002-0000-1000-8000-00805f9b34fb';
396
- const notifyUuid = infos?.notifyUuid ?? '00000003-0000-1000-8000-00805f9b34fb';
370
+ const { serviceUuid, writeUuid, notifyUuid } = infos;
397
371
 
398
372
  if (!serviceUuid) {
399
373
  throw ERRORS.TypedError(HardwareErrorCode.BleServiceNotFound);
@@ -461,10 +435,9 @@ export default class ReactNativeBleTransport {
461
435
  try {
462
436
  Log?.debug('device disconnect: ', device?.id);
463
437
  this.emitDeviceDisconnect(uuid, device?.name, monitorToken);
464
- if (this.runPromise) {
438
+ if (this.runPromise && this.runPromiseDeviceId === uuid) {
465
439
  const error = ERRORS.TypedError(HardwareErrorCode.BleConnectedError);
466
440
  this.runPromise.reject(error);
467
- this.rejectAllProtocolV2Frames(error);
468
441
  }
469
442
  } catch (e) {
470
443
  Log?.debug('device disconnect error: ', e);
@@ -607,10 +580,12 @@ export default class ReactNativeBleTransport {
607
580
  }
608
581
 
609
582
  const displayName = getDeviceDisplayName(device);
610
- const isOneKey =
611
- isOnekeyDevice(device?.name ?? null, device?.id) ||
612
- isOnekeyDevice(device?.localName ?? null, device?.id) ||
613
- hasKnownOneKeyService(device);
583
+ const isOneKey = isOnekeyBluetoothDevice({
584
+ id: device?.id,
585
+ name: device?.name,
586
+ localName: device?.localName,
587
+ serviceUuids: device?.serviceUUIDs,
588
+ });
614
589
  if (isOneKey) {
615
590
  addDevice(device as unknown as Device);
616
591
  } else if (displayName && /\bpro\s*2\b/i.test(displayName)) {
@@ -627,10 +602,18 @@ export default class ReactNativeBleTransport {
627
602
  getConnectedDeviceIds(Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(
628
603
  devices => {
629
604
  for (const device of devices) {
630
- const { serviceUUIDs } = device as { serviceUUIDs?: string[] };
631
- const hasCachedServiceUuid = Boolean(serviceUUIDs?.length);
632
- const keepDevice = Platform.OS === 'ios' || hasCachedServiceUuid;
633
- if (keepDevice) {
605
+ const localName =
606
+ 'localName' in device && typeof device.localName === 'string'
607
+ ? device.localName
608
+ : null;
609
+ if (
610
+ isOnekeyBluetoothDevice({
611
+ id: device.id,
612
+ name: device.name,
613
+ localName,
614
+ serviceUuids: device.serviceUUIDs,
615
+ })
616
+ ) {
634
617
  Log?.debug('search connected peripheral: ', device.id);
635
618
  addDevice(device as unknown as Device);
636
619
  }
@@ -666,6 +649,46 @@ export default class ReactNativeBleTransport {
666
649
  });
667
650
  }
668
651
 
652
+ private async installTransportForAcquire(
653
+ uuid: string,
654
+ device: Device,
655
+ characteristics?: ResolvedBleCharacteristics
656
+ ) {
657
+ const { writeCharacteristic, notifyCharacteristic } =
658
+ characteristics ?? (await this.resolveCharacteristics(device));
659
+ const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
660
+ if (Platform.OS === 'android') {
661
+ transport.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport.mtuSize;
662
+ }
663
+ const monitorToken = this.nextMonitorToken;
664
+ this.nextMonitorToken += 1;
665
+ const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
666
+ transport.monitorToken = monitorToken;
667
+ transport.notifyTransactionId = notifyTransactionId;
668
+ this.monitorTokens.set(uuid, monitorToken);
669
+ transport.notifySubscription = this._monitorCharacteristic(
670
+ transport.notifyCharacteristic,
671
+ uuid,
672
+ monitorToken,
673
+ notifyTransactionId
674
+ );
675
+ transportCache[uuid] = transport;
676
+ this.protocolV2Assemblers.set(
677
+ uuid,
678
+ new ProtocolV2FrameAssembler(PROTOCOL_V2_BLE_FRAME_MAX_BYTES)
679
+ );
680
+
681
+ if (Platform.OS === 'ios') {
682
+ await new Promise<void>(resolve => {
683
+ setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
684
+ });
685
+ } else if (Platform.OS === 'android') {
686
+ await delay(ANDROID_NOTIFY_READY_DELAY_MS);
687
+ }
688
+
689
+ return transport;
690
+ }
691
+
669
692
  async acquire(input: BleAcquireInput) {
670
693
  const { uuid, forceCleanRunPromise, expectedProtocol } = input;
671
694
 
@@ -699,8 +722,8 @@ export default class ReactNativeBleTransport {
699
722
  if (forceCleanRunPromise && this.runPromise) {
700
723
  const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
701
724
  this.runPromise.reject(error);
702
- this.rejectAllProtocolV2Frames(error);
703
725
  this.runPromise = null;
726
+ this.runPromiseDeviceId = null;
704
727
  Log?.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
705
728
  }
706
729
 
@@ -789,12 +812,16 @@ export default class ReactNativeBleTransport {
789
812
  }
790
813
 
791
814
  device = await requestAndroidMtu(device);
792
- const { writeCharacteristic, notifyCharacteristic } = await this.resolveCharacteristics(device);
815
+ const acquiredDevice = device;
816
+ const { writeCharacteristic, notifyCharacteristic } = await this.resolveCharacteristics(
817
+ acquiredDevice
818
+ );
793
819
 
794
820
  const protocolHint = expectedProtocol
795
821
  ? undefined
796
- : this.deviceProtocolHints.get(uuid) ??
797
- inferProtocolHintFromDeviceName(getDeviceDisplayName(device));
822
+ : input.protocolHint ??
823
+ this.deviceProtocolHints.get(uuid) ??
824
+ inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
798
825
 
799
826
  // release transport before new transport instance
800
827
  await this.release(uuid, true);
@@ -802,42 +829,30 @@ export default class ReactNativeBleTransport {
802
829
  this.deviceProtocolHints.set(uuid, protocolHint);
803
830
  }
804
831
 
805
- const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
806
- if (Platform.OS === 'android') {
807
- transport.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport.mtuSize;
808
- }
809
- const monitorToken = this.nextMonitorToken;
810
- this.nextMonitorToken += 1;
811
- const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
812
- transport.monitorToken = monitorToken;
813
- transport.notifyTransactionId = notifyTransactionId;
814
- this.monitorTokens.set(uuid, monitorToken);
815
- transport.notifySubscription = this._monitorCharacteristic(
816
- transport.notifyCharacteristic,
817
- uuid,
818
- monitorToken,
819
- notifyTransactionId
820
- );
821
- transportCache[uuid] = transport;
822
-
823
- this.protocolV2Assemblers.set(
824
- uuid,
825
- new ProtocolV2FrameAssembler(PROTOCOL_V2_BLE_FRAME_MAX_BYTES)
826
- );
832
+ await this.installTransportForAcquire(uuid, acquiredDevice, {
833
+ writeCharacteristic,
834
+ notifyCharacteristic,
835
+ });
827
836
 
828
- if (Platform.OS === 'ios') {
829
- await new Promise<void>(resolve => {
830
- setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
831
- });
832
- } else if (Platform.OS === 'android') {
833
- await delay(ANDROID_NOTIFY_READY_DELAY_MS);
837
+ try {
838
+ const protocolType = await this.detectProtocol(
839
+ uuid,
840
+ expectedProtocol,
841
+ protocolHint,
842
+ async () => {
843
+ await this.installTransportForAcquire(uuid, acquiredDevice);
844
+ }
845
+ );
846
+ const currentTransport = transportCache[uuid];
847
+ if (!currentTransport) {
848
+ throw ERRORS.TypedError(HardwareErrorCode.TransportNotFound);
849
+ }
850
+ this.attachDisconnectSubscription(currentTransport, acquiredDevice, uuid);
851
+ return { uuid, protocolType };
852
+ } catch (error) {
853
+ await this.release(uuid, true);
854
+ throw error;
834
855
  }
835
-
836
- const protocolType = await this.detectProtocol(uuid, expectedProtocol, protocolHint);
837
-
838
- this.attachDisconnectSubscription(transport, device, uuid);
839
-
840
- return { uuid, protocolType };
841
856
  }
842
857
 
843
858
  _monitorCharacteristic(
@@ -887,7 +902,7 @@ export default class ReactNativeBleTransport {
887
902
  this.rejectProtocolV2Frames(uuid, ERRORS.TypedError(errorCode));
888
903
  return;
889
904
  }
890
- if (this.runPromise) {
905
+ if (this.runPromise && this.runPromiseDeviceId === uuid) {
891
906
  let ERROR:
892
907
  | typeof HardwareErrorCode.BleDeviceBondError
893
908
  | typeof HardwareErrorCode.BleCharacteristicNotifyError
@@ -910,7 +925,6 @@ export default class ReactNativeBleTransport {
910
925
  HardwareErrorCode.BleCharacteristicNotifyChangeFailure
911
926
  );
912
927
  this.runPromise.reject(notifyError);
913
- this.rejectAllProtocolV2Frames(notifyError);
914
928
  Log?.debug(
915
929
  `${HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`
916
930
  );
@@ -918,7 +932,6 @@ export default class ReactNativeBleTransport {
918
932
  }
919
933
  const notifyError = ERRORS.TypedError(ERROR);
920
934
  this.runPromise.reject(notifyError);
921
- this.rejectAllProtocolV2Frames(notifyError);
922
935
  Log?.debug(': monitor notify error, and has unreleased Promise', Error);
923
936
  }
924
937
 
@@ -963,14 +976,16 @@ export default class ReactNativeBleTransport {
963
976
  // );
964
977
  bufferLength = 0;
965
978
  buffer = [];
966
- this.runPromise?.resolve(value.toString('hex'));
979
+ if (this.runPromiseDeviceId === uuid) {
980
+ this.runPromise?.resolve(value.toString('hex'));
981
+ }
967
982
  }
968
983
  } catch (error) {
969
984
  Log?.debug('monitor data error: ', error);
970
985
  const notifyError = ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError);
971
986
  if (this.deviceProtocol.get(uuid) === 'V2') {
972
987
  this.rejectProtocolV2Frames(uuid, notifyError);
973
- } else {
988
+ } else if (this.runPromiseDeviceId === uuid) {
974
989
  this.runPromise?.reject(notifyError);
975
990
  }
976
991
  }
@@ -986,11 +1001,12 @@ export default class ReactNativeBleTransport {
986
1001
 
987
1002
  private async releaseNative(uuid: string, onclose = false) {
988
1003
  const transport = transportCache[uuid];
989
- if (this.runPromise) {
1004
+ if (this.runPromise && this.runPromiseDeviceId === uuid) {
990
1005
  const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
991
1006
  this.runPromise.reject(error);
992
1007
  this.runPromise = null;
993
- this.rejectAllProtocolV2Frames(error);
1008
+ this.runPromiseDeviceId = null;
1009
+ this.rejectProtocolV2Frames(uuid, error);
994
1010
  } else {
995
1011
  this.resetProtocolV2Frames(uuid);
996
1012
  }
@@ -1098,6 +1114,7 @@ export default class ReactNativeBleTransport {
1098
1114
  const runPromise = createDeferred<string>();
1099
1115
  runPromise.promise.catch(() => undefined);
1100
1116
  this.runPromise = runPromise;
1117
+ this.runPromiseDeviceId = uuid;
1101
1118
  const messages = this._messages;
1102
1119
  const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
1103
1120
  let timeout: ReturnType<typeof setTimeout> | undefined;
@@ -1197,31 +1214,14 @@ export default class ReactNativeBleTransport {
1197
1214
  if (!retryType || attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
1198
1215
  throw error;
1199
1216
  }
1200
- const shouldReconnect = retryType === 'reconnectable';
1201
- const delayMs = shouldReconnect
1202
- ? FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS
1203
- : resolveFirmwareUploadRetryDelay(attempt);
1217
+ const delayMs = resolveFirmwareUploadRetryDelay(attempt);
1204
1218
  Log?.debug('[ReactNativeBleTransport] FirmwareUpload write retry:', {
1205
1219
  attempt: attempt + 1,
1206
1220
  delayMs,
1207
- reconnect: shouldReconnect,
1208
1221
  error,
1209
1222
  });
1210
- if (shouldReconnect) {
1211
- this.firmwareUploadWriteRecoveryIds.add(uuid);
1212
- }
1213
1223
  await delay(delayMs);
1214
1224
  attempt += 1;
1215
- if (shouldReconnect) {
1216
- try {
1217
- await this.reconnectFirmwareUploadTransport(uuid, transport);
1218
- } catch (e) {
1219
- Log?.debug('[ReactNativeBleTransport] FirmwareUpload reconnect error:', e);
1220
- if (attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
1221
- throw e;
1222
- }
1223
- }
1224
- }
1225
1225
  }
1226
1226
  }
1227
1227
  },
@@ -1274,16 +1274,25 @@ export default class ReactNativeBleTransport {
1274
1274
  const jsonData = ProtocolV1.decodeMessage(messages, response);
1275
1275
  return check.call(jsonData);
1276
1276
  } catch (e) {
1277
- if (name === 'Initialize' && options?.timeoutMs === PROTOCOL_PROBE_TIMEOUT_MS) {
1278
- Log?.debug('[ReactNativeBleTransport] Protocol V1 Initialize probe call failed:', e);
1277
+ if (name === 'GetFeatures' && options?.timeoutMs === PROTOCOL_PROBE_TIMEOUT_MS) {
1278
+ Log?.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe call failed:', e);
1279
1279
  } else {
1280
1280
  Log?.error('call error: ', e);
1281
1281
  }
1282
+ const isProbeTimeout =
1283
+ name === 'GetFeatures' && options?.timeoutMs === PROTOCOL_PROBE_TIMEOUT_MS;
1284
+ if (
1285
+ !isProbeTimeout &&
1286
+ (e as { errorCode?: unknown })?.errorCode === HardwareErrorCode.BleTimeoutError
1287
+ ) {
1288
+ await this.disconnect(uuid);
1289
+ }
1282
1290
  throw e;
1283
1291
  } finally {
1284
1292
  if (timeout) clearTimeout(timeout);
1285
1293
  if (this.runPromise === runPromise) {
1286
1294
  this.runPromise = null;
1295
+ this.runPromiseDeviceId = null;
1287
1296
  }
1288
1297
  }
1289
1298
  }
@@ -1376,6 +1385,7 @@ export default class ReactNativeBleTransport {
1376
1385
  // this.runPromise.reject(new Error('Transport_CallCanceled'));
1377
1386
  }
1378
1387
  this.runPromise = null;
1388
+ this.runPromiseDeviceId = null;
1379
1389
  }
1380
1390
 
1381
1391
  private getCachedTransport(uuid: string) {
@@ -1396,7 +1406,7 @@ export default class ReactNativeBleTransport {
1396
1406
  private createProtocolDetectionError() {
1397
1407
  return ERRORS.TypedError(
1398
1408
  HardwareErrorCode.BleTimeoutError,
1399
- 'Unable to detect BLE protocol: device did not respond to Protocol V1 Initialize or Protocol V2 Ping'
1409
+ 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping'
1400
1410
  );
1401
1411
  }
1402
1412
 
@@ -1409,7 +1419,8 @@ export default class ReactNativeBleTransport {
1409
1419
  private async detectProtocol(
1410
1420
  uuid: string,
1411
1421
  expectedProtocol?: ProtocolType,
1412
- protocolHint?: ProtocolType
1422
+ protocolHint?: ProtocolType,
1423
+ rebuildTransport?: () => Promise<void>
1413
1424
  ): Promise<ProtocolType> {
1414
1425
  if (expectedProtocol === 'V1') {
1415
1426
  if (await this.probeProtocolV1(uuid)) {
@@ -1447,6 +1458,12 @@ export default class ReactNativeBleTransport {
1447
1458
  if (i > 0) {
1448
1459
  // Reset subscriptions and buffers after a failed probe before trying another protocol.
1449
1460
  await this.resetProbeStateAfterProtocolProbe(uuid, probeOrder[i - 1]);
1461
+ if (!transportCache[uuid]) {
1462
+ if (!rebuildTransport) {
1463
+ throw ERRORS.TypedError(HardwareErrorCode.TransportNotFound);
1464
+ }
1465
+ await rebuildTransport();
1466
+ }
1450
1467
  }
1451
1468
  const detected =
1452
1469
  protocol === 'V1' ? await this.probeProtocolV1(uuid) : await this.probeProtocolV2(uuid);
@@ -1524,11 +1541,13 @@ export default class ReactNativeBleTransport {
1524
1541
 
1525
1542
  try {
1526
1543
  this.deviceProtocol.set(uuid, 'V1');
1527
- await this.callProtocolV1(uuid, 'Initialize', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
1544
+ // GetFeatures identifies Protocol V1 without resetting an existing wallet
1545
+ // session before Core has a chance to restore a hidden wallet.
1546
+ await this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
1528
1547
  return true;
1529
1548
  } catch (error) {
1530
1549
  this.clearProbeProtocol(uuid, 'V1');
1531
- Log?.debug('[ReactNativeBleTransport] Protocol V1 Initialize probe failed:', error);
1550
+ Log?.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
1532
1551
  return false;
1533
1552
  }
1534
1553
  }
@@ -1603,17 +1622,8 @@ export default class ReactNativeBleTransport {
1603
1622
  this.getProtocolV2FrameQueue(uuid).push(frame);
1604
1623
  }
1605
1624
 
1606
- private rejectAllProtocolV2Frames(error: Error) {
1607
- this.protocolV2FrameQueues.clear();
1608
- for (const framePromise of this.protocolV2FramePromises.values()) {
1609
- framePromise.reject(error);
1610
- }
1611
- this.protocolV2FramePromises.clear();
1612
- }
1613
-
1614
1625
  private resetProtocolV2Frames(uuid: string) {
1615
- this.protocolV2FrameQueues.delete(uuid);
1616
- this.protocolV2FramePromises.delete(uuid);
1626
+ this.rejectProtocolV2Frames(uuid, new Error(`Protocol V2 frame state reset for ${uuid}`));
1617
1627
  }
1618
1628
 
1619
1629
  private rejectProtocolV2Frames(uuid: string, error: Error) {
@@ -1,18 +1 @@
1
- import type { ProtocolType } from '@onekeyfe/hd-transport';
2
-
3
- export function createTransportCallLog(
4
- name: string,
5
- protocol: ProtocolType,
6
- data: Record<string, unknown>
7
- ) {
8
- if (name === 'ResourceUpdate' || name === 'ResourceAck') {
9
- return {
10
- name,
11
- protocol,
12
- file_name: data.file_name,
13
- hash: data.hash,
14
- };
15
- }
16
-
17
- return { name, protocol };
18
- }
1
+ export { createTransportCallLog } from '@onekeyfe/hd-transport';
package/src/types.ts CHANGED
@@ -10,4 +10,5 @@ export type BleAcquireInput = {
10
10
  uuid: string;
11
11
  forceCleanRunPromise?: boolean;
12
12
  expectedProtocol?: ProtocolType;
13
+ protocolHint?: ProtocolType;
13
14
  };