@onekeyfe/hd-common-connect-sdk 1.2.8-alpha.13 → 1.2.8-alpha.15
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/README.md +27 -0
- package/__tests__/device-state-events.test.ts +38 -4
- package/dist/index.d.ts +6 -1
- package/dist/index.js +26 -0
- package/package.json +9 -9
- package/src/index.ts +35 -0
package/README.md
CHANGED
|
@@ -28,6 +28,33 @@ function init() {
|
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## Desktop USB identity discovery
|
|
32
|
+
|
|
33
|
+
`probeUsbDeviceIdentities({ commType: 'webusb' | 'bridge' })` is a named export for
|
|
34
|
+
choosing a Desktop connection before switching the active SDK. It does not require
|
|
35
|
+
SDK initialization, dispose Core, change BLE settings, or open a wallet session.
|
|
36
|
+
Concurrent probes for the same mode share one pending request.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { probeUsbDeviceIdentities } from '@onekeyfe/hd-common-connect-sdk';
|
|
40
|
+
|
|
41
|
+
const devices = await probeUsbDeviceIdentities({ commType: 'webusb' });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Each result contains `path`, `serialNo`, `deviceId`, `deviceType`, `connectProtocol`,
|
|
45
|
+
and `commType`. `path` locates the USB endpoint; compare `serialNo` with the target's
|
|
46
|
+
physical identity, or `deviceId` for legacy devices without a physical serial.
|
|
47
|
+
Missing identities remain `null`; a descriptor path is never substituted for them.
|
|
48
|
+
The protocol comes from an active device response. V1 uses read-only Features;
|
|
49
|
+
V2 uses hardware DeviceInfo and does not query a wallet session.
|
|
50
|
+
|
|
51
|
+
Busy, ambiguous, disconnected, or unverified endpoints are omitted. An active
|
|
52
|
+
WebUSB request's identity can be reused only for the exact USB handle it owns.
|
|
53
|
+
Discovery releases only handles it acquired and does not replace the active SDK's
|
|
54
|
+
disconnect observer. An empty result is not proof that the device is absent.
|
|
55
|
+
Keep the selected transport fixed during a hardware operation; reevaluate it
|
|
56
|
+
between operations. Firmware updates must separately validate their live target.
|
|
57
|
+
|
|
31
58
|
## Docs
|
|
32
59
|
|
|
33
60
|
Documentation is available [Hardware SDK Getting Started](https://developer.onekey.so/en/hardware-sdk/getting-started)
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { readFileSync } from 'fs';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import EventEmitter from 'events';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CORE_EVENT,
|
|
6
|
+
UI_REQUEST,
|
|
7
|
+
initCore,
|
|
8
|
+
probeUsbDeviceIdentitiesWithTransport,
|
|
9
|
+
} from '@onekeyfe/hd-core';
|
|
5
10
|
import { HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
|
|
6
11
|
|
|
7
|
-
import sdkExport, { messagePromises } from '../src';
|
|
12
|
+
import sdkExport, { messagePromises, probeUsbDeviceIdentities } from '../src';
|
|
8
13
|
|
|
9
14
|
jest.mock('../../core/src/data/config', () => ({
|
|
10
15
|
getSDKVersion: jest.fn(() => '1.0.0-test'),
|
|
@@ -15,9 +20,10 @@ jest.mock('@onekeyfe/hd-core', () => ({
|
|
|
15
20
|
__esModule: true,
|
|
16
21
|
default: (options: unknown) => options,
|
|
17
22
|
initCore: jest.fn(),
|
|
23
|
+
probeUsbDeviceIdentitiesWithTransport: jest.fn(),
|
|
18
24
|
}));
|
|
19
|
-
jest.mock('@onekeyfe/hd-transport-http', () => ({}));
|
|
20
|
-
jest.mock('@onekeyfe/hd-transport-web-device', () => ({}));
|
|
25
|
+
jest.mock('@onekeyfe/hd-transport-http', () => ({ __esModule: true, default: jest.fn() }));
|
|
26
|
+
jest.mock('@onekeyfe/hd-transport-web-device', () => ({ WebUsbTransport: jest.fn() }));
|
|
21
27
|
jest.mock('@onekeyfe/hd-transport-lowlevel', () => ({}));
|
|
22
28
|
jest.mock('@onekeyfe/hd-transport-emulator', () => ({}));
|
|
23
29
|
|
|
@@ -82,6 +88,34 @@ describe('SDK request cleanup', () => {
|
|
|
82
88
|
expect(Object.keys(messagePromises)).toHaveLength(0);
|
|
83
89
|
});
|
|
84
90
|
|
|
91
|
+
test.each(['webusb', 'bridge'] as const)(
|
|
92
|
+
'probes %s without disposing an outstanding BLE request and coalesces concurrent probes',
|
|
93
|
+
async commType => {
|
|
94
|
+
const pending = createDeferred<unknown>();
|
|
95
|
+
const discovery = createDeferred<never[]>();
|
|
96
|
+
core.handleMessage.mockReturnValueOnce(pending.promise);
|
|
97
|
+
const request = sdk.call({ method: 'getDeviceState' });
|
|
98
|
+
jest
|
|
99
|
+
.mocked(probeUsbDeviceIdentitiesWithTransport)
|
|
100
|
+
.mockReset()
|
|
101
|
+
.mockReturnValueOnce(discovery.promise);
|
|
102
|
+
const initializationCount = jest.mocked(initCore).mock.calls.length;
|
|
103
|
+
const first = probeUsbDeviceIdentities({ commType });
|
|
104
|
+
const second = probeUsbDeviceIdentities({ commType });
|
|
105
|
+
expect(second).toBe(first);
|
|
106
|
+
expect(probeUsbDeviceIdentitiesWithTransport).toHaveBeenCalledTimes(1);
|
|
107
|
+
discovery.resolve([]);
|
|
108
|
+
await first;
|
|
109
|
+
expect(core.dispose).not.toHaveBeenCalled();
|
|
110
|
+
expect(initCore).toHaveBeenCalledTimes(initializationCount);
|
|
111
|
+
expect(core.listenerCount(CORE_EVENT)).toBe(1);
|
|
112
|
+
expect(Object.keys(messagePromises)).toHaveLength(1);
|
|
113
|
+
pending.resolve({ success: true, payload: {} });
|
|
114
|
+
await expect(request).resolves.toMatchObject({ success: true });
|
|
115
|
+
expect(Object.keys(messagePromises)).toHaveLength(0);
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
|
|
85
119
|
test('waits for Core disposal and does not retain old listeners after reinitialization', async () => {
|
|
86
120
|
const cleanup = createDeferred<void>();
|
|
87
121
|
core.dispose.mockImplementationOnce(async () => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import * as _onekeyfe_hd_core from '@onekeyfe/hd-core';
|
|
2
|
+
import { UsbDeviceIdentity } from '@onekeyfe/hd-core';
|
|
2
3
|
import { Deferred } from '@onekeyfe/hd-shared';
|
|
3
4
|
|
|
5
|
+
/** Identify USB without disposing the current SDK, changing settings, or opening a wallet. */
|
|
6
|
+
declare const probeUsbDeviceIdentities: ({ commType, }: {
|
|
7
|
+
commType: UsbDeviceIdentity['commType'];
|
|
8
|
+
}) => Promise<UsbDeviceIdentity[]>;
|
|
4
9
|
declare const messagePromises: {
|
|
5
10
|
[key: number]: Deferred<any>;
|
|
6
11
|
};
|
|
7
12
|
declare const HardwareCommonConnectSdk: _onekeyfe_hd_core.CoreApi;
|
|
8
13
|
|
|
9
|
-
export { HardwareCommonConnectSdk as default, messagePromises };
|
|
14
|
+
export { HardwareCommonConnectSdk as default, messagePromises, probeUsbDeviceIdentities };
|
package/dist/index.js
CHANGED
|
@@ -607,6 +607,31 @@ var getTransport = function (env) { return __awaiter(void 0, void 0, void 0, fun
|
|
|
607
607
|
}); };
|
|
608
608
|
var _core;
|
|
609
609
|
var _settings = HardwareSdk.parseConnectSettings();
|
|
610
|
+
var usbIdentityProbeTransports = {};
|
|
611
|
+
var usbIdentityProbes = {};
|
|
612
|
+
/** Identify USB without disposing the current SDK, changing settings, or opening a wallet. */
|
|
613
|
+
var probeUsbDeviceIdentities = function (_a) {
|
|
614
|
+
var commType = _a.commType;
|
|
615
|
+
if (commType !== 'webusb' && commType !== 'bridge') {
|
|
616
|
+
return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter));
|
|
617
|
+
}
|
|
618
|
+
var pending = usbIdentityProbes[commType];
|
|
619
|
+
if (pending)
|
|
620
|
+
return pending;
|
|
621
|
+
var transport = usbIdentityProbeTransports[commType];
|
|
622
|
+
if (!transport) {
|
|
623
|
+
transport =
|
|
624
|
+
commType === 'webusb' ? new hdTransportWebDevice.WebUsbTransport(true) : new HttpTransport__default["default"](undefined, 3000);
|
|
625
|
+
usbIdentityProbeTransports[commType] = transport;
|
|
626
|
+
}
|
|
627
|
+
var probe = HardwareSdk.probeUsbDeviceIdentitiesWithTransport(transport, commType, function (descriptor) {
|
|
628
|
+
return _core === null || _core === void 0 ? void 0 : _core.getOwnedUsbDeviceIdentity(descriptor);
|
|
629
|
+
}).finally(function () {
|
|
630
|
+
delete usbIdentityProbes[commType];
|
|
631
|
+
});
|
|
632
|
+
usbIdentityProbes[commType] = probe;
|
|
633
|
+
return probe;
|
|
634
|
+
};
|
|
610
635
|
var _messageID = 0;
|
|
611
636
|
var messagePromises = {};
|
|
612
637
|
var dispose = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -790,3 +815,4 @@ var HardwareCommonConnectSdk = HardwareSdk__default["default"]({
|
|
|
790
815
|
|
|
791
816
|
exports["default"] = HardwareCommonConnectSdk;
|
|
792
817
|
exports.messagePromises = messagePromises;
|
|
818
|
+
exports.probeUsbDeviceIdentities = probeUsbDeviceIdentities;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-common-connect-sdk",
|
|
3
|
-
"version": "1.2.8-alpha.
|
|
3
|
+
"version": "1.2.8-alpha.15",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "ISC",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-core": "1.2.8-alpha.
|
|
25
|
-
"@onekeyfe/hd-shared": "1.2.8-alpha.
|
|
26
|
-
"@onekeyfe/hd-transport-emulator": "1.2.8-alpha.
|
|
27
|
-
"@onekeyfe/hd-transport-http": "1.2.8-alpha.
|
|
28
|
-
"@onekeyfe/hd-transport-lowlevel": "1.2.8-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport-usb": "1.2.8-alpha.
|
|
30
|
-
"@onekeyfe/hd-transport-web-device": "1.2.8-alpha.
|
|
24
|
+
"@onekeyfe/hd-core": "1.2.8-alpha.15",
|
|
25
|
+
"@onekeyfe/hd-shared": "1.2.8-alpha.15",
|
|
26
|
+
"@onekeyfe/hd-transport-emulator": "1.2.8-alpha.15",
|
|
27
|
+
"@onekeyfe/hd-transport-http": "1.2.8-alpha.15",
|
|
28
|
+
"@onekeyfe/hd-transport-lowlevel": "1.2.8-alpha.15",
|
|
29
|
+
"@onekeyfe/hd-transport-usb": "1.2.8-alpha.15",
|
|
30
|
+
"@onekeyfe/hd-transport-web-device": "1.2.8-alpha.15"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "e84d88f3866ddfb99e18eed9188a583f56a30b17"
|
|
33
33
|
}
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import HardwareSdk, {
|
|
|
17
17
|
getLogger,
|
|
18
18
|
initCore,
|
|
19
19
|
parseConnectSettings,
|
|
20
|
+
probeUsbDeviceIdentitiesWithTransport,
|
|
20
21
|
setLoggerPostMessage,
|
|
21
22
|
} from '@onekeyfe/hd-core';
|
|
22
23
|
import { ERRORS, HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
|
|
@@ -32,6 +33,7 @@ import type {
|
|
|
32
33
|
CoreMessage,
|
|
33
34
|
LowLevelCoreApi,
|
|
34
35
|
UiResponseEvent,
|
|
36
|
+
UsbDeviceIdentity,
|
|
35
37
|
} from '@onekeyfe/hd-core';
|
|
36
38
|
import type { LowlevelTransportSharedPlugin } from '@onekeyfe/hd-transport';
|
|
37
39
|
|
|
@@ -57,6 +59,39 @@ const getTransport = async (env: ConnectSettings['env']) => {
|
|
|
57
59
|
let _core: Core | undefined;
|
|
58
60
|
let _settings = parseConnectSettings();
|
|
59
61
|
|
|
62
|
+
const usbIdentityProbeTransports: Partial<
|
|
63
|
+
Record<UsbDeviceIdentity['commType'], WebUsbTransport | HttpTransport>
|
|
64
|
+
> = {};
|
|
65
|
+
const usbIdentityProbes: Partial<
|
|
66
|
+
Record<UsbDeviceIdentity['commType'], Promise<UsbDeviceIdentity[]>>
|
|
67
|
+
> = {};
|
|
68
|
+
|
|
69
|
+
/** Identify USB without disposing the current SDK, changing settings, or opening a wallet. */
|
|
70
|
+
export const probeUsbDeviceIdentities = ({
|
|
71
|
+
commType,
|
|
72
|
+
}: {
|
|
73
|
+
commType: UsbDeviceIdentity['commType'];
|
|
74
|
+
}): Promise<UsbDeviceIdentity[]> => {
|
|
75
|
+
if (commType !== 'webusb' && commType !== 'bridge') {
|
|
76
|
+
return Promise.reject(ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter));
|
|
77
|
+
}
|
|
78
|
+
const pending = usbIdentityProbes[commType];
|
|
79
|
+
if (pending) return pending;
|
|
80
|
+
let transport = usbIdentityProbeTransports[commType];
|
|
81
|
+
if (!transport) {
|
|
82
|
+
transport =
|
|
83
|
+
commType === 'webusb' ? new WebUsbTransport(true) : new HttpTransport(undefined, 3000);
|
|
84
|
+
usbIdentityProbeTransports[commType] = transport;
|
|
85
|
+
}
|
|
86
|
+
const probe = probeUsbDeviceIdentitiesWithTransport(transport, commType, descriptor =>
|
|
87
|
+
_core?.getOwnedUsbDeviceIdentity(descriptor)
|
|
88
|
+
).finally(() => {
|
|
89
|
+
delete usbIdentityProbes[commType];
|
|
90
|
+
});
|
|
91
|
+
usbIdentityProbes[commType] = probe;
|
|
92
|
+
return probe;
|
|
93
|
+
};
|
|
94
|
+
|
|
60
95
|
let _messageID = 0;
|
|
61
96
|
export const messagePromises: { [key: number]: Deferred<any> } = {};
|
|
62
97
|
|