@onekeyfe/hwk-trezor-connector-electron-ble 1.2.4 → 1.2.5-alpha.0

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/dist/index.d.mts CHANGED
@@ -1,12 +1,10 @@
1
1
  import { TrezorDebugLogger, TrezorConnectorBase, TrezorConnectorBaseOptions, TrezorConnectorByteTransport } from '@onekeyfe/hwk-trezor-connector';
2
- import { T as TrezorBleApi, a as TrezorBleDeviceInfo } from './desktop-api-DDNonbNW.mjs';
3
- export { b as TrezorBleAvailability } from './desktop-api-DDNonbNW.mjs';
4
- import { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
5
- export { TREZOR_BLE_CHANNELS, TREZOR_BLE_POWER_ON_TIMEOUT_MS, TREZOR_BLE_SCAN_DURATION_MS, TREZOR_BLE_WRITE_CHUNK_DELAY_MS, TrezorBleChannel } from './constants.mjs';
2
+ import { ThirdPartyBleApi, ThirdPartyBleDeviceInfo } from '@onekeyfe/hwk-desktop-noble-ble';
3
+ import { ConnectorDevice, ElectronBleConnectOptions, ElectronBleMatch } from '@onekeyfe/hwk-adapter-core';
6
4
 
7
5
  interface TrezorElectronBleTransportOptions {
8
6
  /** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */
9
- bridge?: TrezorBleApi;
7
+ bridge?: ThirdPartyBleApi;
10
8
  logger?: TrezorDebugLogger;
11
9
  }
12
10
  /**
@@ -17,6 +15,7 @@ interface TrezorElectronBleTransportOptions {
17
15
  declare class TrezorElectronBleTransport {
18
16
  private readonly _bridge;
19
17
  private readonly _connected;
18
+ private readonly _connecting;
20
19
  private readonly _readQueues;
21
20
  private readonly _pendingReads;
22
21
  private readonly _disconnectHandlers;
@@ -24,10 +23,10 @@ declare class TrezorElectronBleTransport {
24
23
  private _disposeDisconnectListener?;
25
24
  private readonly _logger?;
26
25
  constructor(options?: TrezorElectronBleTransportOptions);
27
- scan(durationMs?: number): Promise<TrezorBleDeviceInfo[]>;
26
+ scan(durationMs?: number): Promise<ThirdPartyBleDeviceInfo[]>;
28
27
  stopScan(): Promise<void>;
29
28
  /** Abandon the in-flight connect/pairing in the main process. */
30
- cancelPairing(): Promise<void>;
29
+ cancelPairing(connectId?: string): Promise<void>;
31
30
  connect(connectId: string): Promise<void>;
32
31
  disconnect(connectId: string): Promise<void>;
33
32
  write(connectId: string, data: Uint8Array): Promise<void>;
@@ -36,6 +35,7 @@ declare class TrezorElectronBleTransport {
36
35
  /** Tear down global listeners — called by the connector's `reset()`. */
37
36
  reset(): void;
38
37
  private _wireGlobalListeners;
38
+ private _handleDeviceDisconnected;
39
39
  private _failPendingReads;
40
40
  private _log;
41
41
  }
@@ -62,4 +62,18 @@ declare class TrezorElectronBleConnector extends TrezorConnectorBase {
62
62
  }
63
63
  declare function createTrezorElectronBleConnector(options?: TrezorElectronBleConnectorOptions): TrezorElectronBleConnector;
64
64
 
65
- export { TrezorBleApi, TrezorBleDeviceInfo, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
65
+ /** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */
66
+ declare const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
67
+ declare const TREZOR_BLE_VENDOR = "trezor";
68
+ /**
69
+ * Trezor matcher sent to the vendor-agnostic main process. A name must match every
70
+ * pattern, like `isTrezorSafe7BleName`: "Trezor" plus "Safe 7" or "T3W1".
71
+ */
72
+ declare const TREZOR_BLE_MATCH: ElectronBleMatch;
73
+ /**
74
+ * Trezor firmware expects fixed-size packets: a short final packet is silently
75
+ * dropped, so every write is padded to the full MTU.
76
+ */
77
+ declare const TREZOR_BLE_CONNECT_PROFILE: ElectronBleConnectOptions;
78
+
79
+ export { TREZOR_BLE_CONNECT_PROFILE, TREZOR_BLE_MATCH, TREZOR_BLE_VENDOR, TREZOR_BLE_WRITE_CHUNK_DELAY_MS, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import { TrezorDebugLogger, TrezorConnectorBase, TrezorConnectorBaseOptions, TrezorConnectorByteTransport } from '@onekeyfe/hwk-trezor-connector';
2
- import { T as TrezorBleApi, a as TrezorBleDeviceInfo } from './desktop-api-DDNonbNW.js';
3
- export { b as TrezorBleAvailability } from './desktop-api-DDNonbNW.js';
4
- import { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
5
- export { TREZOR_BLE_CHANNELS, TREZOR_BLE_POWER_ON_TIMEOUT_MS, TREZOR_BLE_SCAN_DURATION_MS, TREZOR_BLE_WRITE_CHUNK_DELAY_MS, TrezorBleChannel } from './constants.js';
2
+ import { ThirdPartyBleApi, ThirdPartyBleDeviceInfo } from '@onekeyfe/hwk-desktop-noble-ble';
3
+ import { ConnectorDevice, ElectronBleConnectOptions, ElectronBleMatch } from '@onekeyfe/hwk-adapter-core';
6
4
 
7
5
  interface TrezorElectronBleTransportOptions {
8
6
  /** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */
9
- bridge?: TrezorBleApi;
7
+ bridge?: ThirdPartyBleApi;
10
8
  logger?: TrezorDebugLogger;
11
9
  }
12
10
  /**
@@ -17,6 +15,7 @@ interface TrezorElectronBleTransportOptions {
17
15
  declare class TrezorElectronBleTransport {
18
16
  private readonly _bridge;
19
17
  private readonly _connected;
18
+ private readonly _connecting;
20
19
  private readonly _readQueues;
21
20
  private readonly _pendingReads;
22
21
  private readonly _disconnectHandlers;
@@ -24,10 +23,10 @@ declare class TrezorElectronBleTransport {
24
23
  private _disposeDisconnectListener?;
25
24
  private readonly _logger?;
26
25
  constructor(options?: TrezorElectronBleTransportOptions);
27
- scan(durationMs?: number): Promise<TrezorBleDeviceInfo[]>;
26
+ scan(durationMs?: number): Promise<ThirdPartyBleDeviceInfo[]>;
28
27
  stopScan(): Promise<void>;
29
28
  /** Abandon the in-flight connect/pairing in the main process. */
30
- cancelPairing(): Promise<void>;
29
+ cancelPairing(connectId?: string): Promise<void>;
31
30
  connect(connectId: string): Promise<void>;
32
31
  disconnect(connectId: string): Promise<void>;
33
32
  write(connectId: string, data: Uint8Array): Promise<void>;
@@ -36,6 +35,7 @@ declare class TrezorElectronBleTransport {
36
35
  /** Tear down global listeners — called by the connector's `reset()`. */
37
36
  reset(): void;
38
37
  private _wireGlobalListeners;
38
+ private _handleDeviceDisconnected;
39
39
  private _failPendingReads;
40
40
  private _log;
41
41
  }
@@ -62,4 +62,18 @@ declare class TrezorElectronBleConnector extends TrezorConnectorBase {
62
62
  }
63
63
  declare function createTrezorElectronBleConnector(options?: TrezorElectronBleConnectorOptions): TrezorElectronBleConnector;
64
64
 
65
- export { TrezorBleApi, TrezorBleDeviceInfo, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
65
+ /** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */
66
+ declare const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
67
+ declare const TREZOR_BLE_VENDOR = "trezor";
68
+ /**
69
+ * Trezor matcher sent to the vendor-agnostic main process. A name must match every
70
+ * pattern, like `isTrezorSafe7BleName`: "Trezor" plus "Safe 7" or "T3W1".
71
+ */
72
+ declare const TREZOR_BLE_MATCH: ElectronBleMatch;
73
+ /**
74
+ * Trezor firmware expects fixed-size packets: a short final packet is silently
75
+ * dropped, so every write is padded to the full MTU.
76
+ */
77
+ declare const TREZOR_BLE_CONNECT_PROFILE: ElectronBleConnectOptions;
78
+
79
+ export { TREZOR_BLE_CONNECT_PROFILE, TREZOR_BLE_MATCH, TREZOR_BLE_VENDOR, TREZOR_BLE_WRITE_CHUNK_DELAY_MS, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
package/dist/index.js CHANGED
@@ -20,9 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- TREZOR_BLE_CHANNELS: () => TREZOR_BLE_CHANNELS,
24
- TREZOR_BLE_POWER_ON_TIMEOUT_MS: () => TREZOR_BLE_POWER_ON_TIMEOUT_MS,
25
- TREZOR_BLE_SCAN_DURATION_MS: () => TREZOR_BLE_SCAN_DURATION_MS,
23
+ TREZOR_BLE_CONNECT_PROFILE: () => TREZOR_BLE_CONNECT_PROFILE,
24
+ TREZOR_BLE_MATCH: () => TREZOR_BLE_MATCH,
25
+ TREZOR_BLE_VENDOR: () => TREZOR_BLE_VENDOR,
26
26
  TREZOR_BLE_WRITE_CHUNK_DELAY_MS: () => TREZOR_BLE_WRITE_CHUNK_DELAY_MS,
27
27
  TrezorElectronBleConnector: () => TrezorElectronBleConnector,
28
28
  TrezorElectronBleTransport: () => TrezorElectronBleTransport,
@@ -33,7 +33,7 @@ module.exports = __toCommonJS(index_exports);
33
33
 
34
34
  // src/TrezorElectronBleConnector.ts
35
35
  var import_buffer2 = require("buffer");
36
- var import_hwk_trezor_adapter = require("@onekeyfe/hwk-trezor-adapter");
36
+ var import_hwk_trezor_adapter2 = require("@onekeyfe/hwk-trezor-adapter");
37
37
  var import_hwk_adapter_core2 = require("@onekeyfe/hwk-adapter-core");
38
38
  var import_hwk_trezor_connector2 = require("@onekeyfe/hwk-trezor-connector");
39
39
 
@@ -41,6 +41,28 @@ var import_hwk_trezor_connector2 = require("@onekeyfe/hwk-trezor-connector");
41
41
  var import_buffer = require("buffer");
42
42
  var import_hwk_adapter_core = require("@onekeyfe/hwk-adapter-core");
43
43
  var import_hwk_trezor_connector = require("@onekeyfe/hwk-trezor-connector");
44
+
45
+ // src/bleProfile.ts
46
+ var import_hwk_trezor_adapter = require("@onekeyfe/hwk-trezor-adapter");
47
+ var TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
48
+ var TREZOR_BLE_VENDOR = "trezor";
49
+ var TREZOR_BLE_MATCH = {
50
+ serviceUuids: [import_hwk_trezor_adapter.TREZOR_BLE_UUIDS.service],
51
+ namePatterns: ["\\bTrezor\\b", "\\bSafe\\s*7\\b|\\bT3W1\\b"]
52
+ };
53
+ var TREZOR_BLE_CONNECT_PROFILE = {
54
+ vendor: TREZOR_BLE_VENDOR,
55
+ serviceUuid: import_hwk_trezor_adapter.TREZOR_BLE_UUIDS.service,
56
+ writeUuid: import_hwk_trezor_adapter.TREZOR_BLE_UUIDS.write,
57
+ notifyUuid: import_hwk_trezor_adapter.TREZOR_BLE_UUIDS.notify,
58
+ write: {
59
+ mode: "padded",
60
+ chunkSize: import_hwk_trezor_adapter.TREZOR_BLE_PACKET_SIZE,
61
+ chunkDelayMs: TREZOR_BLE_WRITE_CHUNK_DELAY_MS
62
+ }
63
+ };
64
+
65
+ // src/TrezorElectronBleTransport.ts
44
66
  var disconnectError = (message) => Object.assign(new Error(message), { code: import_hwk_adapter_core.HardwareErrorCode.DeviceDisconnected });
45
67
  var notConnectedError = (id) => disconnectError(`Trezor Electron BLE device is not connected: ${id}`);
46
68
  var resolveBridge = (options) => {
@@ -58,6 +80,7 @@ var resolveBridge = (options) => {
58
80
  var TrezorElectronBleTransport = class {
59
81
  constructor(options = {}) {
60
82
  this._connected = /* @__PURE__ */ new Set();
83
+ this._connecting = /* @__PURE__ */ new Map();
61
84
  this._readQueues = /* @__PURE__ */ new Map();
62
85
  this._pendingReads = /* @__PURE__ */ new Map();
63
86
  this._disconnectHandlers = /* @__PURE__ */ new Map();
@@ -68,6 +91,8 @@ var TrezorElectronBleTransport = class {
68
91
  async scan(durationMs) {
69
92
  try {
70
93
  return await this._bridge.scan({
94
+ vendor: TREZOR_BLE_VENDOR,
95
+ match: TREZOR_BLE_MATCH,
71
96
  durationMs
72
97
  });
73
98
  } catch (error) {
@@ -78,24 +103,55 @@ var TrezorElectronBleTransport = class {
78
103
  }
79
104
  }
80
105
  async stopScan() {
81
- await this._bridge.stopScan();
106
+ await this._bridge.stopScan(TREZOR_BLE_VENDOR);
82
107
  }
83
108
  /** Abandon the in-flight connect/pairing in the main process. */
84
- async cancelPairing() {
85
- await this._bridge.cancelPairing();
109
+ async cancelPairing(connectId) {
110
+ const ids = new Set(
111
+ [...this._connecting.keys(), ...this._connected].filter(
112
+ (id) => connectId === void 0 || id === connectId
113
+ )
114
+ );
115
+ for (const id of ids) {
116
+ const claim = this._connecting.get(id);
117
+ if (claim) claim.cancelled = true;
118
+ }
119
+ await Promise.all(
120
+ Array.from(ids, async (id) => {
121
+ await this._bridge.cancelPairing({ vendor: TREZOR_BLE_VENDOR, id });
122
+ if (this._connected.has(id)) this._handleDeviceDisconnected(id);
123
+ })
124
+ );
125
+ if (connectId === void 0) await this.stopScan();
86
126
  }
87
127
  async connect(connectId) {
88
128
  if (this._connected.has(connectId)) return;
89
- await this._bridge.connect(connectId);
129
+ const claim = { cancelled: false };
130
+ this._connecting.set(connectId, claim);
131
+ const assertActive = () => {
132
+ if (claim.cancelled) {
133
+ throw (0, import_hwk_adapter_core.createHwkError)({
134
+ code: import_hwk_adapter_core.HardwareErrorCode.BlePairingCancelled,
135
+ message: "Trezor BLE pairing cancelled"
136
+ });
137
+ }
138
+ };
90
139
  try {
91
- await this._bridge.subscribe(connectId);
92
- } catch (error) {
93
- await this._bridge.disconnect(connectId).catch(() => void 0);
94
- throw error;
140
+ await this._bridge.connect(connectId, TREZOR_BLE_CONNECT_PROFILE);
141
+ try {
142
+ assertActive();
143
+ await this._bridge.subscribe(connectId);
144
+ assertActive();
145
+ } catch (error) {
146
+ await this._bridge.disconnect(connectId).catch(() => void 0);
147
+ throw error;
148
+ }
149
+ this._connected.add(connectId);
150
+ this._readQueues.set(connectId, []);
151
+ this._pendingReads.set(connectId, []);
152
+ } finally {
153
+ if (this._connecting.get(connectId) === claim) this._connecting.delete(connectId);
95
154
  }
96
- this._connected.add(connectId);
97
- this._readQueues.set(connectId, []);
98
- this._pendingReads.set(connectId, []);
99
155
  }
100
156
  async disconnect(connectId) {
101
157
  this._connected.delete(connectId);
@@ -164,16 +220,19 @@ var TrezorElectronBleTransport = class {
164
220
  if (queue) queue.push(data);
165
221
  });
166
222
  this._disposeDisconnectListener = this._bridge.onDeviceDisconnected((id) => {
167
- this._connected.delete(id);
168
- this._failPendingReads(id, disconnectError(`Trezor BLE device disconnected: ${id}`));
169
- this._readQueues.delete(id);
170
- this._disconnectHandlers.get(id)?.forEach((handler) => {
171
- try {
172
- handler();
173
- } catch (error) {
174
- this._log("error", "disconnect.handler.threw", { id, error: String(error) });
175
- }
176
- });
223
+ this._handleDeviceDisconnected(id);
224
+ });
225
+ }
226
+ _handleDeviceDisconnected(id) {
227
+ this._connected.delete(id);
228
+ this._failPendingReads(id, disconnectError(`Trezor BLE device disconnected: ${id}`));
229
+ this._readQueues.delete(id);
230
+ this._disconnectHandlers.get(id)?.forEach((handler) => {
231
+ try {
232
+ handler();
233
+ } catch (error) {
234
+ this._log("error", "disconnect.handler.threw", { id, error: String(error) });
235
+ }
177
236
  });
178
237
  }
179
238
  _failPendingReads(connectId, error) {
@@ -198,7 +257,7 @@ var TrezorElectronBleConnector = class extends import_hwk_trezor_connector2.Trez
198
257
  constructor(options) {
199
258
  super({
200
259
  connectionType: "ble",
201
- chunkSize: import_hwk_trezor_adapter.TREZOR_BLE_PACKET_SIZE,
260
+ chunkSize: import_hwk_trezor_adapter2.TREZOR_BLE_PACKET_SIZE,
202
261
  thp: options?.thp,
203
262
  deviceSessionFactory: options?.deviceSessionFactory
204
263
  });
@@ -209,13 +268,13 @@ var TrezorElectronBleConnector = class extends import_hwk_trezor_connector2.Trez
209
268
  async enumerateDevices() {
210
269
  const transport = this._ensureTransport();
211
270
  const devices = await transport.scan();
212
- const filtered = devices.filter(import_hwk_trezor_adapter.isTrezorBleDescriptor);
271
+ const filtered = devices.filter(import_hwk_trezor_adapter2.isTrezorBleDescriptor);
213
272
  if (filtered.length !== devices.length) {
214
273
  this._log("info", "ble.connector.enumerate.filtered", {
215
274
  transport: "electron-ble",
216
275
  descriptorCount: devices.length,
217
276
  filteredCount: filtered.length,
218
- dropped: devices.filter((device) => !(0, import_hwk_trezor_adapter.isTrezorBleDescriptor)(device)).map(toBleFilterLogSample),
277
+ dropped: devices.filter((device) => !(0, import_hwk_trezor_adapter2.isTrezorBleDescriptor)(device)).map(toBleFilterLogSample),
219
278
  kept: filtered.map(toBleFilterLogSample)
220
279
  });
221
280
  }
@@ -223,7 +282,7 @@ var TrezorElectronBleConnector = class extends import_hwk_trezor_connector2.Trez
223
282
  connectId: d.id,
224
283
  deviceId: "",
225
284
  name: d.name ?? d.localName ?? "Trezor Safe 7",
226
- model: import_hwk_trezor_adapter.TREZOR_SAFE_7_MODEL,
285
+ model: import_hwk_trezor_adapter2.TREZOR_SAFE_7_MODEL,
227
286
  connectionType: "ble",
228
287
  // Promote the typed BLE fields the device surface already has slots for.
229
288
  rssi: d.rssi ?? null,
@@ -285,14 +344,14 @@ var TrezorElectronBleConnector = class extends import_hwk_trezor_connector2.Trez
285
344
  connectId,
286
345
  deviceId: "",
287
346
  name: "Trezor Safe 7",
288
- model: import_hwk_trezor_adapter.TREZOR_SAFE_7_MODEL,
347
+ model: import_hwk_trezor_adapter2.TREZOR_SAFE_7_MODEL,
289
348
  capabilities: { persistentDeviceIdentity: false }
290
349
  };
291
350
  }
292
351
  async cancel(sessionId) {
293
352
  await super.cancel(sessionId);
294
353
  try {
295
- await this._transport?.cancelPairing();
354
+ await this._transport?.cancelPairing(sessionId);
296
355
  } catch {
297
356
  }
298
357
  }
@@ -332,7 +391,7 @@ function toBleFilterLogSample(device) {
332
391
  rssi: device.rssi,
333
392
  isConnectable: device.isConnectable,
334
393
  keys: Object.keys(device).sort(),
335
- matchesTrezorService: (0, import_hwk_trezor_adapter.isTrezorBleDescriptor)(device),
394
+ matchesTrezorService: (0, import_hwk_trezor_adapter2.isTrezorBleDescriptor)(device),
336
395
  serviceUUIDs: readStringArrayField(device, "serviceUUIDs"),
337
396
  serviceUuids: readStringArrayField(device, "serviceUuids"),
338
397
  advertisedServiceUuids: readStringArrayField(device, "advertisedServiceUuids"),
@@ -345,33 +404,11 @@ function toBleFilterLogSample(device) {
345
404
  state: device.state
346
405
  };
347
406
  }
348
-
349
- // src/constants.ts
350
- var TREZOR_BLE_CHANNELS = {
351
- scan: "$onekey-trezor-ble-scan",
352
- stopScan: "$onekey-trezor-ble-stop-scan",
353
- connect: "$onekey-trezor-ble-connect",
354
- disconnect: "$onekey-trezor-ble-disconnect",
355
- write: "$onekey-trezor-ble-write",
356
- subscribe: "$onekey-trezor-ble-subscribe",
357
- unsubscribe: "$onekey-trezor-ble-unsubscribe",
358
- availability: "$onekey-trezor-ble-availability",
359
- getDevice: "$onekey-trezor-ble-get-device",
360
- readRssi: "$onekey-trezor-ble-read-rssi",
361
- cancelPairing: "$onekey-trezor-ble-cancel-pairing",
362
- /** push event: main → renderer with assembled BLE notification payload */
363
- notification: "$onekey-trezor-ble-notification",
364
- /** push event: main → renderer when device disconnects unexpectedly */
365
- disconnected: "$onekey-trezor-ble-disconnected"
366
- };
367
- var TREZOR_BLE_SCAN_DURATION_MS = 5e3;
368
- var TREZOR_BLE_POWER_ON_TIMEOUT_MS = 1e4;
369
- var TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
370
407
  // Annotate the CommonJS export names for ESM import in node:
371
408
  0 && (module.exports = {
372
- TREZOR_BLE_CHANNELS,
373
- TREZOR_BLE_POWER_ON_TIMEOUT_MS,
374
- TREZOR_BLE_SCAN_DURATION_MS,
409
+ TREZOR_BLE_CONNECT_PROFILE,
410
+ TREZOR_BLE_MATCH,
411
+ TREZOR_BLE_VENDOR,
375
412
  TREZOR_BLE_WRITE_CHUNK_DELAY_MS,
376
413
  TrezorElectronBleConnector,
377
414
  TrezorElectronBleTransport,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/TrezorElectronBleConnector.ts","../src/TrezorElectronBleTransport.ts","../src/constants.ts"],"sourcesContent":["export {\n TrezorElectronBleConnector,\n createTrezorElectronBleConnector,\n} from './TrezorElectronBleConnector';\nexport type { TrezorElectronBleConnectorOptions } from './TrezorElectronBleConnector';\n\nexport {\n TrezorElectronBleTransport,\n createTrezorElectronBleTransport,\n} from './TrezorElectronBleTransport';\nexport type { TrezorElectronBleTransportOptions } from './TrezorElectronBleTransport';\n\nexport {\n TREZOR_BLE_CHANNELS,\n TREZOR_BLE_SCAN_DURATION_MS,\n TREZOR_BLE_POWER_ON_TIMEOUT_MS,\n TREZOR_BLE_WRITE_CHUNK_DELAY_MS,\n} from './constants';\nexport type { TrezorBleChannel } from './constants';\n\nexport type { TrezorBleApi, TrezorBleAvailability, TrezorBleDeviceInfo } from './types/desktop-api';\n","import { Buffer } from 'buffer';\nimport {\n TREZOR_BLE_PACKET_SIZE,\n TREZOR_SAFE_7_MODEL,\n isTrezorBleDescriptor,\n} from '@onekeyfe/hwk-trezor-adapter';\nimport { HardwareErrorCode, createHwkError } from '@onekeyfe/hwk-adapter-core';\nimport {\n TrezorConnectorBase,\n type TrezorConnectorBaseOptions,\n type TrezorConnectorByteTransport,\n type TrezorDebugLogLevel,\n type TrezorDebugLogger,\n filterTrezorDebugLogEntry,\n} from '@onekeyfe/hwk-trezor-connector';\n\nimport {\n TrezorElectronBleTransport,\n type TrezorElectronBleTransportOptions,\n} from './TrezorElectronBleTransport';\n\nimport type { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';\nimport type { TrezorBleDeviceInfo } from './types/desktop-api';\n\nconst isStandardHwkError = (error: unknown): error is { code: number } =>\n typeof (error as { code?: unknown })?.code === 'number';\n\nexport interface TrezorElectronBleConnectorOptions {\n transport?: TrezorElectronBleTransport;\n transportOptions?: TrezorElectronBleTransportOptions;\n thp?: TrezorConnectorBaseOptions['thp'];\n deviceSessionFactory?: TrezorConnectorBaseOptions['deviceSessionFactory'];\n}\n\nexport class TrezorElectronBleConnector extends TrezorConnectorBase {\n private _transport: TrezorElectronBleTransport | undefined;\n\n private readonly _transportOptions?: TrezorElectronBleTransportOptions;\n\n private readonly _logger?: TrezorDebugLogger;\n\n constructor(options?: TrezorElectronBleConnectorOptions) {\n super({\n connectionType: 'ble',\n chunkSize: TREZOR_BLE_PACKET_SIZE,\n thp: options?.thp,\n deviceSessionFactory: options?.deviceSessionFactory,\n });\n this._transport = options?.transport;\n this._transportOptions = options?.transportOptions;\n this._logger = options?.transportOptions?.logger;\n }\n\n protected async enumerateDevices(): Promise<ConnectorDevice[]> {\n const transport = this._ensureTransport();\n const devices = await transport.scan();\n const filtered = devices.filter(isTrezorBleDescriptor);\n if (filtered.length !== devices.length) {\n this._log('info', 'ble.connector.enumerate.filtered', {\n transport: 'electron-ble',\n descriptorCount: devices.length,\n filteredCount: filtered.length,\n dropped: devices.filter(device => !isTrezorBleDescriptor(device)).map(toBleFilterLogSample),\n kept: filtered.map(toBleFilterLogSample),\n });\n }\n return filtered.map(d => ({\n connectId: d.id,\n deviceId: '',\n name: d.name ?? d.localName ?? 'Trezor Safe 7',\n model: TREZOR_SAFE_7_MODEL,\n connectionType: 'ble' as const,\n // Promote the typed BLE fields the device surface already has slots for.\n rssi: d.rssi ?? null,\n isConnectable: d.isConnectable ?? null,\n capabilities: { persistentDeviceIdentity: false },\n // Stash the FULL scan-time advertisement so the app/debug layer sees\n // everything the OS BLE stack exposed (mirrors the WebUSB connector's\n // `raw.descriptor`). This is where a cross-transport identity, if any,\n // would surface (manufacturerData / serviceData / localName).\n raw: {\n transport: 'electron-ble',\n descriptor: d,\n },\n }));\n }\n\n protected async createByteTransport(\n device: ConnectorDevice\n ): Promise<TrezorConnectorByteTransport> {\n const transport = this._ensureTransport();\n try {\n await transport.connect(device.connectId);\n } catch (error) {\n // Rethrowing the caught error (typed `unknown`) as-is is intentional.\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n if (isStandardHwkError(error)) throw error;\n const reason = error instanceof Error ? error.message : String(error);\n // The device wasn't found at all → DeviceNotFound. Otherwise the connect\n // itself failed: noble drops the real CoreBluetooth reason (hardcodes\n // \"connection failed\" / a timeout), so we CANNOT tell a stale bond from an\n // out-of-range / unresponsive device. Surface one honest, generic\n // BleConnectFailed instead of guessing a specific cause.\n if (/device not found/i.test(reason)) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message: `Trezor BLE device not found: ${device.connectId}`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n // cancelPairing abandoned the connect. Reporting that as a connect failure\n // would tell the user the device is unreachable when they are the one who\n // stopped it.\n if (/connect cancelled/i.test(reason)) {\n throw createHwkError({\n code: HardwareErrorCode.BlePairingCancelled,\n message: `Trezor BLE pairing cancelled: ${device.connectId}`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n throw createHwkError({\n code: HardwareErrorCode.BleConnectFailed,\n message: `Trezor BLE connect failed: ${device.connectId} (${reason})`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n\n return {\n write: async (chunk: Buffer) => {\n await transport.write(device.connectId, Uint8Array.from(chunk));\n },\n read: async () => {\n const data = await transport.read(device.connectId);\n return Buffer.from(data);\n },\n close: () => transport.disconnect(device.connectId),\n onDisconnect: (handler: () => void) => transport.onDisconnect(device.connectId, handler),\n };\n }\n\n protected resolveUnlistedDevice(deviceId: string): ConnectorDevice | undefined {\n const connectId = deviceId.trim();\n if (!connectId) return undefined;\n return {\n connectId,\n deviceId: '',\n name: 'Trezor Safe 7',\n model: TREZOR_SAFE_7_MODEL,\n capabilities: { persistentDeviceIdentity: false },\n };\n }\n\n override async cancel(sessionId: string): Promise<void> {\n await super.cancel(sessionId);\n // Base cancel only settles UI waiters; a connect stuck in the main process\n // must be abandoned there.\n try {\n await this._transport?.cancelPairing();\n } catch {\n // Cancel must never throw.\n }\n }\n\n reset(): void {\n super.reset();\n this._transport?.reset();\n this._transport = undefined;\n }\n\n private _ensureTransport(): TrezorElectronBleTransport {\n if (!this._transport) {\n this._transport = new TrezorElectronBleTransport(this._transportOptions);\n }\n return this._transport;\n }\n\n private _log(level: TrezorDebugLogLevel, event: string, data?: Record<string, unknown>): void {\n const entry = filterTrezorDebugLogEntry({ level, scope: 'trezor-electron-ble', event, data });\n if (!entry) return;\n\n try {\n this._logger?.(entry);\n } catch {\n // Debug logging must not affect BLE connector behavior.\n }\n }\n}\n\nexport function createTrezorElectronBleConnector(\n options?: TrezorElectronBleConnectorOptions\n): TrezorElectronBleConnector {\n return new TrezorElectronBleConnector(options);\n}\n\nfunction readStringArrayField(source: TrezorBleDeviceInfo, key: string): string[] | undefined {\n const value = (source as unknown as Record<string, unknown>)[key];\n if (!Array.isArray(value)) return undefined;\n return value.filter((item): item is string => typeof item === 'string');\n}\n\nfunction toBleFilterLogSample(device: TrezorBleDeviceInfo): Record<string, unknown> {\n return {\n id: device.id,\n name: device.name,\n localName: device.localName,\n rssi: device.rssi,\n isConnectable: device.isConnectable,\n keys: Object.keys(device).sort(),\n matchesTrezorService: isTrezorBleDescriptor(device),\n serviceUUIDs: readStringArrayField(device, 'serviceUUIDs'),\n serviceUuids: readStringArrayField(device, 'serviceUuids'),\n advertisedServiceUuids: readStringArrayField(device, 'advertisedServiceUuids'),\n serviceSolicitationUuids: device.serviceSolicitationUuids,\n txPowerLevel: device.txPowerLevel,\n manufacturerDataHex: device.manufacturerDataHex,\n serviceData: device.serviceData,\n address: device.address,\n addressType: device.addressType,\n state: device.state,\n };\n}\n","import { Buffer } from 'buffer';\nimport { HardwareErrorCode, createHwkError } from '@onekeyfe/hwk-adapter-core';\nimport {\n type TrezorDebugLogLevel,\n type TrezorDebugLogger,\n filterTrezorDebugLogEntry,\n} from '@onekeyfe/hwk-trezor-connector';\n\nimport type { TrezorBleApi, TrezorBleDeviceInfo } from './types/desktop-api';\n\nexport interface TrezorElectronBleTransportOptions {\n /** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */\n bridge?: TrezorBleApi;\n logger?: TrezorDebugLogger;\n}\n\nconst disconnectError = (message: string): Error =>\n Object.assign(new Error(message), { code: HardwareErrorCode.DeviceDisconnected });\n\nconst notConnectedError = (id: string): Error =>\n disconnectError(`Trezor Electron BLE device is not connected: ${id}`);\n\nconst resolveBridge = (options?: TrezorElectronBleTransportOptions): TrezorBleApi => {\n if (options?.bridge) return options.bridge;\n const win =\n typeof window !== 'undefined'\n ? (window as unknown as { desktopApi?: { trezorBle?: TrezorBleApi } })\n : undefined;\n const bridge = win?.desktopApi?.trezorBle;\n if (!bridge) {\n throw createHwkError({\n code: HardwareErrorCode.BridgeNotFound,\n message:\n 'TrezorElectronBleTransport: no bridge found — pass `bridge` or expose `window.desktopApi.trezorBle` from your Electron preload script',\n });\n }\n return bridge;\n};\n\ninterface PendingRead {\n resolve(data: Uint8Array): void;\n reject(error: Error): void;\n}\n\n/**\n * Renderer-side wrapper around the main process's BLE handler. Buffers\n * notifications into a per-device read queue so callers can `read()`\n * sequentially without missing chunks that arrive between reads.\n */\nexport class TrezorElectronBleTransport {\n private readonly _bridge: TrezorBleApi;\n\n private readonly _connected = new Set<string>();\n\n private readonly _readQueues = new Map<string, Uint8Array[]>();\n\n private readonly _pendingReads = new Map<string, PendingRead[]>();\n\n private readonly _disconnectHandlers = new Map<string, Set<() => void>>();\n\n private _disposeNotificationListener?: () => void;\n\n private _disposeDisconnectListener?: () => void;\n\n private readonly _logger?: TrezorElectronBleTransportOptions['logger'];\n\n constructor(options: TrezorElectronBleTransportOptions = {}) {\n this._bridge = resolveBridge(options);\n this._logger = options.logger;\n this._wireGlobalListeners();\n }\n\n async scan(durationMs?: number): Promise<TrezorBleDeviceInfo[]> {\n // No serviceUuids filter: a native service-UUID scan filter drops a\n // Safe 7's ADV packets on Windows (its UUID travels in the scan response,\n // not the ADV packet), so the handler scans unfiltered and does the Trezor\n // matching itself in JS. Passing a filter here would at best be ignored by\n // a current handler and at worst re-break discovery on an older one.\n try {\n return await this._bridge.scan({\n durationMs,\n });\n } catch (error) {\n this._log('warn', 'ble.renderer.scan.error', {\n error: String(error),\n });\n throw error;\n }\n }\n\n async stopScan(): Promise<void> {\n await this._bridge.stopScan();\n }\n\n /** Abandon the in-flight connect/pairing in the main process. */\n async cancelPairing(): Promise<void> {\n await this._bridge.cancelPairing();\n }\n\n async connect(connectId: string): Promise<void> {\n if (this._connected.has(connectId)) return;\n await this._bridge.connect(connectId);\n try {\n await this._bridge.subscribe(connectId);\n } catch (error) {\n // Main process is already connected — tear it down so we don't leak a\n // main-side connection the renderer can no longer address.\n await this._bridge.disconnect(connectId).catch(() => undefined);\n throw error;\n }\n this._connected.add(connectId);\n this._readQueues.set(connectId, []);\n this._pendingReads.set(connectId, []);\n }\n\n async disconnect(connectId: string): Promise<void> {\n this._connected.delete(connectId);\n this._failPendingReads(connectId, notConnectedError(connectId));\n this._readQueues.delete(connectId);\n try {\n await this._bridge.unsubscribe(connectId);\n } catch (error) {\n this._log('warn', 'unsubscribe.error', { connectId, error: String(error) });\n }\n await this._bridge.disconnect(connectId);\n }\n\n async write(connectId: string, data: Uint8Array): Promise<void> {\n if (!this._connected.has(connectId)) throw notConnectedError(connectId);\n const hex = Buffer.from(data).toString('hex');\n await this._bridge.write(connectId, hex);\n }\n\n async read(connectId: string): Promise<Uint8Array> {\n if (!this._connected.has(connectId)) throw notConnectedError(connectId);\n const queue = this._readQueues.get(connectId);\n if (queue && queue.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return queue.shift()!;\n }\n return new Promise<Uint8Array>((resolve, reject) => {\n const pending = this._pendingReads.get(connectId);\n if (!pending) {\n reject(notConnectedError(connectId));\n return;\n }\n pending.push({ resolve, reject });\n });\n }\n\n onDisconnect(connectId: string, handler: () => void): () => void {\n const handlers = this._disconnectHandlers.get(connectId) ?? new Set<() => void>();\n handlers.add(handler);\n this._disconnectHandlers.set(connectId, handlers);\n return () => {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._disconnectHandlers.delete(connectId);\n }\n };\n }\n\n /** Tear down global listeners — called by the connector's `reset()`. */\n reset(): void {\n this._disposeNotificationListener?.();\n this._disposeDisconnectListener?.();\n this._disposeNotificationListener = undefined;\n this._disposeDisconnectListener = undefined;\n for (const handlers of this._disconnectHandlers.values()) handlers.clear();\n this._disconnectHandlers.clear();\n for (const id of this._connected) this._failPendingReads(id, notConnectedError(id));\n this._connected.clear();\n this._readQueues.clear();\n this._pendingReads.clear();\n }\n\n private _wireGlobalListeners(): void {\n this._disposeNotificationListener = this._bridge.onNotification((id, hex) => {\n const data = new Uint8Array(Buffer.from(hex, 'hex'));\n const pending = this._pendingReads.get(id);\n if (pending && pending.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n pending.shift()!.resolve(data);\n return;\n }\n const queue = this._readQueues.get(id);\n if (queue) queue.push(data);\n });\n this._disposeDisconnectListener = this._bridge.onDeviceDisconnected(id => {\n this._connected.delete(id);\n this._failPendingReads(id, disconnectError(`Trezor BLE device disconnected: ${id}`));\n this._readQueues.delete(id);\n this._disconnectHandlers.get(id)?.forEach(handler => {\n try {\n handler();\n } catch (error) {\n this._log('error', 'disconnect.handler.threw', { id, error: String(error) });\n }\n });\n });\n }\n\n private _failPendingReads(connectId: string, error: Error): void {\n const pending = this._pendingReads.get(connectId);\n if (!pending) return;\n for (const item of pending) item.reject(error);\n this._pendingReads.set(connectId, []);\n }\n\n private _log(level: TrezorDebugLogLevel, event: string, data?: Record<string, unknown>): void {\n const entry = filterTrezorDebugLogEntry({ level, scope: 'trezor-electron-ble', event, data });\n if (!entry) return;\n\n this._logger?.(entry);\n }\n}\n\nexport function createTrezorElectronBleTransport(\n options?: TrezorElectronBleTransportOptions\n): TrezorElectronBleTransport {\n return new TrezorElectronBleTransport(options);\n}\n","/**\n * IPC channel names exchanged between renderer and main process.\n * Namespaced under `$onekey-trezor-ble-…` to avoid clashing with the\n * existing OneKey BLE handler (`$onekey-noble-ble-…`) when both run in\n * the same Electron app.\n */\nexport const TREZOR_BLE_CHANNELS = {\n scan: '$onekey-trezor-ble-scan',\n stopScan: '$onekey-trezor-ble-stop-scan',\n connect: '$onekey-trezor-ble-connect',\n disconnect: '$onekey-trezor-ble-disconnect',\n write: '$onekey-trezor-ble-write',\n subscribe: '$onekey-trezor-ble-subscribe',\n unsubscribe: '$onekey-trezor-ble-unsubscribe',\n availability: '$onekey-trezor-ble-availability',\n getDevice: '$onekey-trezor-ble-get-device',\n readRssi: '$onekey-trezor-ble-read-rssi',\n cancelPairing: '$onekey-trezor-ble-cancel-pairing',\n /** push event: main → renderer with assembled BLE notification payload */\n notification: '$onekey-trezor-ble-notification',\n /** push event: main → renderer when device disconnects unexpectedly */\n disconnected: '$onekey-trezor-ble-disconnected',\n} as const;\n\nexport type TrezorBleChannel = (typeof TREZOR_BLE_CHANNELS)[keyof typeof TREZOR_BLE_CHANNELS];\n\n/** Reconnect scan window for `connect(id)`. */\nexport const TREZOR_BLE_SCAN_DURATION_MS = 5_000;\n\n/** Continuous scan auto-stops this long after the last poll (reset, not accumulated). */\nexport const TREZOR_BLE_SCAN_IDLE_STOP_MS = 10_000;\n\n/** Drop a device from the snapshot if it hasn't re-advertised within this window. */\nexport const TREZOR_BLE_DEVICE_TTL_MS = 5_000;\n\n/** Time we'll wait for noble to reach `poweredOn` before failing init. */\nexport const TREZOR_BLE_POWER_ON_TIMEOUT_MS = 10_000;\n\n/** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */\nexport const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAAuB;AACvB,gCAIO;AACP,IAAAC,2BAAkD;AAClD,IAAAC,+BAOO;;;ACdP,oBAAuB;AACvB,8BAAkD;AAClD,kCAIO;AAUP,IAAM,kBAAkB,CAAC,YACvB,OAAO,OAAO,IAAI,MAAM,OAAO,GAAG,EAAE,MAAM,0CAAkB,mBAAmB,CAAC;AAElF,IAAM,oBAAoB,CAAC,OACzB,gBAAgB,gDAAgD,EAAE,EAAE;AAEtE,IAAM,gBAAgB,CAAC,YAA8D;AACnF,MAAI,SAAS,OAAQ,QAAO,QAAQ;AACpC,QAAM,MACJ,OAAO,WAAW,cACb,SACD;AACN,QAAM,SAAS,KAAK,YAAY;AAChC,MAAI,CAAC,QAAQ;AACX,cAAM,wCAAe;AAAA,MACnB,MAAM,0CAAkB;AAAA,MACxB,SACE;AAAA,IACJ,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAYO,IAAM,6BAAN,MAAiC;AAAA,EAiBtC,YAAY,UAA6C,CAAC,GAAG;AAd7D,SAAiB,aAAa,oBAAI,IAAY;AAE9C,SAAiB,cAAc,oBAAI,IAA0B;AAE7D,SAAiB,gBAAgB,oBAAI,IAA2B;AAEhE,SAAiB,sBAAsB,oBAAI,IAA6B;AAStE,SAAK,UAAU,cAAc,OAAO;AACpC,SAAK,UAAU,QAAQ;AACvB,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,MAAM,KAAK,YAAqD;AAM9D,QAAI;AACF,aAAO,MAAM,KAAK,QAAQ,KAAK;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,KAAK,QAAQ,2BAA2B;AAAA,QAC3C,OAAO,OAAO,KAAK;AAAA,MACrB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,WAA0B;AAC9B,UAAM,KAAK,QAAQ,SAAS;AAAA,EAC9B;AAAA;AAAA,EAGA,MAAM,gBAA+B;AACnC,UAAM,KAAK,QAAQ,cAAc;AAAA,EACnC;AAAA,EAEA,MAAM,QAAQ,WAAkC;AAC9C,QAAI,KAAK,WAAW,IAAI,SAAS,EAAG;AACpC,UAAM,KAAK,QAAQ,QAAQ,SAAS;AACpC,QAAI;AACF,YAAM,KAAK,QAAQ,UAAU,SAAS;AAAA,IACxC,SAAS,OAAO;AAGd,YAAM,KAAK,QAAQ,WAAW,SAAS,EAAE,MAAM,MAAM,MAAS;AAC9D,YAAM;AAAA,IACR;AACA,SAAK,WAAW,IAAI,SAAS;AAC7B,SAAK,YAAY,IAAI,WAAW,CAAC,CAAC;AAClC,SAAK,cAAc,IAAI,WAAW,CAAC,CAAC;AAAA,EACtC;AAAA,EAEA,MAAM,WAAW,WAAkC;AACjD,SAAK,WAAW,OAAO,SAAS;AAChC,SAAK,kBAAkB,WAAW,kBAAkB,SAAS,CAAC;AAC9D,SAAK,YAAY,OAAO,SAAS;AACjC,QAAI;AACF,YAAM,KAAK,QAAQ,YAAY,SAAS;AAAA,IAC1C,SAAS,OAAO;AACd,WAAK,KAAK,QAAQ,qBAAqB,EAAE,WAAW,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,IAC5E;AACA,UAAM,KAAK,QAAQ,WAAW,SAAS;AAAA,EACzC;AAAA,EAEA,MAAM,MAAM,WAAmB,MAAiC;AAC9D,QAAI,CAAC,KAAK,WAAW,IAAI,SAAS,EAAG,OAAM,kBAAkB,SAAS;AACtE,UAAM,MAAM,qBAAO,KAAK,IAAI,EAAE,SAAS,KAAK;AAC5C,UAAM,KAAK,QAAQ,MAAM,WAAW,GAAG;AAAA,EACzC;AAAA,EAEA,MAAM,KAAK,WAAwC;AACjD,QAAI,CAAC,KAAK,WAAW,IAAI,SAAS,EAAG,OAAM,kBAAkB,SAAS;AACtE,UAAM,QAAQ,KAAK,YAAY,IAAI,SAAS;AAC5C,QAAI,SAAS,MAAM,SAAS,GAAG;AAE7B,aAAO,MAAM,MAAM;AAAA,IACrB;AACA,WAAO,IAAI,QAAoB,CAAC,SAAS,WAAW;AAClD,YAAM,UAAU,KAAK,cAAc,IAAI,SAAS;AAChD,UAAI,CAAC,SAAS;AACZ,eAAO,kBAAkB,SAAS,CAAC;AACnC;AAAA,MACF;AACA,cAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,WAAmB,SAAiC;AAC/D,UAAM,WAAW,KAAK,oBAAoB,IAAI,SAAS,KAAK,oBAAI,IAAgB;AAChF,aAAS,IAAI,OAAO;AACpB,SAAK,oBAAoB,IAAI,WAAW,QAAQ;AAChD,WAAO,MAAM;AACX,eAAS,OAAO,OAAO;AACvB,UAAI,SAAS,SAAS,GAAG;AACvB,aAAK,oBAAoB,OAAO,SAAS;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,+BAA+B;AACpC,SAAK,6BAA6B;AAClC,SAAK,+BAA+B;AACpC,SAAK,6BAA6B;AAClC,eAAW,YAAY,KAAK,oBAAoB,OAAO,EAAG,UAAS,MAAM;AACzE,SAAK,oBAAoB,MAAM;AAC/B,eAAW,MAAM,KAAK,WAAY,MAAK,kBAAkB,IAAI,kBAAkB,EAAE,CAAC;AAClF,SAAK,WAAW,MAAM;AACtB,SAAK,YAAY,MAAM;AACvB,SAAK,cAAc,MAAM;AAAA,EAC3B;AAAA,EAEQ,uBAA6B;AACnC,SAAK,+BAA+B,KAAK,QAAQ,eAAe,CAAC,IAAI,QAAQ;AAC3E,YAAM,OAAO,IAAI,WAAW,qBAAO,KAAK,KAAK,KAAK,CAAC;AACnD,YAAM,UAAU,KAAK,cAAc,IAAI,EAAE;AACzC,UAAI,WAAW,QAAQ,SAAS,GAAG;AAEjC,gBAAQ,MAAM,EAAG,QAAQ,IAAI;AAC7B;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,YAAY,IAAI,EAAE;AACrC,UAAI,MAAO,OAAM,KAAK,IAAI;AAAA,IAC5B,CAAC;AACD,SAAK,6BAA6B,KAAK,QAAQ,qBAAqB,QAAM;AACxE,WAAK,WAAW,OAAO,EAAE;AACzB,WAAK,kBAAkB,IAAI,gBAAgB,mCAAmC,EAAE,EAAE,CAAC;AACnF,WAAK,YAAY,OAAO,EAAE;AAC1B,WAAK,oBAAoB,IAAI,EAAE,GAAG,QAAQ,aAAW;AACnD,YAAI;AACF,kBAAQ;AAAA,QACV,SAAS,OAAO;AACd,eAAK,KAAK,SAAS,4BAA4B,EAAE,IAAI,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,QAC7E;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEQ,kBAAkB,WAAmB,OAAoB;AAC/D,UAAM,UAAU,KAAK,cAAc,IAAI,SAAS;AAChD,QAAI,CAAC,QAAS;AACd,eAAW,QAAQ,QAAS,MAAK,OAAO,KAAK;AAC7C,SAAK,cAAc,IAAI,WAAW,CAAC,CAAC;AAAA,EACtC;AAAA,EAEQ,KAAK,OAA4B,OAAe,MAAsC;AAC5F,UAAM,YAAQ,uDAA0B,EAAE,OAAO,OAAO,uBAAuB,OAAO,KAAK,CAAC;AAC5F,QAAI,CAAC,MAAO;AAEZ,SAAK,UAAU,KAAK;AAAA,EACtB;AACF;AAEO,SAAS,iCACd,SAC4B;AAC5B,SAAO,IAAI,2BAA2B,OAAO;AAC/C;;;ADrMA,IAAM,qBAAqB,CAAC,UAC1B,OAAQ,OAA8B,SAAS;AAS1C,IAAM,6BAAN,cAAyC,iDAAoB;AAAA,EAOlE,YAAY,SAA6C;AACvD,UAAM;AAAA,MACJ,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,KAAK,SAAS;AAAA,MACd,sBAAsB,SAAS;AAAA,IACjC,CAAC;AACD,SAAK,aAAa,SAAS;AAC3B,SAAK,oBAAoB,SAAS;AAClC,SAAK,UAAU,SAAS,kBAAkB;AAAA,EAC5C;AAAA,EAEA,MAAgB,mBAA+C;AAC7D,UAAM,YAAY,KAAK,iBAAiB;AACxC,UAAM,UAAU,MAAM,UAAU,KAAK;AACrC,UAAM,WAAW,QAAQ,OAAO,+CAAqB;AACrD,QAAI,SAAS,WAAW,QAAQ,QAAQ;AACtC,WAAK,KAAK,QAAQ,oCAAoC;AAAA,QACpD,WAAW;AAAA,QACX,iBAAiB,QAAQ;AAAA,QACzB,eAAe,SAAS;AAAA,QACxB,SAAS,QAAQ,OAAO,YAAU,KAAC,iDAAsB,MAAM,CAAC,EAAE,IAAI,oBAAoB;AAAA,QAC1F,MAAM,SAAS,IAAI,oBAAoB;AAAA,MACzC,CAAC;AAAA,IACH;AACA,WAAO,SAAS,IAAI,QAAM;AAAA,MACxB,WAAW,EAAE;AAAA,MACb,UAAU;AAAA,MACV,MAAM,EAAE,QAAQ,EAAE,aAAa;AAAA,MAC/B,OAAO;AAAA,MACP,gBAAgB;AAAA;AAAA,MAEhB,MAAM,EAAE,QAAQ;AAAA,MAChB,eAAe,EAAE,iBAAiB;AAAA,MAClC,cAAc,EAAE,0BAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAKhD,KAAK;AAAA,QACH,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF,EAAE;AAAA,EACJ;AAAA,EAEA,MAAgB,oBACd,QACuC;AACvC,UAAM,YAAY,KAAK,iBAAiB;AACxC,QAAI;AACF,YAAM,UAAU,QAAQ,OAAO,SAAS;AAAA,IAC1C,SAAS,OAAO;AAGd,UAAI,mBAAmB,KAAK,EAAG,OAAM;AACrC,YAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAMpE,UAAI,oBAAoB,KAAK,MAAM,GAAG;AACpC,kBAAM,yCAAe;AAAA,UACnB,MAAM,2CAAkB;AAAA,UACxB,SAAS,gCAAgC,OAAO,SAAS;AAAA,UACzD,QAAQ,EAAE,WAAW,OAAO,WAAW,eAAe,EAAE,SAAS,OAAO,EAAE;AAAA,QAC5E,CAAC;AAAA,MACH;AAIA,UAAI,qBAAqB,KAAK,MAAM,GAAG;AACrC,kBAAM,yCAAe;AAAA,UACnB,MAAM,2CAAkB;AAAA,UACxB,SAAS,iCAAiC,OAAO,SAAS;AAAA,UAC1D,QAAQ,EAAE,WAAW,OAAO,WAAW,eAAe,EAAE,SAAS,OAAO,EAAE;AAAA,QAC5E,CAAC;AAAA,MACH;AACA,gBAAM,yCAAe;AAAA,QACnB,MAAM,2CAAkB;AAAA,QACxB,SAAS,8BAA8B,OAAO,SAAS,KAAK,MAAM;AAAA,QAClE,QAAQ,EAAE,WAAW,OAAO,WAAW,eAAe,EAAE,SAAS,OAAO,EAAE;AAAA,MAC5E,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,OAAO,OAAO,UAAkB;AAC9B,cAAM,UAAU,MAAM,OAAO,WAAW,WAAW,KAAK,KAAK,CAAC;AAAA,MAChE;AAAA,MACA,MAAM,YAAY;AAChB,cAAM,OAAO,MAAM,UAAU,KAAK,OAAO,SAAS;AAClD,eAAO,sBAAO,KAAK,IAAI;AAAA,MACzB;AAAA,MACA,OAAO,MAAM,UAAU,WAAW,OAAO,SAAS;AAAA,MAClD,cAAc,CAAC,YAAwB,UAAU,aAAa,OAAO,WAAW,OAAO;AAAA,IACzF;AAAA,EACF;AAAA,EAEU,sBAAsB,UAA+C;AAC7E,UAAM,YAAY,SAAS,KAAK;AAChC,QAAI,CAAC,UAAW,QAAO;AACvB,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,EAAE,0BAA0B,MAAM;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAe,OAAO,WAAkC;AACtD,UAAM,MAAM,OAAO,SAAS;AAG5B,QAAI;AACF,YAAM,KAAK,YAAY,cAAc;AAAA,IACvC,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,UAAM,MAAM;AACZ,SAAK,YAAY,MAAM;AACvB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEQ,mBAA+C;AACrD,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,IAAI,2BAA2B,KAAK,iBAAiB;AAAA,IACzE;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,KAAK,OAA4B,OAAe,MAAsC;AAC5F,UAAM,YAAQ,wDAA0B,EAAE,OAAO,OAAO,uBAAuB,OAAO,KAAK,CAAC;AAC5F,QAAI,CAAC,MAAO;AAEZ,QAAI;AACF,WAAK,UAAU,KAAK;AAAA,IACtB,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEO,SAAS,iCACd,SAC4B;AAC5B,SAAO,IAAI,2BAA2B,OAAO;AAC/C;AAEA,SAAS,qBAAqB,QAA6B,KAAmC;AAC5F,QAAM,QAAS,OAA8C,GAAG;AAChE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,SAAO,MAAM,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ;AACxE;AAEA,SAAS,qBAAqB,QAAsD;AAClF,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,MAAM,OAAO;AAAA,IACb,WAAW,OAAO;AAAA,IAClB,MAAM,OAAO;AAAA,IACb,eAAe,OAAO;AAAA,IACtB,MAAM,OAAO,KAAK,MAAM,EAAE,KAAK;AAAA,IAC/B,0BAAsB,iDAAsB,MAAM;AAAA,IAClD,cAAc,qBAAqB,QAAQ,cAAc;AAAA,IACzD,cAAc,qBAAqB,QAAQ,cAAc;AAAA,IACzD,wBAAwB,qBAAqB,QAAQ,wBAAwB;AAAA,IAC7E,0BAA0B,OAAO;AAAA,IACjC,cAAc,OAAO;AAAA,IACrB,qBAAqB,OAAO;AAAA,IAC5B,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,aAAa,OAAO;AAAA,IACpB,OAAO,OAAO;AAAA,EAChB;AACF;;;AEtNO,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,cAAc;AAChB;AAKO,IAAM,8BAA8B;AASpC,IAAM,iCAAiC;AAGvC,IAAM,kCAAkC;","names":["import_buffer","import_hwk_adapter_core","import_hwk_trezor_connector"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/TrezorElectronBleConnector.ts","../src/TrezorElectronBleTransport.ts","../src/bleProfile.ts"],"sourcesContent":["export {\n TrezorElectronBleConnector,\n createTrezorElectronBleConnector,\n} from './TrezorElectronBleConnector';\nexport type { TrezorElectronBleConnectorOptions } from './TrezorElectronBleConnector';\n\nexport {\n TrezorElectronBleTransport,\n createTrezorElectronBleTransport,\n} from './TrezorElectronBleTransport';\nexport type { TrezorElectronBleTransportOptions } from './TrezorElectronBleTransport';\n\nexport {\n TREZOR_BLE_VENDOR,\n TREZOR_BLE_MATCH,\n TREZOR_BLE_CONNECT_PROFILE,\n TREZOR_BLE_WRITE_CHUNK_DELAY_MS,\n} from './bleProfile';\n","import { Buffer } from 'buffer';\nimport {\n TREZOR_BLE_PACKET_SIZE,\n TREZOR_SAFE_7_MODEL,\n isTrezorBleDescriptor,\n} from '@onekeyfe/hwk-trezor-adapter';\nimport { HardwareErrorCode, createHwkError } from '@onekeyfe/hwk-adapter-core';\nimport {\n TrezorConnectorBase,\n type TrezorConnectorBaseOptions,\n type TrezorConnectorByteTransport,\n type TrezorDebugLogLevel,\n type TrezorDebugLogger,\n filterTrezorDebugLogEntry,\n} from '@onekeyfe/hwk-trezor-connector';\n\nimport {\n TrezorElectronBleTransport,\n type TrezorElectronBleTransportOptions,\n} from './TrezorElectronBleTransport';\n\nimport type { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';\nimport type { ThirdPartyBleDeviceInfo } from '@onekeyfe/hwk-desktop-noble-ble';\n\nconst isStandardHwkError = (error: unknown): error is { code: number } =>\n typeof (error as { code?: unknown })?.code === 'number';\n\nexport interface TrezorElectronBleConnectorOptions {\n transport?: TrezorElectronBleTransport;\n transportOptions?: TrezorElectronBleTransportOptions;\n thp?: TrezorConnectorBaseOptions['thp'];\n deviceSessionFactory?: TrezorConnectorBaseOptions['deviceSessionFactory'];\n}\n\nexport class TrezorElectronBleConnector extends TrezorConnectorBase {\n private _transport: TrezorElectronBleTransport | undefined;\n\n private readonly _transportOptions?: TrezorElectronBleTransportOptions;\n\n private readonly _logger?: TrezorDebugLogger;\n\n constructor(options?: TrezorElectronBleConnectorOptions) {\n super({\n connectionType: 'ble',\n chunkSize: TREZOR_BLE_PACKET_SIZE,\n thp: options?.thp,\n deviceSessionFactory: options?.deviceSessionFactory,\n });\n this._transport = options?.transport;\n this._transportOptions = options?.transportOptions;\n this._logger = options?.transportOptions?.logger;\n }\n\n protected async enumerateDevices(): Promise<ConnectorDevice[]> {\n const transport = this._ensureTransport();\n const devices = await transport.scan();\n const filtered = devices.filter(isTrezorBleDescriptor);\n if (filtered.length !== devices.length) {\n this._log('info', 'ble.connector.enumerate.filtered', {\n transport: 'electron-ble',\n descriptorCount: devices.length,\n filteredCount: filtered.length,\n dropped: devices.filter(device => !isTrezorBleDescriptor(device)).map(toBleFilterLogSample),\n kept: filtered.map(toBleFilterLogSample),\n });\n }\n return filtered.map(d => ({\n connectId: d.id,\n deviceId: '',\n name: d.name ?? d.localName ?? 'Trezor Safe 7',\n model: TREZOR_SAFE_7_MODEL,\n connectionType: 'ble' as const,\n // Promote the typed BLE fields the device surface already has slots for.\n rssi: d.rssi ?? null,\n isConnectable: d.isConnectable ?? null,\n capabilities: { persistentDeviceIdentity: false },\n // Stash the FULL scan-time advertisement so the app/debug layer sees\n // everything the OS BLE stack exposed (mirrors the WebUSB connector's\n // `raw.descriptor`). This is where a cross-transport identity, if any,\n // would surface (manufacturerData / serviceData / localName).\n raw: {\n transport: 'electron-ble',\n descriptor: d,\n },\n }));\n }\n\n protected async createByteTransport(\n device: ConnectorDevice\n ): Promise<TrezorConnectorByteTransport> {\n const transport = this._ensureTransport();\n try {\n await transport.connect(device.connectId);\n } catch (error) {\n // Rethrowing the caught error (typed `unknown`) as-is is intentional.\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n if (isStandardHwkError(error)) throw error;\n const reason = error instanceof Error ? error.message : String(error);\n // The device wasn't found at all → DeviceNotFound. Otherwise the connect\n // itself failed: noble drops the real CoreBluetooth reason (hardcodes\n // \"connection failed\" / a timeout), so we CANNOT tell a stale bond from an\n // out-of-range / unresponsive device. Surface one honest, generic\n // BleConnectFailed instead of guessing a specific cause.\n if (/device not found/i.test(reason)) {\n throw createHwkError({\n code: HardwareErrorCode.DeviceNotFound,\n message: `Trezor BLE device not found: ${device.connectId}`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n // cancelPairing abandoned the connect. Reporting that as a connect failure\n // would tell the user the device is unreachable when they are the one who\n // stopped it.\n if (/connect cancelled/i.test(reason)) {\n throw createHwkError({\n code: HardwareErrorCode.BlePairingCancelled,\n message: `Trezor BLE pairing cancelled: ${device.connectId}`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n throw createHwkError({\n code: HardwareErrorCode.BleConnectFailed,\n message: `Trezor BLE connect failed: ${device.connectId} (${reason})`,\n params: { connectId: device.connectId, originalError: { message: reason } },\n });\n }\n\n return {\n write: async (chunk: Buffer) => {\n await transport.write(device.connectId, Uint8Array.from(chunk));\n },\n read: async () => {\n const data = await transport.read(device.connectId);\n return Buffer.from(data);\n },\n close: () => transport.disconnect(device.connectId),\n onDisconnect: (handler: () => void) => transport.onDisconnect(device.connectId, handler),\n };\n }\n\n protected resolveUnlistedDevice(deviceId: string): ConnectorDevice | undefined {\n const connectId = deviceId.trim();\n if (!connectId) return undefined;\n return {\n connectId,\n deviceId: '',\n name: 'Trezor Safe 7',\n model: TREZOR_SAFE_7_MODEL,\n capabilities: { persistentDeviceIdentity: false },\n };\n }\n\n override async cancel(sessionId: string): Promise<void> {\n await super.cancel(sessionId);\n // Base cancel only settles UI waiters; a connect stuck in the main process\n // must be abandoned there.\n try {\n await this._transport?.cancelPairing(sessionId);\n } catch {\n // Cancel must never throw.\n }\n }\n\n reset(): void {\n super.reset();\n this._transport?.reset();\n this._transport = undefined;\n }\n\n private _ensureTransport(): TrezorElectronBleTransport {\n if (!this._transport) {\n this._transport = new TrezorElectronBleTransport(this._transportOptions);\n }\n return this._transport;\n }\n\n private _log(level: TrezorDebugLogLevel, event: string, data?: Record<string, unknown>): void {\n const entry = filterTrezorDebugLogEntry({ level, scope: 'trezor-electron-ble', event, data });\n if (!entry) return;\n\n try {\n this._logger?.(entry);\n } catch {\n // Debug logging must not affect BLE connector behavior.\n }\n }\n}\n\nexport function createTrezorElectronBleConnector(\n options?: TrezorElectronBleConnectorOptions\n): TrezorElectronBleConnector {\n return new TrezorElectronBleConnector(options);\n}\n\nfunction readStringArrayField(source: ThirdPartyBleDeviceInfo, key: string): string[] | undefined {\n const value = (source as unknown as Record<string, unknown>)[key];\n if (!Array.isArray(value)) return undefined;\n return value.filter((item): item is string => typeof item === 'string');\n}\n\nfunction toBleFilterLogSample(device: ThirdPartyBleDeviceInfo): Record<string, unknown> {\n return {\n id: device.id,\n name: device.name,\n localName: device.localName,\n rssi: device.rssi,\n isConnectable: device.isConnectable,\n keys: Object.keys(device).sort(),\n matchesTrezorService: isTrezorBleDescriptor(device),\n serviceUUIDs: readStringArrayField(device, 'serviceUUIDs'),\n serviceUuids: readStringArrayField(device, 'serviceUuids'),\n advertisedServiceUuids: readStringArrayField(device, 'advertisedServiceUuids'),\n serviceSolicitationUuids: device.serviceSolicitationUuids,\n txPowerLevel: device.txPowerLevel,\n manufacturerDataHex: device.manufacturerDataHex,\n serviceData: device.serviceData,\n address: device.address,\n addressType: device.addressType,\n state: device.state,\n };\n}\n","import { Buffer } from 'buffer';\nimport { HardwareErrorCode, createHwkError } from '@onekeyfe/hwk-adapter-core';\nimport {\n type TrezorDebugLogLevel,\n type TrezorDebugLogger,\n filterTrezorDebugLogEntry,\n} from '@onekeyfe/hwk-trezor-connector';\n\nimport { TREZOR_BLE_CONNECT_PROFILE, TREZOR_BLE_MATCH, TREZOR_BLE_VENDOR } from './bleProfile';\n\nimport type { ThirdPartyBleApi, ThirdPartyBleDeviceInfo } from '@onekeyfe/hwk-desktop-noble-ble';\n\nexport interface TrezorElectronBleTransportOptions {\n /** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */\n bridge?: ThirdPartyBleApi;\n logger?: TrezorDebugLogger;\n}\n\nconst disconnectError = (message: string): Error =>\n Object.assign(new Error(message), { code: HardwareErrorCode.DeviceDisconnected });\n\nconst notConnectedError = (id: string): Error =>\n disconnectError(`Trezor Electron BLE device is not connected: ${id}`);\n\nconst resolveBridge = (options?: TrezorElectronBleTransportOptions): ThirdPartyBleApi => {\n if (options?.bridge) return options.bridge;\n const win =\n typeof window !== 'undefined'\n ? (window as unknown as { desktopApi?: { trezorBle?: ThirdPartyBleApi } })\n : undefined;\n const bridge = win?.desktopApi?.trezorBle;\n if (!bridge) {\n throw createHwkError({\n code: HardwareErrorCode.BridgeNotFound,\n message:\n 'TrezorElectronBleTransport: no bridge found — pass `bridge` or expose `window.desktopApi.trezorBle` from your Electron preload script',\n });\n }\n return bridge;\n};\n\ninterface PendingRead {\n resolve(data: Uint8Array): void;\n reject(error: Error): void;\n}\n\n/**\n * Renderer-side wrapper around the main process's BLE handler. Buffers\n * notifications into a per-device read queue so callers can `read()`\n * sequentially without missing chunks that arrive between reads.\n */\nexport class TrezorElectronBleTransport {\n private readonly _bridge: ThirdPartyBleApi;\n\n private readonly _connected = new Set<string>();\n\n private readonly _connecting = new Map<string, { cancelled: boolean }>();\n\n private readonly _readQueues = new Map<string, Uint8Array[]>();\n\n private readonly _pendingReads = new Map<string, PendingRead[]>();\n\n private readonly _disconnectHandlers = new Map<string, Set<() => void>>();\n\n private _disposeNotificationListener?: () => void;\n\n private _disposeDisconnectListener?: () => void;\n\n private readonly _logger?: TrezorElectronBleTransportOptions['logger'];\n\n constructor(options: TrezorElectronBleTransportOptions = {}) {\n this._bridge = resolveBridge(options);\n this._logger = options.logger;\n this._wireGlobalListeners();\n }\n\n async scan(durationMs?: number): Promise<ThirdPartyBleDeviceInfo[]> {\n // `match` is applied in JS after an unfiltered radio scan, not as a native\n // scan filter: a native service-UUID filter drops a Safe 7's ADV packets on\n // Windows, since its UUID lives in the scan response, not the ADV packet.\n try {\n return await this._bridge.scan({\n vendor: TREZOR_BLE_VENDOR,\n match: TREZOR_BLE_MATCH,\n durationMs,\n });\n } catch (error) {\n this._log('warn', 'ble.renderer.scan.error', {\n error: String(error),\n });\n throw error;\n }\n }\n\n async stopScan(): Promise<void> {\n await this._bridge.stopScan(TREZOR_BLE_VENDOR);\n }\n\n /** Abandon the in-flight connect/pairing in the main process. */\n async cancelPairing(connectId?: string): Promise<void> {\n const ids = new Set(\n [...this._connecting.keys(), ...this._connected].filter(\n id => connectId === undefined || id === connectId\n )\n );\n for (const id of ids) {\n const claim = this._connecting.get(id);\n if (claim) claim.cancelled = true;\n }\n await Promise.all(\n Array.from(ids, async id => {\n await this._bridge.cancelPairing({ vendor: TREZOR_BLE_VENDOR, id });\n if (this._connected.has(id)) this._handleDeviceDisconnected(id);\n })\n );\n if (connectId === undefined) await this.stopScan();\n }\n\n async connect(connectId: string): Promise<void> {\n if (this._connected.has(connectId)) return;\n // The shared handler holds no vendor defaults: every GATT uuid and the\n // padded-write framing travel with the call.\n const claim = { cancelled: false };\n this._connecting.set(connectId, claim);\n const assertActive = () => {\n if (claim.cancelled) {\n throw createHwkError({\n code: HardwareErrorCode.BlePairingCancelled,\n message: 'Trezor BLE pairing cancelled',\n });\n }\n };\n try {\n await this._bridge.connect(connectId, TREZOR_BLE_CONNECT_PROFILE);\n try {\n assertActive();\n await this._bridge.subscribe(connectId);\n assertActive();\n } catch (error) {\n // Main already owns the link; reject late completion without leaving it open.\n await this._bridge.disconnect(connectId).catch(() => undefined);\n throw error;\n }\n this._connected.add(connectId);\n this._readQueues.set(connectId, []);\n this._pendingReads.set(connectId, []);\n } finally {\n if (this._connecting.get(connectId) === claim) this._connecting.delete(connectId);\n }\n }\n\n async disconnect(connectId: string): Promise<void> {\n this._connected.delete(connectId);\n this._failPendingReads(connectId, notConnectedError(connectId));\n this._readQueues.delete(connectId);\n try {\n await this._bridge.unsubscribe(connectId);\n } catch (error) {\n this._log('warn', 'unsubscribe.error', { connectId, error: String(error) });\n }\n await this._bridge.disconnect(connectId);\n }\n\n async write(connectId: string, data: Uint8Array): Promise<void> {\n if (!this._connected.has(connectId)) throw notConnectedError(connectId);\n const hex = Buffer.from(data).toString('hex');\n await this._bridge.write(connectId, hex);\n }\n\n async read(connectId: string): Promise<Uint8Array> {\n if (!this._connected.has(connectId)) throw notConnectedError(connectId);\n const queue = this._readQueues.get(connectId);\n if (queue && queue.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return queue.shift()!;\n }\n return new Promise<Uint8Array>((resolve, reject) => {\n const pending = this._pendingReads.get(connectId);\n if (!pending) {\n reject(notConnectedError(connectId));\n return;\n }\n pending.push({ resolve, reject });\n });\n }\n\n onDisconnect(connectId: string, handler: () => void): () => void {\n const handlers = this._disconnectHandlers.get(connectId) ?? new Set<() => void>();\n handlers.add(handler);\n this._disconnectHandlers.set(connectId, handlers);\n return () => {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._disconnectHandlers.delete(connectId);\n }\n };\n }\n\n /** Tear down global listeners — called by the connector's `reset()`. */\n reset(): void {\n this._disposeNotificationListener?.();\n this._disposeDisconnectListener?.();\n this._disposeNotificationListener = undefined;\n this._disposeDisconnectListener = undefined;\n for (const handlers of this._disconnectHandlers.values()) handlers.clear();\n this._disconnectHandlers.clear();\n for (const id of this._connected) this._failPendingReads(id, notConnectedError(id));\n this._connected.clear();\n this._readQueues.clear();\n this._pendingReads.clear();\n }\n\n private _wireGlobalListeners(): void {\n this._disposeNotificationListener = this._bridge.onNotification((id, hex) => {\n const data = new Uint8Array(Buffer.from(hex, 'hex'));\n const pending = this._pendingReads.get(id);\n if (pending && pending.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n pending.shift()!.resolve(data);\n return;\n }\n const queue = this._readQueues.get(id);\n if (queue) queue.push(data);\n });\n this._disposeDisconnectListener = this._bridge.onDeviceDisconnected(id => {\n this._handleDeviceDisconnected(id);\n });\n }\n\n private _handleDeviceDisconnected(id: string): void {\n this._connected.delete(id);\n this._failPendingReads(id, disconnectError(`Trezor BLE device disconnected: ${id}`));\n this._readQueues.delete(id);\n this._disconnectHandlers.get(id)?.forEach(handler => {\n try {\n handler();\n } catch (error) {\n this._log('error', 'disconnect.handler.threw', { id, error: String(error) });\n }\n });\n }\n\n private _failPendingReads(connectId: string, error: Error): void {\n const pending = this._pendingReads.get(connectId);\n if (!pending) return;\n for (const item of pending) item.reject(error);\n this._pendingReads.set(connectId, []);\n }\n\n private _log(level: TrezorDebugLogLevel, event: string, data?: Record<string, unknown>): void {\n const entry = filterTrezorDebugLogEntry({ level, scope: 'trezor-electron-ble', event, data });\n if (!entry) return;\n\n this._logger?.(entry);\n }\n}\n\nexport function createTrezorElectronBleTransport(\n options?: TrezorElectronBleTransportOptions\n): TrezorElectronBleTransport {\n return new TrezorElectronBleTransport(options);\n}\n","import { TREZOR_BLE_PACKET_SIZE, TREZOR_BLE_UUIDS } from '@onekeyfe/hwk-trezor-adapter';\n\nimport type { ElectronBleConnectOptions, ElectronBleMatch } from '@onekeyfe/hwk-adapter-core';\n\n/** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */\nexport const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;\n\nexport const TREZOR_BLE_VENDOR = 'trezor';\n\n/**\n * Trezor matcher sent to the vendor-agnostic main process. A name must match every\n * pattern, like `isTrezorSafe7BleName`: \"Trezor\" plus \"Safe 7\" or \"T3W1\".\n */\nexport const TREZOR_BLE_MATCH: ElectronBleMatch = {\n serviceUuids: [TREZOR_BLE_UUIDS.service],\n namePatterns: ['\\\\bTrezor\\\\b', '\\\\bSafe\\\\s*7\\\\b|\\\\bT3W1\\\\b'],\n};\n\n/**\n * Trezor firmware expects fixed-size packets: a short final packet is silently\n * dropped, so every write is padded to the full MTU.\n */\nexport const TREZOR_BLE_CONNECT_PROFILE: ElectronBleConnectOptions = {\n vendor: TREZOR_BLE_VENDOR,\n serviceUuid: TREZOR_BLE_UUIDS.service,\n writeUuid: TREZOR_BLE_UUIDS.write,\n notifyUuid: TREZOR_BLE_UUIDS.notify,\n write: {\n mode: 'padded',\n chunkSize: TREZOR_BLE_PACKET_SIZE,\n chunkDelayMs: TREZOR_BLE_WRITE_CHUNK_DELAY_MS,\n },\n};\n"],"mappings":"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","names":["import_buffer","import_hwk_trezor_adapter","import_hwk_adapter_core","import_hwk_trezor_connector"]}