@onekeyfe/hd-transport-electron 1.2.0-alpha.166 → 1.2.0-alpha.168

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.
@@ -32,7 +32,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
32
32
 
33
33
  function initNobleBleSupport(webContents) {
34
34
  return __awaiter(this, void 0, void 0, function* () {
35
- const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-038532d9.js'); });
35
+ const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-e8b87173.js'); });
36
36
  setupNobleBleHandlers(webContents);
37
37
  });
38
38
  }
package/dist/index.d.ts CHANGED
@@ -25,7 +25,6 @@ interface NobleModule {
25
25
  interface Logger {
26
26
  info(message: string, ...args: any[]): void;
27
27
  debug(message: string, ...args: any[]): void;
28
- warn(message: string, ...args: any[]): void;
29
28
  error(message: string, ...args: any[]): void;
30
29
  }
31
30
 
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-f4b406db.js');
5
+ var index = require('./index-b37d926c.js');
6
6
 
7
7
 
8
8
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-f4b406db.js');
3
+ var index = require('./index-b37d926c.js');
4
4
  var hdShared = require('@onekeyfe/hd-shared');
5
5
  var pRetry = require('p-retry');
6
6
 
@@ -116,8 +116,7 @@ const DEVICE_SCAN_TIMEOUT = 5000;
116
116
  const DEVICE_CHECK_INTERVAL = 500;
117
117
  const SERVICE_DISCOVERY_TIMEOUT = 10000;
118
118
  const BLE_CLEANUP_TIMEOUT = 250;
119
- const BLE_DISCONNECT_CONFIRM_TIMEOUT_MS = 3000;
120
- const BLE_IDLE_DISCONNECT_MS = 20000;
119
+ const BLE_IDLE_DISCONNECT_MS = 3 * 60000;
121
120
  const BLE_BUSY_BACKSTOP_MS = 10 * 60000;
122
121
  const BLE_PACKET_SIZE_FALLBACK = 192;
123
122
  const BLE_PACKET_SIZE_MAXIMUM = 244;
@@ -243,7 +242,6 @@ function initializeNoble() {
243
242
  try {
244
243
  noble = require('@stoprocent/noble');
245
244
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Noble library loaded');
246
- setupPersistentStateListener();
247
245
  yield new Promise((resolve, reject) => {
248
246
  if (!noble) {
249
247
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Noble not initialized'));
@@ -253,6 +251,7 @@ function initializeNoble() {
253
251
  resolve();
254
252
  return;
255
253
  }
254
+ setupPersistentStateListener();
256
255
  const timeout = setTimeout(() => {
257
256
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Bluetooth initialization timeout'));
258
257
  }, BLUETOOTH_INIT_TIMEOUT);
@@ -337,14 +336,7 @@ function armIdleDisconnect(deviceId, ms = BLE_IDLE_DISCONNECT_MS, reason = 'idle
337
336
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Keep-alive timeout, disconnecting device', { deviceId, reason });
338
337
  const peripheral = connectedDevices.get(deviceId);
339
338
  const deviceName = ((_a = peripheral === null || peripheral === void 0 ? void 0 : peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.localName) || 'Unknown Device';
340
- const pending = unsubscribeNotifications(deviceId)
341
- .catch(error => {
342
- logger === null || logger === void 0 ? void 0 : logger.warn('[NobleBLE] Keep-alive unsubscribe failed, disconnecting anyway', {
343
- deviceId,
344
- error: error instanceof Error ? error.message : String(error),
345
- });
346
- })
347
- .then(() => disconnectDevice(deviceId))
339
+ const pending = disconnectDevice(deviceId)
348
340
  .then(() => {
349
341
  broadcastToAllWebContents(hdShared.EOneKeyBleMessageKeys.BLE_DEVICE_DISCONNECTED, {
350
342
  id: deviceId,
@@ -396,10 +388,6 @@ function cleanupDevice(deviceId, webContents, options = {}) {
396
388
  pairedDevices.delete(deviceId);
397
389
  }
398
390
  if (cleanupDiscoveredCache) {
399
- const evicted = discoveredDevices.get(deviceId);
400
- if (evicted) {
401
- stalePeripherals.set(deviceId, evicted);
402
- }
403
391
  discoveredDevices.delete(deviceId);
404
392
  }
405
393
  if (sendDisconnectEvent) {
@@ -421,7 +409,6 @@ function handleDeviceDisconnect(deviceId, webContents) {
421
409
  });
422
410
  cleanupDevice(deviceId, webContents, {
423
411
  cleanupConnection: true,
424
- cleanupDiscoveredCache: true,
425
412
  sendDisconnectEvent: true,
426
413
  cancelOperations: true,
427
414
  reason: 'auto-disconnect',
@@ -603,37 +590,18 @@ function transmitHexDataToDevice(deviceId, hexData, options) {
603
590
  }
604
591
  });
605
592
  }
606
- const BLE_COLD_CONNECT_SCAN_TIMEOUT_MS = 1500;
607
- const stalePeripherals = new Map();
608
- const bleNamesById = new Map();
609
- function rememberBleName(deviceId, name) {
610
- const trimmed = name === null || name === void 0 ? void 0 : name.trim();
611
- if (trimmed) {
612
- bleNamesById.set(deviceId, trimmed);
613
- }
614
- }
615
- function resolveBleName(deviceId) {
616
- var _a, _b, _c, _d, _e, _f;
617
- const live = ((_c = (_b = (_a = connectedDevices.get(deviceId)) === null || _a === void 0 ? void 0 : _a.advertisement) === null || _b === void 0 ? void 0 : _b.localName) === null || _c === void 0 ? void 0 : _c.trim()) ||
618
- ((_f = (_e = (_d = discoveredDevices.get(deviceId)) === null || _d === void 0 ? void 0 : _d.advertisement) === null || _e === void 0 ? void 0 : _e.localName) === null || _f === void 0 ? void 0 : _f.trim());
619
- return live || bleNamesById.get(deviceId);
620
- }
621
- function shouldConnectByIdFirst(deviceId) {
622
- return hdShared.isPro2FamilyBleName(resolveBleName(deviceId));
623
- }
624
593
  function handleDeviceDiscovered(peripheral) {
625
- var _a, _b, _c;
594
+ var _a, _b;
626
595
  if (!isOneKeyPeripheral(peripheral)) {
627
596
  return;
628
597
  }
629
598
  const isNewDevice = !discoveredDevices.has(peripheral.id);
630
599
  discoveredDevices.set(peripheral.id, peripheral);
631
- rememberBleName(peripheral.id, (_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.localName);
632
600
  if (isNewDevice) {
633
601
  logger === null || logger === void 0 ? void 0 : logger.debug('[NobleBLE] OneKey BLE device discovered', {
634
602
  deviceId: peripheral.id,
635
- name: ((_b = peripheral.advertisement) === null || _b === void 0 ? void 0 : _b.localName) || 'Unknown Device',
636
- serviceUUIDs: ((_c = peripheral.advertisement) === null || _c === void 0 ? void 0 : _c.serviceUuids) || [],
603
+ name: ((_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.localName) || 'Unknown Device',
604
+ serviceUUIDs: ((_b = peripheral.advertisement) === null || _b === void 0 ? void 0 : _b.serviceUuids) || [],
637
605
  });
638
606
  }
639
607
  }
@@ -659,7 +627,7 @@ function waitForNobleScanStop(nobleInstance) {
659
627
  });
660
628
  });
661
629
  }
662
- function performTargetedScan(targetDeviceId, timeoutMs = NOBLE_BLE_TARGETED_SCAN_TIMEOUT_MS) {
630
+ function performTargetedScan(targetDeviceId) {
663
631
  return index.__awaiter(this, void 0, void 0, function* () {
664
632
  if (!noble) {
665
633
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Noble not available');
@@ -699,7 +667,7 @@ function performTargetedScan(targetDeviceId, timeoutMs = NOBLE_BLE_TARGETED_SCAN
699
667
  const timeoutId = setTimeout(() => {
700
668
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Targeted scan timeout for device:', targetDeviceId);
701
669
  finish(null).catch(reject);
702
- }, timeoutMs);
670
+ }, NOBLE_BLE_TARGETED_SCAN_TIMEOUT_MS);
703
671
  nobleInstance.on('discover', onDiscover);
704
672
  nobleInstance.startScanning([], true, (error) => {
705
673
  if (error) {
@@ -914,12 +882,7 @@ function forceReconnectPeripheral(peripheral, deviceId) {
914
882
  yield runBleCallbackOperation(callback => peripheral.disconnect(() => {
915
883
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Force disconnect completed');
916
884
  callback();
917
- }), { timeoutMs: BLE_DISCONNECT_CONFIRM_TIMEOUT_MS, timeoutBehavior: 'resolve' });
918
- if (peripheral.state === 'connected') {
919
- logger === null || logger === void 0 ? void 0 : logger.warn('[NobleBLE] Reset disconnect did not confirm, reconnecting anyway', {
920
- deviceId,
921
- });
922
- }
885
+ }), { timeoutMs: BLE_CLEANUP_TIMEOUT, timeoutBehavior: 'resolve' });
923
886
  }
924
887
  yield runBleCallbackOperation(callback => peripheral.connect(callback), {
925
888
  timeoutMs: NOBLE_BLE_CONNECTION_TIMEOUT_MS,
@@ -1003,18 +966,23 @@ function discoverServicesAndCharacteristicsWithRetry(peripheral, deviceId) {
1003
966
  }
1004
967
  function setupConnectionAndDiscoverServices(peripheral, deviceId, webContents) {
1005
968
  return index.__awaiter(this, void 0, void 0, function* () {
969
+ setupDisconnectListener(peripheral, deviceId, webContents);
1006
970
  try {
1007
- yield forceReconnectPeripheral(peripheral, deviceId);
971
+ return yield discoverServicesAndCharacteristicsWithRetry(peripheral, deviceId);
1008
972
  }
1009
- catch (resetError) {
1010
- logger === null || logger === void 0 ? void 0 : logger.error('[NobleBLE] Connection reset before discovery failed, continuing', resetError);
973
+ catch (initialError) {
974
+ logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Direct service discovery failed, retrying after reconnect', {
975
+ deviceId,
976
+ error: initialError,
977
+ });
1011
978
  }
979
+ yield forceReconnectPeripheral(peripheral, deviceId);
1012
980
  setupDisconnectListener(peripheral, deviceId, webContents);
1013
981
  try {
1014
982
  return yield discoverServicesAndCharacteristicsWithRetry(peripheral, deviceId);
1015
983
  }
1016
- catch (discoveryError) {
1017
- logger === null || logger === void 0 ? void 0 : logger.error('[NobleBLE] Service discovery failed, attempting fresh scan...', discoveryError);
984
+ catch (reconnectError) {
985
+ logger === null || logger === void 0 ? void 0 : logger.error('[NobleBLE] Service discovery failed after reconnect, attempting fresh scan...', reconnectError);
1018
986
  return freshScanAndDiscover(deviceId, webContents);
1019
987
  }
1020
988
  });
@@ -1074,7 +1042,7 @@ function tryDirectConnectById(deviceId) {
1074
1042
  });
1075
1043
  }
1076
1044
  function connectDevice(deviceId, webContents) {
1077
- var _a, _b, _c;
1045
+ var _a;
1078
1046
  return index.__awaiter(this, void 0, void 0, function* () {
1079
1047
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Connect device request:', {
1080
1048
  deviceId,
@@ -1086,57 +1054,34 @@ function connectDevice(deviceId, webContents) {
1086
1054
  });
1087
1055
  let peripheral = (_a = discoveredDevices.get(deviceId)) !== null && _a !== void 0 ? _a : connectedDevices.get(deviceId);
1088
1056
  if (!peripheral) {
1057
+ logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Device not discovered, attempting targeted scan for:', deviceId);
1089
1058
  if (!noble) {
1090
1059
  yield initializeNoble();
1091
1060
  }
1092
1061
  if (!noble) {
1093
1062
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Noble not available');
1094
1063
  }
1095
- const byIdFirst = shouldConnectByIdFirst(deviceId);
1096
- logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Resolving device for cold connect', {
1097
- deviceId,
1098
- name: (_b = resolveBleName(deviceId)) !== null && _b !== void 0 ? _b : 'unknown',
1099
- strategy: byIdFirst ? 'connect-by-id-first' : 'scan-first',
1100
- });
1101
- const scanForPeripheral = () => index.__awaiter(this, void 0, void 0, function* () {
1102
- var _d;
1103
- try {
1104
- return (_d = (yield performTargetedScan(deviceId, BLE_COLD_CONNECT_SCAN_TIMEOUT_MS))) !== null && _d !== void 0 ? _d : undefined;
1105
- }
1106
- catch (scanError) {
1107
- logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Targeted scan failed', {
1108
- deviceId,
1109
- error: scanError instanceof Error ? scanError.message : String(scanError),
1110
- });
1111
- return undefined;
1112
- }
1113
- });
1114
- const connectById = () => index.__awaiter(this, void 0, void 0, function* () {
1115
- const found = yield tryDirectConnectById(deviceId);
1116
- if (found) {
1117
- discoveredDevices.set(deviceId, found);
1118
- }
1119
- return found;
1120
- });
1121
- peripheral = byIdFirst ? yield connectById() : yield scanForPeripheral();
1122
- if (!peripheral) {
1123
- peripheral = byIdFirst ? yield scanForPeripheral() : yield connectById();
1064
+ peripheral = yield tryDirectConnectById(deviceId);
1065
+ if (peripheral) {
1066
+ discoveredDevices.set(deviceId, peripheral);
1124
1067
  }
1125
- if (!peripheral) {
1126
- const stale = stalePeripherals.get(deviceId);
1127
- if (stale) {
1128
- logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Falling back to the last known peripheral:', deviceId);
1129
- peripheral = stale;
1068
+ }
1069
+ if (!peripheral) {
1070
+ try {
1071
+ const foundPeripheral = yield performTargetedScan(deviceId);
1072
+ if (!foundPeripheral) {
1073
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Device ${deviceId} not found even after targeted scan`);
1130
1074
  }
1075
+ peripheral = foundPeripheral;
1131
1076
  }
1132
- else {
1133
- stalePeripherals.delete(deviceId);
1077
+ catch (error) {
1078
+ logger === null || logger === void 0 ? void 0 : logger.error('[NobleBLE] Targeted scan failed:', error);
1079
+ throw error;
1134
1080
  }
1135
1081
  }
1136
1082
  if (!peripheral) {
1137
1083
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Device ${deviceId} not found`);
1138
1084
  }
1139
- rememberBleName(deviceId, (_c = peripheral.advertisement) === null || _c === void 0 ? void 0 : _c.localName);
1140
1085
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Connecting to device:', deviceId);
1141
1086
  if (peripheral.state === 'connected') {
1142
1087
  logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Device already connected, skipping connection step');
@@ -1231,15 +1176,11 @@ function disconnectDevice(deviceId) {
1231
1176
  deviceDisconnectListeners.delete(deviceId);
1232
1177
  }
1233
1178
  yield runBleCallbackOperation(callback => peripheral.disconnect(() => callback()), {
1234
- timeoutMs: BLE_DISCONNECT_CONFIRM_TIMEOUT_MS,
1179
+ timeoutMs: BLE_CLEANUP_TIMEOUT,
1235
1180
  timeoutBehavior: 'resolve',
1236
1181
  });
1237
- if (peripheral.state === 'connected') {
1238
- logger === null || logger === void 0 ? void 0 : logger.warn('[NobleBLE] Physical disconnect did not confirm in time', { deviceId });
1239
- }
1240
1182
  cleanupDevice(deviceId, undefined, {
1241
1183
  cleanupConnection: true,
1242
- cleanupDiscoveredCache: true,
1243
1184
  sendDisconnectEvent: false,
1244
1185
  cancelOperations: true,
1245
1186
  reason: 'manual-disconnect',
@@ -1450,6 +1391,10 @@ function setupNobleBleHandlers(webContents) {
1450
1391
  yield disconnectDevice(deviceId).catch(() => undefined);
1451
1392
  }
1452
1393
  yield stopScanning().catch(() => undefined);
1394
+ if (noble && persistentStateListener) {
1395
+ noble.removeListener('stateChange', persistentStateListener);
1396
+ persistentStateListener = null;
1397
+ }
1453
1398
  cleanupNobleListeners();
1454
1399
  discoveredDevices.clear();
1455
1400
  safeLog(logger, 'info', 'Noble BLE cleanup completed');
@@ -1 +1 @@
1
- {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAoFhE,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE,oBAAoB,UAI7E;AAkuDD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAkMpE"}
1
+ {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA0EhE,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE,oBAAoB,UAI7E;AA2mDD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAgMpE"}
@@ -22,7 +22,6 @@ export interface NobleModule {
22
22
  export interface Logger {
23
23
  info(message: string, ...args: any[]): void;
24
24
  debug(message: string, ...args: any[]): void;
25
- warn(message: string, ...args: any[]): void;
26
25
  error(message: string, ...args: any[]): void;
27
26
  }
28
27
  export declare function safeLog(logger: Logger | null, level: 'info' | 'debug' | 'error', message: string, ...args: any[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"noble-extended.d.ts","sourceRoot":"","sources":["../../src/types/noble-extended.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CACX,YAAY,EAAE,MAAM,EAAE,EACtB,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GACjC,IAAI,CAAC;IACR,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAClE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IACxE,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9E,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF;AAGD,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC9C;AAGD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,IAAI,CAMN"}
1
+ {"version":3,"file":"noble-extended.d.ts","sourceRoot":"","sources":["../../src/types/noble-extended.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CACX,YAAY,EAAE,MAAM,EAAE,EACtB,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GACjC,IAAI,CAAC;IACR,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAClE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IACxE,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9E,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF;AAGD,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC9C;AAGD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,IAAI,CAMN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-electron",
3
- "version": "1.2.0-alpha.166",
3
+ "version": "1.2.0-alpha.168",
4
4
  "author": "OneKey",
5
5
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
6
6
  "license": "MIT",
@@ -25,9 +25,9 @@
25
25
  "electron-log": ">=4.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-core": "1.2.0-alpha.166",
29
- "@onekeyfe/hd-shared": "1.2.0-alpha.166",
30
- "@onekeyfe/hd-transport": "1.2.0-alpha.166",
28
+ "@onekeyfe/hd-core": "1.2.0-alpha.168",
29
+ "@onekeyfe/hd-shared": "1.2.0-alpha.168",
30
+ "@onekeyfe/hd-transport": "1.2.0-alpha.168",
31
31
  "@stoprocent/noble": "2.3.16",
32
32
  "p-retry": "^4.6.2"
33
33
  },
@@ -36,5 +36,5 @@
36
36
  "electron": "^25.0.0",
37
37
  "typescript": "^5.3.3"
38
38
  },
39
- "gitHead": "3dd1b964d8503ee800f44466b8c08e3d59be67e8"
39
+ "gitHead": "70f16e98ede0365f106ae8add83e82afff761c4c"
40
40
  }
@@ -16,7 +16,6 @@ import {
16
16
  createKnownBleUuidAliases,
17
17
  hasOnekeyCommunicationService,
18
18
  isOnekeyBluetoothDevice,
19
- isPro2FamilyBleName,
20
19
  matchesKnownBleUuid,
21
20
  wait,
22
21
  } from '@onekeyfe/hd-shared';
@@ -91,18 +90,8 @@ const DEVICE_SCAN_TIMEOUT = 5000; // 5 seconds for device scanning
91
90
  const DEVICE_CHECK_INTERVAL = 500; // 500ms interval for periodic device checks
92
91
  const SERVICE_DISCOVERY_TIMEOUT = 10000; // 10 seconds for service discovery
93
92
  const BLE_CLEANUP_TIMEOUT = 250;
94
- // A physical teardown must actually reach the OS before the device can return
95
- // to a clean state; 250ms routinely declared success while CoreBluetooth was
96
- // still disconnecting, leaving no trace when the teardown never completed.
97
- const BLE_DISCONNECT_CONFIRM_TIMEOUT_MS = 3000;
98
93
  // Renderer release is logical only; this timer physically frees the device.
99
- // Keep it SHORT: the Classic 1S goes protocol-deaf when a link is dropped
100
- // after sitting idle for minutes (field logs 2026-08-19: every deaf window
101
- // followed a 3-minute-idle disconnect, while disconnects right after traffic
102
- // have never produced one across 6.5.0's per-call teardown history). A hot
103
- // disconnect ~20s after the last operation stays inside the proven-safe
104
- // pattern and also shrinks the window in which phones cannot see the device.
105
- const BLE_IDLE_DISCONNECT_MS = 20_000;
94
+ const BLE_IDLE_DISCONNECT_MS = 3 * 60_000;
106
95
  // Ceiling while a call is in flight: no outstanding write, but not forever.
107
96
  const BLE_BUSY_BACKSTOP_MS = 10 * 60_000;
108
97
 
@@ -268,11 +257,6 @@ async function initializeNoble(): Promise<void> {
268
257
  noble = require('@stoprocent/noble') as NobleModule;
269
258
  logger?.info('[NobleBLE] Noble library loaded');
270
259
 
271
- // Register the process-lifetime state listener before any early return:
272
- // the poweredOn fast path below would otherwise skip it for the whole
273
- // session, leaving poweredOff cache/state reconciliation dead.
274
- setupPersistentStateListener();
275
-
276
260
  // Wait for Bluetooth to be ready
277
261
  await new Promise<void>((resolve, reject) => {
278
262
  if (!noble) {
@@ -285,6 +269,9 @@ async function initializeNoble(): Promise<void> {
285
269
  return;
286
270
  }
287
271
 
272
+ // Setup persistent state listener before initialization
273
+ setupPersistentStateListener();
274
+
288
275
  const timeout = setTimeout(() => {
289
276
  reject(
290
277
  ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Bluetooth initialization timeout')
@@ -411,21 +398,7 @@ function armIdleDisconnect(
411
398
  logger?.info('[NobleBLE] Keep-alive timeout, disconnecting device', { deviceId, reason });
412
399
  const peripheral = connectedDevices.get(deviceId);
413
400
  const deviceName = peripheral?.advertisement?.localName || 'Unknown Device';
414
- // Unsubscribe CCCD before dropping the link, matching every other
415
- // teardown path: the 1S leaves its notify session half-open when the
416
- // link drops without an unsubscribe and then ignores application
417
- // protocol traffic on NEW links for tens of minutes (field log
418
- // 2026-08-19: the lone unsubscribe-skipping idle teardown caused a
419
- // 6-attempt reconnect loop; unsubscribe-first teardowns reconnected
420
- // instantly).
421
- const pending = unsubscribeNotifications(deviceId)
422
- .catch(error => {
423
- logger?.warn('[NobleBLE] Keep-alive unsubscribe failed, disconnecting anyway', {
424
- deviceId,
425
- error: error instanceof Error ? error.message : String(error),
426
- });
427
- })
428
- .then(() => disconnectDevice(deviceId))
401
+ const pending = disconnectDevice(deviceId)
429
402
  .then(() => {
430
403
  // A call is still in flight here; it must reject, not hang.
431
404
  // Both 'idle' and 'busy-backstop' report IdleKeepAlive on purpose:
@@ -503,16 +476,8 @@ function cleanupDevice(
503
476
  pairedDevices.delete(deviceId);
504
477
  }
505
478
 
506
- // 2. Clean up discovered cache (optional). A peripheral that has been
507
- // through a disconnect is never preferred again — reconnecting it is what
508
- // produces stale-session links — but it is kept aside as the last resort for
509
- // a bonded device that stays silent, so eviction cannot turn a working
510
- // reconnect into DeviceNotFound.
479
+ // 2. Clean up discovered cache (optional)
511
480
  if (cleanupDiscoveredCache) {
512
- const evicted = discoveredDevices.get(deviceId);
513
- if (evicted) {
514
- stalePeripherals.set(deviceId, evicted);
515
- }
516
481
  discoveredDevices.delete(deviceId);
517
482
  }
518
483
 
@@ -543,9 +508,6 @@ function handleDeviceDisconnect(deviceId: string, webContents: WebContents): voi
543
508
 
544
509
  cleanupDevice(deviceId, webContents, {
545
510
  cleanupConnection: true,
546
- // Same stale-object hazard as manual disconnect: an externally dropped
547
- // link invalidates the cached peripheral for the next reconnect.
548
- cleanupDiscoveredCache: true,
549
511
  sendDisconnectEvent: true,
550
512
  cancelOperations: true,
551
513
  reason: 'auto-disconnect',
@@ -799,45 +761,6 @@ async function transmitHexDataToDevice(
799
761
  }
800
762
 
801
763
  // Handle discovered device (for general enumeration only)
802
- // A scan that finds nothing costs this much before the direct-connect
803
- // fallback runs. Every advertisement in the 6.5.0 control logs arrived within
804
- // 631ms, so this leaves ~2x headroom while keeping a miss cheap.
805
- const BLE_COLD_CONNECT_SCAN_TIMEOUT_MS = 1500;
806
-
807
- // Peripherals evicted by a disconnect, kept only as the fallback of last
808
- // resort in connectDevice (see cleanupDevice).
809
- const stalePeripherals = new Map<string, Peripheral>();
810
-
811
- // Advertised names, kept for the life of the process: device caches are purged
812
- // on every disconnect, but the family a device belongs to never changes and
813
- // decides which connection strategy is safe for it.
814
- const bleNamesById = new Map<string, string>();
815
-
816
- function rememberBleName(deviceId: string, name?: string | null): void {
817
- const trimmed = name?.trim();
818
- if (trimmed) {
819
- bleNamesById.set(deviceId, trimmed);
820
- }
821
- }
822
-
823
- function resolveBleName(deviceId: string): string | undefined {
824
- const live =
825
- connectedDevices.get(deviceId)?.advertisement?.localName?.trim() ||
826
- discoveredDevices.get(deviceId)?.advertisement?.localName?.trim();
827
- return live || bleNamesById.get(deviceId);
828
- }
829
-
830
- /**
831
- * Pro2/Neo connect by id first: they are unaffected by the stale-session
832
- * problem and advertise under Find My names a OneKey-filtered scan cannot
833
- * match. Everything else — Classic family, and any device whose name is not
834
- * known yet — scans first, because connecting by id can resolve a session the
835
- * device no longer serves (see setupConnectionAndDiscoverServices).
836
- */
837
- function shouldConnectByIdFirst(deviceId: string): boolean {
838
- return isPro2FamilyBleName(resolveBleName(deviceId));
839
- }
840
-
841
764
  function handleDeviceDiscovered(peripheral: Peripheral): void {
842
765
  // Only process OneKey candidates for general discovery. Avoid logging every
843
766
  // ambient BLE peripheral; it makes Pro2 debugging hard to read.
@@ -847,7 +770,6 @@ function handleDeviceDiscovered(peripheral: Peripheral): void {
847
770
 
848
771
  const isNewDevice = !discoveredDevices.has(peripheral.id);
849
772
  discoveredDevices.set(peripheral.id, peripheral);
850
- rememberBleName(peripheral.id, peripheral.advertisement?.localName);
851
773
  if (isNewDevice) {
852
774
  logger?.debug('[NobleBLE] OneKey BLE device discovered', {
853
775
  deviceId: peripheral.id,
@@ -882,10 +804,7 @@ async function waitForNobleScanStop(nobleInstance: NobleModule): Promise<void> {
882
804
 
883
805
  // Perform targeted scan for a specific device ID
884
806
  // Uses self-contained local listener pattern - no global state needed
885
- async function performTargetedScan(
886
- targetDeviceId: string,
887
- timeoutMs: number = NOBLE_BLE_TARGETED_SCAN_TIMEOUT_MS
888
- ): Promise<Peripheral | null> {
807
+ async function performTargetedScan(targetDeviceId: string): Promise<Peripheral | null> {
889
808
  if (!noble) {
890
809
  throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Noble not available');
891
810
  }
@@ -930,7 +849,7 @@ async function performTargetedScan(
930
849
  const timeoutId = setTimeout(() => {
931
850
  logger?.info('[NobleBLE] Targeted scan timeout for device:', targetDeviceId);
932
851
  finish(null).catch(reject);
933
- }, timeoutMs);
852
+ }, NOBLE_BLE_TARGETED_SCAN_TIMEOUT_MS);
934
853
 
935
854
  // Add local listener for this scan
936
855
  nobleInstance.on('discover', onDiscover);
@@ -1237,10 +1156,7 @@ async function forceReconnectPeripheral(peripheral: Peripheral, deviceId: string
1237
1156
  reason: 'force-reconnect',
1238
1157
  });
1239
1158
 
1240
- // Step 2: Force disconnect if connected. Wait for the teardown to be
1241
- // confirmed: reconnecting while CoreBluetooth is still closing the old link
1242
- // rebuilds the very stale-session state this reset exists to clear, and
1243
- // 250ms is not enough to prove a physical teardown on macOS.
1159
+ // Step 2: Force disconnect if connected
1244
1160
  if (peripheral.state === 'connected') {
1245
1161
  await runBleCallbackOperation(
1246
1162
  callback =>
@@ -1248,13 +1164,8 @@ async function forceReconnectPeripheral(peripheral: Peripheral, deviceId: string
1248
1164
  logger?.info('[NobleBLE] Force disconnect completed');
1249
1165
  callback();
1250
1166
  }),
1251
- { timeoutMs: BLE_DISCONNECT_CONFIRM_TIMEOUT_MS, timeoutBehavior: 'resolve' }
1167
+ { timeoutMs: BLE_CLEANUP_TIMEOUT, timeoutBehavior: 'resolve' }
1252
1168
  );
1253
- if (peripheral.state === 'connected') {
1254
- logger?.warn('[NobleBLE] Reset disconnect did not confirm, reconnecting anyway', {
1255
- deviceId,
1256
- });
1257
- }
1258
1169
  }
1259
1170
 
1260
1171
  // Step 3: Re-establish connection
@@ -1394,28 +1305,26 @@ async function setupConnectionAndDiscoverServices(
1394
1305
  deviceId: string,
1395
1306
  webContents: WebContents
1396
1307
  ): Promise<CharacteristicPair> {
1397
- // Reset the link before any protocol traffic reaches the device. 6.5.0 did
1398
- // this on every cold setup and never produced a protocol-deaf Classic 1S
1399
- // (control log 2026-08-20: 16/16 links answered within ~1s, including after
1400
- // a 15-minute idle). Demoting it to a discovery-failure fallback removed the
1401
- // reset entirely for this device, because discovery always succeeds: the link
1402
- // comes up, GATT resolves from cache, and the device then answers nothing on
1403
- // a session it no longer serves. Costs ~1.3s per cold setup; a kept-alive
1404
- // link with an intact subscription returns before reaching here, so reuse
1405
- // inside a workflow is unaffected.
1308
+ setupDisconnectListener(peripheral, deviceId, webContents);
1309
+
1406
1310
  try {
1407
- await forceReconnectPeripheral(peripheral, deviceId);
1408
- } catch (resetError) {
1409
- // A failed reset must not abort the attempt: discovery on the existing
1410
- // link, then the fresh-scan fallback, still have a chance to recover.
1411
- logger?.error('[NobleBLE] Connection reset before discovery failed, continuing', resetError);
1311
+ return await discoverServicesAndCharacteristicsWithRetry(peripheral, deviceId);
1312
+ } catch (initialError) {
1313
+ logger?.info('[NobleBLE] Direct service discovery failed, retrying after reconnect', {
1314
+ deviceId,
1315
+ error: initialError,
1316
+ });
1412
1317
  }
1413
- setupDisconnectListener(peripheral, deviceId, webContents);
1414
1318
 
1319
+ await forceReconnectPeripheral(peripheral, deviceId);
1320
+ setupDisconnectListener(peripheral, deviceId, webContents);
1415
1321
  try {
1416
1322
  return await discoverServicesAndCharacteristicsWithRetry(peripheral, deviceId);
1417
- } catch (discoveryError) {
1418
- logger?.error('[NobleBLE] Service discovery failed, attempting fresh scan...', discoveryError);
1323
+ } catch (reconnectError) {
1324
+ logger?.error(
1325
+ '[NobleBLE] Service discovery failed after reconnect, attempting fresh scan...',
1326
+ reconnectError
1327
+ );
1419
1328
  return freshScanAndDiscover(deviceId, webContents);
1420
1329
  }
1421
1330
  }
@@ -1504,7 +1413,10 @@ async function connectDevice(deviceId: string, webContents: WebContents): Promis
1504
1413
  // enumerate clears the discovery map; a kept-alive link outlives it.
1505
1414
  let peripheral = discoveredDevices.get(deviceId) ?? connectedDevices.get(deviceId);
1506
1415
 
1416
+ // If device not discovered, try a targeted scan for this specific device
1507
1417
  if (!peripheral) {
1418
+ logger?.info('[NobleBLE] Device not discovered, attempting targeted scan for:', deviceId);
1419
+
1508
1420
  // Initialize Noble if not already done
1509
1421
  if (!noble) {
1510
1422
  await initializeNoble();
@@ -1514,58 +1426,27 @@ async function connectDevice(deviceId: string, webContents: WebContents): Promis
1514
1426
  throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Noble not available');
1515
1427
  }
1516
1428
 
1517
- // A live advertisement proves the device holds no link and will open a
1518
- // fresh session; connecting by id resolves through the OS cache instead
1519
- // and can hand back a session the device no longer serves (see
1520
- // setupConnectionAndDiscoverServices). Scanning is also the faster of the
1521
- // two when the device does advertise: ~96ms median against ~784ms for
1522
- // connect-by-id across the field logs. Pro2/Neo keep connect-by-id first
1523
- // because they are unaffected and may advertise under an unmatchable Find
1524
- // My name.
1525
- const byIdFirst = shouldConnectByIdFirst(deviceId);
1526
- logger?.info('[NobleBLE] Resolving device for cold connect', {
1527
- deviceId,
1528
- name: resolveBleName(deviceId) ?? 'unknown',
1529
- strategy: byIdFirst ? 'connect-by-id-first' : 'scan-first',
1530
- });
1531
-
1532
- const scanForPeripheral = async () => {
1533
- try {
1534
- return (await performTargetedScan(deviceId, BLE_COLD_CONNECT_SCAN_TIMEOUT_MS)) ?? undefined;
1535
- } catch (scanError) {
1536
- logger?.info('[NobleBLE] Targeted scan failed', {
1537
- deviceId,
1538
- error: scanError instanceof Error ? scanError.message : String(scanError),
1539
- });
1540
- return undefined;
1541
- }
1542
- };
1543
-
1544
- const connectById = async () => {
1545
- const found = await tryDirectConnectById(deviceId);
1546
- if (found) {
1547
- discoveredDevices.set(deviceId, found);
1548
- }
1549
- return found;
1550
- };
1551
-
1552
- peripheral = byIdFirst ? await connectById() : await scanForPeripheral();
1553
- if (!peripheral) {
1554
- // The preferred route came up empty: not advertising (held elsewhere, or
1555
- // silent), or not reachable by id. Try the other one before giving up.
1556
- peripheral = byIdFirst ? await scanForPeripheral() : await connectById();
1429
+ // Reaches a bonded device that is not advertising; else falls to the scan.
1430
+ peripheral = await tryDirectConnectById(deviceId);
1431
+ if (peripheral) {
1432
+ discoveredDevices.set(deviceId, peripheral);
1557
1433
  }
1558
- if (!peripheral) {
1559
- // Neither route resolved a peripheral: a bonded device that has gone
1560
- // silent, or connect-by-id sitting in its cooldown. The evicted object is
1561
- // worse than a fresh one, but it beats failing the call outright.
1562
- const stale = stalePeripherals.get(deviceId);
1563
- if (stale) {
1564
- logger?.info('[NobleBLE] Falling back to the last known peripheral:', deviceId);
1565
- peripheral = stale;
1434
+ }
1435
+
1436
+ if (!peripheral) {
1437
+ // Perform a targeted scan to find the specific device
1438
+ try {
1439
+ const foundPeripheral = await performTargetedScan(deviceId);
1440
+ if (!foundPeripheral) {
1441
+ throw ERRORS.TypedError(
1442
+ HardwareErrorCode.DeviceNotFound,
1443
+ `Device ${deviceId} not found even after targeted scan`
1444
+ );
1566
1445
  }
1567
- } else {
1568
- stalePeripherals.delete(deviceId);
1446
+ peripheral = foundPeripheral;
1447
+ } catch (error) {
1448
+ logger?.error('[NobleBLE] Targeted scan failed:', error);
1449
+ throw error;
1569
1450
  }
1570
1451
  }
1571
1452
 
@@ -1574,10 +1455,6 @@ async function connectDevice(deviceId: string, webContents: WebContents): Promis
1574
1455
  throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound, `Device ${deviceId} not found`);
1575
1456
  }
1576
1457
 
1577
- // Also covers the connect-by-id route, whose simulated discovery carries no
1578
- // service UUIDs and therefore never reaches handleDeviceDiscovered.
1579
- rememberBleName(deviceId, peripheral.advertisement?.localName);
1580
-
1581
1458
  logger?.info('[NobleBLE] Connecting to device:', deviceId);
1582
1459
 
1583
1460
  // Check if device is already connected
@@ -1720,18 +1597,11 @@ async function disconnectDevice(deviceId: string): Promise<void> {
1720
1597
  }
1721
1598
 
1722
1599
  await runBleCallbackOperation(callback => peripheral.disconnect(() => callback()), {
1723
- timeoutMs: BLE_DISCONNECT_CONFIRM_TIMEOUT_MS,
1600
+ timeoutMs: BLE_CLEANUP_TIMEOUT,
1724
1601
  timeoutBehavior: 'resolve',
1725
1602
  });
1726
- if (peripheral.state === 'connected') {
1727
- logger?.warn('[NobleBLE] Physical disconnect did not confirm in time', { deviceId });
1728
- }
1729
1603
  cleanupDevice(deviceId, undefined, {
1730
1604
  cleanupConnection: true,
1731
- // macOS returns zero GATT services when a previously-disconnected
1732
- // peripheral object is reconnected; drop the discovery cache so the next
1733
- // connect resolves a fresh peripheral (direct connect by id, or scan).
1734
- cleanupDiscoveredCache: true,
1735
1605
  sendDisconnectEvent: false,
1736
1606
  cancelOperations: true,
1737
1607
  reason: 'manual-disconnect',
@@ -2057,12 +1927,10 @@ export function setupNobleBleHandlers(webContents: WebContents): void {
2057
1927
  }
2058
1928
 
2059
1929
  await stopScanning().catch(() => undefined);
2060
- // persistentStateListener is process-lifetime, NOT per-window: this
2061
- // destroy handler also fires on a renderer soft restart, and removing
2062
- // the listener here permanently killed poweredOff/poweredOn
2063
- // reconciliation for the rest of the process (nothing re-registers it:
2064
- // initializeNoble early-returns once noble is loaded). The null-guard
2065
- // in setupPersistentStateListener keeps it deduped to one instance.
1930
+ if (noble && persistentStateListener) {
1931
+ noble.removeListener('stateChange', persistentStateListener);
1932
+ persistentStateListener = null;
1933
+ }
2066
1934
  cleanupNobleListeners();
2067
1935
  discoveredDevices.clear();
2068
1936
  safeLog(logger, 'info', 'Noble BLE cleanup completed');
@@ -39,7 +39,6 @@ export interface NobleModule {
39
39
  export interface Logger {
40
40
  info(message: string, ...args: any[]): void;
41
41
  debug(message: string, ...args: any[]): void;
42
- warn(message: string, ...args: any[]): void;
43
42
  error(message: string, ...args: any[]): void;
44
43
  }
45
44