@onekeyfe/hwk-trezor-connector-electron-ble 1.1.27-alpha.100
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/chunk-KNBLSVDP.mjs +37 -0
- package/dist/chunk-KNBLSVDP.mjs.map +1 -0
- package/dist/constants-D7zVXklG.d.mts +104 -0
- package/dist/constants-D7zVXklG.d.ts +104 -0
- package/dist/index.d.mts +64 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +284 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +237 -0
- package/dist/index.mjs.map +1 -0
- package/dist/main.d.mts +177 -0
- package/dist/main.d.ts +177 -0
- package/dist/main.js +406 -0
- package/dist/main.js.map +1 -0
- package/dist/main.mjs +363 -0
- package/dist/main.mjs.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/constants.ts
|
|
9
|
+
var TREZOR_BLE_CHANNELS = {
|
|
10
|
+
scan: "$onekey-trezor-ble-scan",
|
|
11
|
+
stopScan: "$onekey-trezor-ble-stop-scan",
|
|
12
|
+
connect: "$onekey-trezor-ble-connect",
|
|
13
|
+
disconnect: "$onekey-trezor-ble-disconnect",
|
|
14
|
+
write: "$onekey-trezor-ble-write",
|
|
15
|
+
subscribe: "$onekey-trezor-ble-subscribe",
|
|
16
|
+
unsubscribe: "$onekey-trezor-ble-unsubscribe",
|
|
17
|
+
availability: "$onekey-trezor-ble-availability",
|
|
18
|
+
getDevice: "$onekey-trezor-ble-get-device",
|
|
19
|
+
readRssi: "$onekey-trezor-ble-read-rssi",
|
|
20
|
+
cancelPairing: "$onekey-trezor-ble-cancel-pairing",
|
|
21
|
+
/** push event: main → renderer with assembled BLE notification payload */
|
|
22
|
+
notification: "$onekey-trezor-ble-notification",
|
|
23
|
+
/** push event: main → renderer when device disconnects unexpectedly */
|
|
24
|
+
disconnected: "$onekey-trezor-ble-disconnected"
|
|
25
|
+
};
|
|
26
|
+
var TREZOR_BLE_SCAN_DURATION_MS = 5e3;
|
|
27
|
+
var TREZOR_BLE_POWER_ON_TIMEOUT_MS = 1e4;
|
|
28
|
+
var TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
__require,
|
|
32
|
+
TREZOR_BLE_CHANNELS,
|
|
33
|
+
TREZOR_BLE_SCAN_DURATION_MS,
|
|
34
|
+
TREZOR_BLE_POWER_ON_TIMEOUT_MS,
|
|
35
|
+
TREZOR_BLE_WRITE_CHUNK_DELAY_MS
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=chunk-KNBLSVDP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\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/** Default scan window — same as OneKey's `enumerate`. */\nexport const TREZOR_BLE_SCAN_DURATION_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":";;;;;;;;AAMO,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;AAGpC,IAAM,iCAAiC;AAGvC,IAAM,kCAAkC;","names":[]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shape of the API the renderer process talks to. In a real Electron app
|
|
3
|
+
* this is normally exposed via `contextBridge.exposeInMainWorld('desktopApi',
|
|
4
|
+
* { trezorBle: ... })`, but the transport accepts the bridge directly so
|
|
5
|
+
* non-Electron hosts (and unit tests) can plug in their own implementation.
|
|
6
|
+
*/
|
|
7
|
+
interface TrezorBleDeviceInfo {
|
|
8
|
+
/** Stable id (noble peripheral.id) used as connectId. */
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
rssi?: number;
|
|
12
|
+
advertisedServiceUuids?: string[];
|
|
13
|
+
/** Same as `name`, kept explicit to mirror noble's `advertisement.localName`. */
|
|
14
|
+
localName?: string;
|
|
15
|
+
/** Whether the peripheral advertised itself as connectable. */
|
|
16
|
+
isConnectable?: boolean | null;
|
|
17
|
+
serviceSolicitationUuids?: string[];
|
|
18
|
+
txPowerLevel?: number;
|
|
19
|
+
/** Manufacturer-specific advertisement data, hex-encoded (may embed a serial). */
|
|
20
|
+
manufacturerDataHex?: string;
|
|
21
|
+
/** Per-service advertisement data, each hex-encoded. */
|
|
22
|
+
serviceData?: Array<{
|
|
23
|
+
uuid: string;
|
|
24
|
+
dataHex: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** BLE MAC/address when the OS exposes it separately from `id`. */
|
|
27
|
+
address?: string;
|
|
28
|
+
addressType?: string;
|
|
29
|
+
/** noble peripheral connection state at scan time. */
|
|
30
|
+
state?: string;
|
|
31
|
+
}
|
|
32
|
+
interface TrezorBleAvailability {
|
|
33
|
+
available: boolean;
|
|
34
|
+
/** noble state: `poweredOn` / `poweredOff` / `unauthorized` / `unsupported` / `resetting` / `unknown`. */
|
|
35
|
+
state: string;
|
|
36
|
+
initialized: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface TrezorBleScanOptions {
|
|
39
|
+
/** Service UUIDs advertised by target devices. Omit for default (Trezor). */
|
|
40
|
+
serviceUuids?: string[];
|
|
41
|
+
durationMs?: number;
|
|
42
|
+
}
|
|
43
|
+
interface TrezorBleApi {
|
|
44
|
+
scan(options?: TrezorBleScanOptions): Promise<TrezorBleDeviceInfo[]>;
|
|
45
|
+
stopScan(): Promise<void>;
|
|
46
|
+
connect(id: string): Promise<{
|
|
47
|
+
id: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
}>;
|
|
50
|
+
disconnect(id: string): Promise<void>;
|
|
51
|
+
/** Subscribe to the BLE notify characteristic for `id`. */
|
|
52
|
+
subscribe(id: string): Promise<void>;
|
|
53
|
+
unsubscribe(id: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Write a payload (already-framed if Trezor v1, or a single 244-byte chunk
|
|
56
|
+
* for THP). The main process is responsible for splitting it into BLE-MTU
|
|
57
|
+
* chunks before handing it to noble.
|
|
58
|
+
*/
|
|
59
|
+
write(id: string, hexData: string): Promise<void>;
|
|
60
|
+
checkAvailability(): Promise<TrezorBleAvailability>;
|
|
61
|
+
/** Look up a previously-scanned device by id without re-scanning. */
|
|
62
|
+
getDevice(id: string): Promise<TrezorBleDeviceInfo | null>;
|
|
63
|
+
/** Read current RSSI (dBm) of a *connected* peripheral. */
|
|
64
|
+
readRssi(id: string): Promise<number>;
|
|
65
|
+
/** Stop scan + disconnect every in-flight connection. */
|
|
66
|
+
cancelPairing(): Promise<void>;
|
|
67
|
+
/** Register a listener for incoming BLE notifications. Returns an unsubscribe fn. */
|
|
68
|
+
onNotification(handler: (id: string, hexData: string) => void): () => void;
|
|
69
|
+
/** Register a listener for unexpected disconnects. Returns an unsubscribe fn. */
|
|
70
|
+
onDeviceDisconnected(handler: (id: string) => void): () => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* IPC channel names exchanged between renderer and main process.
|
|
75
|
+
* Namespaced under `$onekey-trezor-ble-…` to avoid clashing with the
|
|
76
|
+
* existing OneKey BLE handler (`$onekey-noble-ble-…`) when both run in
|
|
77
|
+
* the same Electron app.
|
|
78
|
+
*/
|
|
79
|
+
declare const TREZOR_BLE_CHANNELS: {
|
|
80
|
+
readonly scan: "$onekey-trezor-ble-scan";
|
|
81
|
+
readonly stopScan: "$onekey-trezor-ble-stop-scan";
|
|
82
|
+
readonly connect: "$onekey-trezor-ble-connect";
|
|
83
|
+
readonly disconnect: "$onekey-trezor-ble-disconnect";
|
|
84
|
+
readonly write: "$onekey-trezor-ble-write";
|
|
85
|
+
readonly subscribe: "$onekey-trezor-ble-subscribe";
|
|
86
|
+
readonly unsubscribe: "$onekey-trezor-ble-unsubscribe";
|
|
87
|
+
readonly availability: "$onekey-trezor-ble-availability";
|
|
88
|
+
readonly getDevice: "$onekey-trezor-ble-get-device";
|
|
89
|
+
readonly readRssi: "$onekey-trezor-ble-read-rssi";
|
|
90
|
+
readonly cancelPairing: "$onekey-trezor-ble-cancel-pairing";
|
|
91
|
+
/** push event: main → renderer with assembled BLE notification payload */
|
|
92
|
+
readonly notification: "$onekey-trezor-ble-notification";
|
|
93
|
+
/** push event: main → renderer when device disconnects unexpectedly */
|
|
94
|
+
readonly disconnected: "$onekey-trezor-ble-disconnected";
|
|
95
|
+
};
|
|
96
|
+
type TrezorBleChannel = (typeof TREZOR_BLE_CHANNELS)[keyof typeof TREZOR_BLE_CHANNELS];
|
|
97
|
+
/** Default scan window — same as OneKey's `enumerate`. */
|
|
98
|
+
declare const TREZOR_BLE_SCAN_DURATION_MS = 5000;
|
|
99
|
+
/** Time we'll wait for noble to reach `poweredOn` before failing init. */
|
|
100
|
+
declare const TREZOR_BLE_POWER_ON_TIMEOUT_MS = 10000;
|
|
101
|
+
/** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */
|
|
102
|
+
declare const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
|
|
103
|
+
|
|
104
|
+
export { type TrezorBleApi as T, type TrezorBleDeviceInfo as a, TREZOR_BLE_CHANNELS as b, TREZOR_BLE_POWER_ON_TIMEOUT_MS as c, TREZOR_BLE_SCAN_DURATION_MS as d, TREZOR_BLE_WRITE_CHUNK_DELAY_MS as e, type TrezorBleAvailability as f, type TrezorBleChannel as g };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shape of the API the renderer process talks to. In a real Electron app
|
|
3
|
+
* this is normally exposed via `contextBridge.exposeInMainWorld('desktopApi',
|
|
4
|
+
* { trezorBle: ... })`, but the transport accepts the bridge directly so
|
|
5
|
+
* non-Electron hosts (and unit tests) can plug in their own implementation.
|
|
6
|
+
*/
|
|
7
|
+
interface TrezorBleDeviceInfo {
|
|
8
|
+
/** Stable id (noble peripheral.id) used as connectId. */
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
rssi?: number;
|
|
12
|
+
advertisedServiceUuids?: string[];
|
|
13
|
+
/** Same as `name`, kept explicit to mirror noble's `advertisement.localName`. */
|
|
14
|
+
localName?: string;
|
|
15
|
+
/** Whether the peripheral advertised itself as connectable. */
|
|
16
|
+
isConnectable?: boolean | null;
|
|
17
|
+
serviceSolicitationUuids?: string[];
|
|
18
|
+
txPowerLevel?: number;
|
|
19
|
+
/** Manufacturer-specific advertisement data, hex-encoded (may embed a serial). */
|
|
20
|
+
manufacturerDataHex?: string;
|
|
21
|
+
/** Per-service advertisement data, each hex-encoded. */
|
|
22
|
+
serviceData?: Array<{
|
|
23
|
+
uuid: string;
|
|
24
|
+
dataHex: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** BLE MAC/address when the OS exposes it separately from `id`. */
|
|
27
|
+
address?: string;
|
|
28
|
+
addressType?: string;
|
|
29
|
+
/** noble peripheral connection state at scan time. */
|
|
30
|
+
state?: string;
|
|
31
|
+
}
|
|
32
|
+
interface TrezorBleAvailability {
|
|
33
|
+
available: boolean;
|
|
34
|
+
/** noble state: `poweredOn` / `poweredOff` / `unauthorized` / `unsupported` / `resetting` / `unknown`. */
|
|
35
|
+
state: string;
|
|
36
|
+
initialized: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface TrezorBleScanOptions {
|
|
39
|
+
/** Service UUIDs advertised by target devices. Omit for default (Trezor). */
|
|
40
|
+
serviceUuids?: string[];
|
|
41
|
+
durationMs?: number;
|
|
42
|
+
}
|
|
43
|
+
interface TrezorBleApi {
|
|
44
|
+
scan(options?: TrezorBleScanOptions): Promise<TrezorBleDeviceInfo[]>;
|
|
45
|
+
stopScan(): Promise<void>;
|
|
46
|
+
connect(id: string): Promise<{
|
|
47
|
+
id: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
}>;
|
|
50
|
+
disconnect(id: string): Promise<void>;
|
|
51
|
+
/** Subscribe to the BLE notify characteristic for `id`. */
|
|
52
|
+
subscribe(id: string): Promise<void>;
|
|
53
|
+
unsubscribe(id: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Write a payload (already-framed if Trezor v1, or a single 244-byte chunk
|
|
56
|
+
* for THP). The main process is responsible for splitting it into BLE-MTU
|
|
57
|
+
* chunks before handing it to noble.
|
|
58
|
+
*/
|
|
59
|
+
write(id: string, hexData: string): Promise<void>;
|
|
60
|
+
checkAvailability(): Promise<TrezorBleAvailability>;
|
|
61
|
+
/** Look up a previously-scanned device by id without re-scanning. */
|
|
62
|
+
getDevice(id: string): Promise<TrezorBleDeviceInfo | null>;
|
|
63
|
+
/** Read current RSSI (dBm) of a *connected* peripheral. */
|
|
64
|
+
readRssi(id: string): Promise<number>;
|
|
65
|
+
/** Stop scan + disconnect every in-flight connection. */
|
|
66
|
+
cancelPairing(): Promise<void>;
|
|
67
|
+
/** Register a listener for incoming BLE notifications. Returns an unsubscribe fn. */
|
|
68
|
+
onNotification(handler: (id: string, hexData: string) => void): () => void;
|
|
69
|
+
/** Register a listener for unexpected disconnects. Returns an unsubscribe fn. */
|
|
70
|
+
onDeviceDisconnected(handler: (id: string) => void): () => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* IPC channel names exchanged between renderer and main process.
|
|
75
|
+
* Namespaced under `$onekey-trezor-ble-…` to avoid clashing with the
|
|
76
|
+
* existing OneKey BLE handler (`$onekey-noble-ble-…`) when both run in
|
|
77
|
+
* the same Electron app.
|
|
78
|
+
*/
|
|
79
|
+
declare const TREZOR_BLE_CHANNELS: {
|
|
80
|
+
readonly scan: "$onekey-trezor-ble-scan";
|
|
81
|
+
readonly stopScan: "$onekey-trezor-ble-stop-scan";
|
|
82
|
+
readonly connect: "$onekey-trezor-ble-connect";
|
|
83
|
+
readonly disconnect: "$onekey-trezor-ble-disconnect";
|
|
84
|
+
readonly write: "$onekey-trezor-ble-write";
|
|
85
|
+
readonly subscribe: "$onekey-trezor-ble-subscribe";
|
|
86
|
+
readonly unsubscribe: "$onekey-trezor-ble-unsubscribe";
|
|
87
|
+
readonly availability: "$onekey-trezor-ble-availability";
|
|
88
|
+
readonly getDevice: "$onekey-trezor-ble-get-device";
|
|
89
|
+
readonly readRssi: "$onekey-trezor-ble-read-rssi";
|
|
90
|
+
readonly cancelPairing: "$onekey-trezor-ble-cancel-pairing";
|
|
91
|
+
/** push event: main → renderer with assembled BLE notification payload */
|
|
92
|
+
readonly notification: "$onekey-trezor-ble-notification";
|
|
93
|
+
/** push event: main → renderer when device disconnects unexpectedly */
|
|
94
|
+
readonly disconnected: "$onekey-trezor-ble-disconnected";
|
|
95
|
+
};
|
|
96
|
+
type TrezorBleChannel = (typeof TREZOR_BLE_CHANNELS)[keyof typeof TREZOR_BLE_CHANNELS];
|
|
97
|
+
/** Default scan window — same as OneKey's `enumerate`. */
|
|
98
|
+
declare const TREZOR_BLE_SCAN_DURATION_MS = 5000;
|
|
99
|
+
/** Time we'll wait for noble to reach `poweredOn` before failing init. */
|
|
100
|
+
declare const TREZOR_BLE_POWER_ON_TIMEOUT_MS = 10000;
|
|
101
|
+
/** Inter-chunk delay during write, matches OneKey's `UNIFIED_WRITE_DELAY`. */
|
|
102
|
+
declare const TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
|
|
103
|
+
|
|
104
|
+
export { type TrezorBleApi as T, type TrezorBleDeviceInfo as a, TREZOR_BLE_CHANNELS as b, TREZOR_BLE_POWER_ON_TIMEOUT_MS as c, TREZOR_BLE_SCAN_DURATION_MS as d, TREZOR_BLE_WRITE_CHUNK_DELAY_MS as e, type TrezorBleAvailability as f, type TrezorBleChannel as g };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { TrezorConnectorBase, TrezorConnectorBaseOptions, TrezorConnectorByteTransport } from '@onekeyfe/hwk-trezor-connector';
|
|
2
|
+
import { T as TrezorBleApi, a as TrezorBleDeviceInfo } from './constants-D7zVXklG.mjs';
|
|
3
|
+
export { b as TREZOR_BLE_CHANNELS, c as TREZOR_BLE_POWER_ON_TIMEOUT_MS, d as TREZOR_BLE_SCAN_DURATION_MS, e as TREZOR_BLE_WRITE_CHUNK_DELAY_MS, f as TrezorBleAvailability, g as TrezorBleChannel } from './constants-D7zVXklG.mjs';
|
|
4
|
+
import { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
|
|
5
|
+
|
|
6
|
+
interface TrezorElectronBleTransportOptions {
|
|
7
|
+
/** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */
|
|
8
|
+
bridge?: TrezorBleApi;
|
|
9
|
+
logger?: (entry: {
|
|
10
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
11
|
+
scope: string;
|
|
12
|
+
event: string;
|
|
13
|
+
data?: Record<string, unknown>;
|
|
14
|
+
}) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Renderer-side wrapper around the main process's BLE handler. Buffers
|
|
18
|
+
* notifications into a per-device read queue so callers can `read()`
|
|
19
|
+
* sequentially without missing chunks that arrive between reads.
|
|
20
|
+
*/
|
|
21
|
+
declare class TrezorElectronBleTransport {
|
|
22
|
+
private readonly _bridge;
|
|
23
|
+
private readonly _connected;
|
|
24
|
+
private readonly _readQueues;
|
|
25
|
+
private readonly _pendingReads;
|
|
26
|
+
private readonly _disconnectHandlers;
|
|
27
|
+
private _disposeNotificationListener?;
|
|
28
|
+
private _disposeDisconnectListener?;
|
|
29
|
+
private readonly _logger?;
|
|
30
|
+
constructor(options?: TrezorElectronBleTransportOptions);
|
|
31
|
+
scan(durationMs?: number): Promise<TrezorBleDeviceInfo[]>;
|
|
32
|
+
stopScan(): Promise<void>;
|
|
33
|
+
connect(connectId: string): Promise<void>;
|
|
34
|
+
disconnect(connectId: string): Promise<void>;
|
|
35
|
+
write(connectId: string, data: Uint8Array): Promise<void>;
|
|
36
|
+
read(connectId: string): Promise<Uint8Array>;
|
|
37
|
+
onDisconnect(connectId: string, handler: () => void): () => void;
|
|
38
|
+
/** Tear down global listeners — called by the connector's `reset()`. */
|
|
39
|
+
reset(): void;
|
|
40
|
+
private _wireGlobalListeners;
|
|
41
|
+
private _failPendingReads;
|
|
42
|
+
private _log;
|
|
43
|
+
}
|
|
44
|
+
declare function createTrezorElectronBleTransport(options?: TrezorElectronBleTransportOptions): TrezorElectronBleTransport;
|
|
45
|
+
|
|
46
|
+
interface TrezorElectronBleConnectorOptions {
|
|
47
|
+
transport?: TrezorElectronBleTransport;
|
|
48
|
+
transportOptions?: TrezorElectronBleTransportOptions;
|
|
49
|
+
thp?: TrezorConnectorBaseOptions['thp'];
|
|
50
|
+
deviceSessionFactory?: TrezorConnectorBaseOptions['deviceSessionFactory'];
|
|
51
|
+
}
|
|
52
|
+
declare class TrezorElectronBleConnector extends TrezorConnectorBase {
|
|
53
|
+
private _transport;
|
|
54
|
+
private readonly _transportOptions?;
|
|
55
|
+
constructor(options?: TrezorElectronBleConnectorOptions);
|
|
56
|
+
protected enumerateDevices(): Promise<ConnectorDevice[]>;
|
|
57
|
+
protected createByteTransport(device: ConnectorDevice): Promise<TrezorConnectorByteTransport>;
|
|
58
|
+
protected resolveUnlistedDevice(deviceId: string): ConnectorDevice | undefined;
|
|
59
|
+
reset(): void;
|
|
60
|
+
private _ensureTransport;
|
|
61
|
+
}
|
|
62
|
+
declare function createTrezorElectronBleConnector(options?: TrezorElectronBleConnectorOptions): TrezorElectronBleConnector;
|
|
63
|
+
|
|
64
|
+
export { TrezorBleApi, TrezorBleDeviceInfo, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { TrezorConnectorBase, TrezorConnectorBaseOptions, TrezorConnectorByteTransport } from '@onekeyfe/hwk-trezor-connector';
|
|
2
|
+
import { T as TrezorBleApi, a as TrezorBleDeviceInfo } from './constants-D7zVXklG.js';
|
|
3
|
+
export { b as TREZOR_BLE_CHANNELS, c as TREZOR_BLE_POWER_ON_TIMEOUT_MS, d as TREZOR_BLE_SCAN_DURATION_MS, e as TREZOR_BLE_WRITE_CHUNK_DELAY_MS, f as TrezorBleAvailability, g as TrezorBleChannel } from './constants-D7zVXklG.js';
|
|
4
|
+
import { ConnectorDevice } from '@onekeyfe/hwk-adapter-core';
|
|
5
|
+
|
|
6
|
+
interface TrezorElectronBleTransportOptions {
|
|
7
|
+
/** The IPC bridge exposed by the main process (typically `window.desktopApi.trezorBle`). */
|
|
8
|
+
bridge?: TrezorBleApi;
|
|
9
|
+
logger?: (entry: {
|
|
10
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
11
|
+
scope: string;
|
|
12
|
+
event: string;
|
|
13
|
+
data?: Record<string, unknown>;
|
|
14
|
+
}) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Renderer-side wrapper around the main process's BLE handler. Buffers
|
|
18
|
+
* notifications into a per-device read queue so callers can `read()`
|
|
19
|
+
* sequentially without missing chunks that arrive between reads.
|
|
20
|
+
*/
|
|
21
|
+
declare class TrezorElectronBleTransport {
|
|
22
|
+
private readonly _bridge;
|
|
23
|
+
private readonly _connected;
|
|
24
|
+
private readonly _readQueues;
|
|
25
|
+
private readonly _pendingReads;
|
|
26
|
+
private readonly _disconnectHandlers;
|
|
27
|
+
private _disposeNotificationListener?;
|
|
28
|
+
private _disposeDisconnectListener?;
|
|
29
|
+
private readonly _logger?;
|
|
30
|
+
constructor(options?: TrezorElectronBleTransportOptions);
|
|
31
|
+
scan(durationMs?: number): Promise<TrezorBleDeviceInfo[]>;
|
|
32
|
+
stopScan(): Promise<void>;
|
|
33
|
+
connect(connectId: string): Promise<void>;
|
|
34
|
+
disconnect(connectId: string): Promise<void>;
|
|
35
|
+
write(connectId: string, data: Uint8Array): Promise<void>;
|
|
36
|
+
read(connectId: string): Promise<Uint8Array>;
|
|
37
|
+
onDisconnect(connectId: string, handler: () => void): () => void;
|
|
38
|
+
/** Tear down global listeners — called by the connector's `reset()`. */
|
|
39
|
+
reset(): void;
|
|
40
|
+
private _wireGlobalListeners;
|
|
41
|
+
private _failPendingReads;
|
|
42
|
+
private _log;
|
|
43
|
+
}
|
|
44
|
+
declare function createTrezorElectronBleTransport(options?: TrezorElectronBleTransportOptions): TrezorElectronBleTransport;
|
|
45
|
+
|
|
46
|
+
interface TrezorElectronBleConnectorOptions {
|
|
47
|
+
transport?: TrezorElectronBleTransport;
|
|
48
|
+
transportOptions?: TrezorElectronBleTransportOptions;
|
|
49
|
+
thp?: TrezorConnectorBaseOptions['thp'];
|
|
50
|
+
deviceSessionFactory?: TrezorConnectorBaseOptions['deviceSessionFactory'];
|
|
51
|
+
}
|
|
52
|
+
declare class TrezorElectronBleConnector extends TrezorConnectorBase {
|
|
53
|
+
private _transport;
|
|
54
|
+
private readonly _transportOptions?;
|
|
55
|
+
constructor(options?: TrezorElectronBleConnectorOptions);
|
|
56
|
+
protected enumerateDevices(): Promise<ConnectorDevice[]>;
|
|
57
|
+
protected createByteTransport(device: ConnectorDevice): Promise<TrezorConnectorByteTransport>;
|
|
58
|
+
protected resolveUnlistedDevice(deviceId: string): ConnectorDevice | undefined;
|
|
59
|
+
reset(): void;
|
|
60
|
+
private _ensureTransport;
|
|
61
|
+
}
|
|
62
|
+
declare function createTrezorElectronBleConnector(options?: TrezorElectronBleConnectorOptions): TrezorElectronBleConnector;
|
|
63
|
+
|
|
64
|
+
export { TrezorBleApi, TrezorBleDeviceInfo, TrezorElectronBleConnector, type TrezorElectronBleConnectorOptions, TrezorElectronBleTransport, type TrezorElectronBleTransportOptions, createTrezorElectronBleConnector, createTrezorElectronBleTransport };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
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,
|
|
26
|
+
TREZOR_BLE_WRITE_CHUNK_DELAY_MS: () => TREZOR_BLE_WRITE_CHUNK_DELAY_MS,
|
|
27
|
+
TrezorElectronBleConnector: () => TrezorElectronBleConnector,
|
|
28
|
+
TrezorElectronBleTransport: () => TrezorElectronBleTransport,
|
|
29
|
+
createTrezorElectronBleConnector: () => createTrezorElectronBleConnector,
|
|
30
|
+
createTrezorElectronBleTransport: () => createTrezorElectronBleTransport
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
|
|
34
|
+
// src/TrezorElectronBleConnector.ts
|
|
35
|
+
var import_buffer = require("buffer");
|
|
36
|
+
var import_hwk_trezor_adapter2 = require("@onekeyfe/hwk-trezor-adapter");
|
|
37
|
+
var import_hwk_trezor_connector = require("@onekeyfe/hwk-trezor-connector");
|
|
38
|
+
|
|
39
|
+
// src/TrezorElectronBleTransport.ts
|
|
40
|
+
var import_hwk_adapter_core = require("@onekeyfe/hwk-adapter-core");
|
|
41
|
+
var import_hwk_trezor_adapter = require("@onekeyfe/hwk-trezor-adapter");
|
|
42
|
+
var disconnectError = (message) => Object.assign(new Error(message), { code: import_hwk_adapter_core.HardwareErrorCode.DeviceDisconnected });
|
|
43
|
+
var notConnectedError = (id) => disconnectError(`Trezor Electron BLE device is not connected: ${id}`);
|
|
44
|
+
var resolveBridge = (options) => {
|
|
45
|
+
if (options?.bridge) return options.bridge;
|
|
46
|
+
const win = typeof window !== "undefined" ? window : void 0;
|
|
47
|
+
const bridge = win?.desktopApi?.trezorBle;
|
|
48
|
+
if (!bridge) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
"TrezorElectronBleTransport: no bridge found \u2014 pass `bridge` or expose `window.desktopApi.trezorBle` from your Electron preload script"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return bridge;
|
|
54
|
+
};
|
|
55
|
+
var TrezorElectronBleTransport = class {
|
|
56
|
+
constructor(options = {}) {
|
|
57
|
+
this._connected = /* @__PURE__ */ new Set();
|
|
58
|
+
this._readQueues = /* @__PURE__ */ new Map();
|
|
59
|
+
this._pendingReads = /* @__PURE__ */ new Map();
|
|
60
|
+
this._disconnectHandlers = /* @__PURE__ */ new Map();
|
|
61
|
+
this._bridge = resolveBridge(options);
|
|
62
|
+
this._logger = options.logger;
|
|
63
|
+
this._wireGlobalListeners();
|
|
64
|
+
}
|
|
65
|
+
async scan(durationMs) {
|
|
66
|
+
return this._bridge.scan({
|
|
67
|
+
serviceUuids: [import_hwk_trezor_adapter.TREZOR_BLE_UUIDS.service],
|
|
68
|
+
durationMs
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async stopScan() {
|
|
72
|
+
await this._bridge.stopScan();
|
|
73
|
+
}
|
|
74
|
+
async connect(connectId) {
|
|
75
|
+
if (this._connected.has(connectId)) return;
|
|
76
|
+
await this._bridge.connect(connectId);
|
|
77
|
+
await this._bridge.subscribe(connectId);
|
|
78
|
+
this._connected.add(connectId);
|
|
79
|
+
this._readQueues.set(connectId, []);
|
|
80
|
+
this._pendingReads.set(connectId, []);
|
|
81
|
+
}
|
|
82
|
+
async disconnect(connectId) {
|
|
83
|
+
this._connected.delete(connectId);
|
|
84
|
+
this._failPendingReads(connectId, notConnectedError(connectId));
|
|
85
|
+
this._readQueues.delete(connectId);
|
|
86
|
+
try {
|
|
87
|
+
await this._bridge.unsubscribe(connectId);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
this._log("warn", "unsubscribe.error", { connectId, error: String(error) });
|
|
90
|
+
}
|
|
91
|
+
await this._bridge.disconnect(connectId);
|
|
92
|
+
}
|
|
93
|
+
async write(connectId, data) {
|
|
94
|
+
if (!this._connected.has(connectId)) throw notConnectedError(connectId);
|
|
95
|
+
const hex = Buffer.from(data).toString("hex");
|
|
96
|
+
await this._bridge.write(connectId, hex);
|
|
97
|
+
}
|
|
98
|
+
async read(connectId) {
|
|
99
|
+
if (!this._connected.has(connectId)) throw notConnectedError(connectId);
|
|
100
|
+
const queue = this._readQueues.get(connectId);
|
|
101
|
+
if (queue && queue.length > 0) {
|
|
102
|
+
return queue.shift();
|
|
103
|
+
}
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const pending = this._pendingReads.get(connectId);
|
|
106
|
+
if (!pending) {
|
|
107
|
+
reject(notConnectedError(connectId));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
pending.push({ resolve, reject });
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
onDisconnect(connectId, handler) {
|
|
114
|
+
const handlers = this._disconnectHandlers.get(connectId) ?? /* @__PURE__ */ new Set();
|
|
115
|
+
handlers.add(handler);
|
|
116
|
+
this._disconnectHandlers.set(connectId, handlers);
|
|
117
|
+
return () => {
|
|
118
|
+
handlers.delete(handler);
|
|
119
|
+
if (handlers.size === 0) {
|
|
120
|
+
this._disconnectHandlers.delete(connectId);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** Tear down global listeners — called by the connector's `reset()`. */
|
|
125
|
+
reset() {
|
|
126
|
+
this._disposeNotificationListener?.();
|
|
127
|
+
this._disposeDisconnectListener?.();
|
|
128
|
+
this._disposeNotificationListener = void 0;
|
|
129
|
+
this._disposeDisconnectListener = void 0;
|
|
130
|
+
for (const handlers of this._disconnectHandlers.values()) handlers.clear();
|
|
131
|
+
this._disconnectHandlers.clear();
|
|
132
|
+
for (const id of this._connected) this._failPendingReads(id, notConnectedError(id));
|
|
133
|
+
this._connected.clear();
|
|
134
|
+
this._readQueues.clear();
|
|
135
|
+
this._pendingReads.clear();
|
|
136
|
+
}
|
|
137
|
+
_wireGlobalListeners() {
|
|
138
|
+
this._disposeNotificationListener = this._bridge.onNotification((id, hex) => {
|
|
139
|
+
const data = new Uint8Array(Buffer.from(hex, "hex"));
|
|
140
|
+
const pending = this._pendingReads.get(id);
|
|
141
|
+
if (pending && pending.length > 0) {
|
|
142
|
+
pending.shift().resolve(data);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const queue = this._readQueues.get(id);
|
|
146
|
+
if (queue) queue.push(data);
|
|
147
|
+
});
|
|
148
|
+
this._disposeDisconnectListener = this._bridge.onDeviceDisconnected((id) => {
|
|
149
|
+
this._connected.delete(id);
|
|
150
|
+
this._failPendingReads(id, disconnectError(`Trezor BLE device disconnected: ${id}`));
|
|
151
|
+
this._readQueues.delete(id);
|
|
152
|
+
this._disconnectHandlers.get(id)?.forEach((handler) => {
|
|
153
|
+
try {
|
|
154
|
+
handler();
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this._log("error", "disconnect.handler.threw", { id, error: String(error) });
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
_failPendingReads(connectId, error) {
|
|
162
|
+
const pending = this._pendingReads.get(connectId);
|
|
163
|
+
if (!pending) return;
|
|
164
|
+
for (const item of pending) item.reject(error);
|
|
165
|
+
this._pendingReads.set(connectId, []);
|
|
166
|
+
}
|
|
167
|
+
_log(level, event, data) {
|
|
168
|
+
this._logger?.({ level, scope: "trezor-electron-ble", event, data });
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
function createTrezorElectronBleTransport(options) {
|
|
172
|
+
return new TrezorElectronBleTransport(options);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/TrezorElectronBleConnector.ts
|
|
176
|
+
var TrezorElectronBleConnector = class extends import_hwk_trezor_connector.TrezorConnectorBase {
|
|
177
|
+
constructor(options) {
|
|
178
|
+
super({
|
|
179
|
+
connectionType: "ble",
|
|
180
|
+
chunkSize: import_hwk_trezor_adapter2.TREZOR_BLE_PACKET_SIZE,
|
|
181
|
+
thp: options?.thp,
|
|
182
|
+
deviceSessionFactory: options?.deviceSessionFactory
|
|
183
|
+
});
|
|
184
|
+
this._transport = options?.transport;
|
|
185
|
+
this._transportOptions = options?.transportOptions;
|
|
186
|
+
}
|
|
187
|
+
async enumerateDevices() {
|
|
188
|
+
const transport = this._ensureTransport();
|
|
189
|
+
const devices = await transport.scan();
|
|
190
|
+
return devices.map((d) => ({
|
|
191
|
+
connectId: d.id,
|
|
192
|
+
deviceId: d.id,
|
|
193
|
+
name: d.name ?? d.localName ?? "Trezor Safe 7",
|
|
194
|
+
model: import_hwk_trezor_adapter2.TREZOR_SAFE_7_MODEL,
|
|
195
|
+
connectionType: "ble",
|
|
196
|
+
// Promote the typed BLE fields the device surface already has slots for.
|
|
197
|
+
rssi: d.rssi ?? null,
|
|
198
|
+
isConnectable: d.isConnectable ?? null,
|
|
199
|
+
capabilities: { persistentDeviceIdentity: false },
|
|
200
|
+
// Stash the FULL scan-time advertisement so the app/debug layer sees
|
|
201
|
+
// everything the OS BLE stack exposed (mirrors the WebUSB connector's
|
|
202
|
+
// `raw.descriptor`). This is where a cross-transport identity, if any,
|
|
203
|
+
// would surface (manufacturerData / serviceData / localName).
|
|
204
|
+
raw: {
|
|
205
|
+
transport: "electron-ble",
|
|
206
|
+
descriptor: d
|
|
207
|
+
}
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
async createByteTransport(device) {
|
|
211
|
+
const transport = this._ensureTransport();
|
|
212
|
+
await transport.connect(device.connectId);
|
|
213
|
+
return {
|
|
214
|
+
write: async (chunk) => {
|
|
215
|
+
await transport.write(device.connectId, Uint8Array.from(chunk));
|
|
216
|
+
},
|
|
217
|
+
read: async () => {
|
|
218
|
+
const data = await transport.read(device.connectId);
|
|
219
|
+
return import_buffer.Buffer.from(data);
|
|
220
|
+
},
|
|
221
|
+
close: () => transport.disconnect(device.connectId),
|
|
222
|
+
onDisconnect: (handler) => transport.onDisconnect(device.connectId, handler)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
resolveUnlistedDevice(deviceId) {
|
|
226
|
+
const connectId = deviceId.trim();
|
|
227
|
+
if (!connectId) return void 0;
|
|
228
|
+
return {
|
|
229
|
+
connectId,
|
|
230
|
+
deviceId: connectId,
|
|
231
|
+
name: "Trezor Safe 7",
|
|
232
|
+
model: import_hwk_trezor_adapter2.TREZOR_SAFE_7_MODEL,
|
|
233
|
+
capabilities: { persistentDeviceIdentity: false }
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
reset() {
|
|
237
|
+
super.reset();
|
|
238
|
+
this._transport?.reset();
|
|
239
|
+
this._transport = void 0;
|
|
240
|
+
}
|
|
241
|
+
_ensureTransport() {
|
|
242
|
+
if (!this._transport) {
|
|
243
|
+
this._transport = new TrezorElectronBleTransport(this._transportOptions);
|
|
244
|
+
}
|
|
245
|
+
return this._transport;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
function createTrezorElectronBleConnector(options) {
|
|
249
|
+
return new TrezorElectronBleConnector(options);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/constants.ts
|
|
253
|
+
var TREZOR_BLE_CHANNELS = {
|
|
254
|
+
scan: "$onekey-trezor-ble-scan",
|
|
255
|
+
stopScan: "$onekey-trezor-ble-stop-scan",
|
|
256
|
+
connect: "$onekey-trezor-ble-connect",
|
|
257
|
+
disconnect: "$onekey-trezor-ble-disconnect",
|
|
258
|
+
write: "$onekey-trezor-ble-write",
|
|
259
|
+
subscribe: "$onekey-trezor-ble-subscribe",
|
|
260
|
+
unsubscribe: "$onekey-trezor-ble-unsubscribe",
|
|
261
|
+
availability: "$onekey-trezor-ble-availability",
|
|
262
|
+
getDevice: "$onekey-trezor-ble-get-device",
|
|
263
|
+
readRssi: "$onekey-trezor-ble-read-rssi",
|
|
264
|
+
cancelPairing: "$onekey-trezor-ble-cancel-pairing",
|
|
265
|
+
/** push event: main → renderer with assembled BLE notification payload */
|
|
266
|
+
notification: "$onekey-trezor-ble-notification",
|
|
267
|
+
/** push event: main → renderer when device disconnects unexpectedly */
|
|
268
|
+
disconnected: "$onekey-trezor-ble-disconnected"
|
|
269
|
+
};
|
|
270
|
+
var TREZOR_BLE_SCAN_DURATION_MS = 5e3;
|
|
271
|
+
var TREZOR_BLE_POWER_ON_TIMEOUT_MS = 1e4;
|
|
272
|
+
var TREZOR_BLE_WRITE_CHUNK_DELAY_MS = 5;
|
|
273
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
274
|
+
0 && (module.exports = {
|
|
275
|
+
TREZOR_BLE_CHANNELS,
|
|
276
|
+
TREZOR_BLE_POWER_ON_TIMEOUT_MS,
|
|
277
|
+
TREZOR_BLE_SCAN_DURATION_MS,
|
|
278
|
+
TREZOR_BLE_WRITE_CHUNK_DELAY_MS,
|
|
279
|
+
TrezorElectronBleConnector,
|
|
280
|
+
TrezorElectronBleTransport,
|
|
281
|
+
createTrezorElectronBleConnector,
|
|
282
|
+
createTrezorElectronBleTransport
|
|
283
|
+
});
|
|
284
|
+
//# sourceMappingURL=index.js.map
|