@onekeyfe/hd-transport-usb 1.2.0-alpha.32 → 1.2.0-alpha.34
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/__tests__/protocol-v2-link.test.ts +41 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -15
- package/package.json +4 -4
- package/src/index.ts +20 -14
|
@@ -253,6 +253,28 @@ const createHarness = () => {
|
|
|
253
253
|
};
|
|
254
254
|
|
|
255
255
|
describe('NodeUsbTransport Protocol V2 link lifecycle', () => {
|
|
256
|
+
test('falls back to Protocol V2 when a cached V1 hint is stale', async () => {
|
|
257
|
+
const transport = new NodeUsbTransport() as any;
|
|
258
|
+
const events: string[] = [];
|
|
259
|
+
transport.probeProtocolV1 = jest.fn().mockImplementation(() => {
|
|
260
|
+
events.push('probe-v1');
|
|
261
|
+
return Promise.resolve(false);
|
|
262
|
+
});
|
|
263
|
+
transport.resetConnectionAfterProbe = jest.fn().mockImplementation(() => {
|
|
264
|
+
events.push('reset');
|
|
265
|
+
return Promise.resolve();
|
|
266
|
+
});
|
|
267
|
+
transport.probeProtocolV2 = jest.fn().mockImplementation(() => {
|
|
268
|
+
events.push('probe-v2');
|
|
269
|
+
return Promise.resolve(true);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
await expect(transport.detectProtocol('pro-usb', undefined, 'V1')).resolves.toBe('V2');
|
|
273
|
+
|
|
274
|
+
expect(events).toEqual(['probe-v1', 'reset', 'probe-v2']);
|
|
275
|
+
expect(transport.getProtocolType('pro-usb')).toBe('V2');
|
|
276
|
+
});
|
|
277
|
+
|
|
256
278
|
test('keeps active links when the Protocol V2 schema is configured repeatedly', () => {
|
|
257
279
|
const transport = new NodeUsbTransport() as any;
|
|
258
280
|
transport.invalidateAllProtocolV2UsbLinks = jest.fn().mockResolvedValue(undefined);
|
|
@@ -286,6 +308,25 @@ describe('NodeUsbTransport Protocol V2 link lifecycle', () => {
|
|
|
286
308
|
);
|
|
287
309
|
});
|
|
288
310
|
|
|
311
|
+
test('releases the USB interface when protocol detection rejects acquire', async () => {
|
|
312
|
+
const harness = createHarness();
|
|
313
|
+
const { transport, path, device, iface } = harness;
|
|
314
|
+
await transport.enumerate();
|
|
315
|
+
device.close.mockClear();
|
|
316
|
+
iface.release.mockClear();
|
|
317
|
+
jest
|
|
318
|
+
.spyOn(transport as any, 'detectProtocol')
|
|
319
|
+
.mockRejectedValueOnce(new Error('terminal protocol probe failure'));
|
|
320
|
+
|
|
321
|
+
await expect(transport.acquire({ path })).rejects.toMatchObject({
|
|
322
|
+
errorCode: expect.any(Number),
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
expect(iface.release).toHaveBeenCalledTimes(1);
|
|
326
|
+
expect(device.close).toHaveBeenCalledTimes(1);
|
|
327
|
+
expect((transport as any).openDevices.has(path)).toBe(false);
|
|
328
|
+
});
|
|
329
|
+
|
|
289
330
|
test('stop releases an acquired USB interface even before a Protocol V2 call', async () => {
|
|
290
331
|
const harness = createHarness();
|
|
291
332
|
const { transport, path, device, iface } = harness;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,SAAS,EAAE,EAQhB,0BAA0B,EAE3B,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAuIhC,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,0BAA0B,CAAC,MAAM,CAAC;IAC9E,QAAQ,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAGlE,UAAU,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEpE,OAAO,CAAC,sBAAsB,CAAqB;IAEnD,IAAI,SAAsB;IAE1B,OAAO,SAAM;IAEb,UAAU,UAAS;IAEnB,UAAU,UAAS;IAEnB,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,OAAO,CAAC,aAAa,CAA6B;IAGlD,OAAO,CAAC,WAAW,CAAiC;IAGpD,OAAO,CAAC,cAAc,CAAwC;IAG9D,OAAO,CAAC,cAAc,CAA0C;IAMhE,OAAO,CAAC,eAAe,CAGnB;IAGJ,OAAO,CAAC,SAAS,CAAS;;IAc1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAMxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAOzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAiBnC,MAAM;IAIA,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BrB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9E,IAAI,CAAC,IAAI,EAAE,MAAM;;;;;;IAiBjB,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA8BxC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -261,7 +261,7 @@ class NodeUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
acquire(input) {
|
|
264
|
-
var _a, _b, _c;
|
|
264
|
+
var _a, _b, _c, _d;
|
|
265
265
|
return __awaiter(this, void 0, void 0, function* () {
|
|
266
266
|
this.cancelled = false;
|
|
267
267
|
const path = (_a = input.path) !== null && _a !== void 0 ? _a : '';
|
|
@@ -272,12 +272,18 @@ class NodeUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
272
272
|
yield this.rotateProtocolV2UsbGeneration(path, 'Node USB transport acquired');
|
|
273
273
|
yield this.closeOpenDevice(path);
|
|
274
274
|
yield this.openDevice(path);
|
|
275
|
-
yield this.detectProtocol(path, input.expectedProtocol);
|
|
275
|
+
yield this.detectProtocol(path, input.expectedProtocol, input.protocolHint);
|
|
276
276
|
return path;
|
|
277
277
|
}
|
|
278
278
|
catch (error) {
|
|
279
279
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug('NodeUsbTransport acquire error: ', error);
|
|
280
|
-
|
|
280
|
+
try {
|
|
281
|
+
yield this.release(path);
|
|
282
|
+
}
|
|
283
|
+
catch (cleanupError) {
|
|
284
|
+
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug('NodeUsbTransport acquire cleanup error: ', cleanupError);
|
|
285
|
+
}
|
|
286
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, (_d = error.message) !== null && _d !== void 0 ? _d : String(error));
|
|
281
287
|
}
|
|
282
288
|
});
|
|
283
289
|
}
|
|
@@ -650,7 +656,7 @@ class NodeUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
650
656
|
createProtocolDetectionError() {
|
|
651
657
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Unable to detect USB protocol: device did not respond to Protocol V1 Initialize or Protocol V2 Ping');
|
|
652
658
|
}
|
|
653
|
-
detectProtocol(path, expectedProtocol) {
|
|
659
|
+
detectProtocol(path, expectedProtocol, protocolHint) {
|
|
654
660
|
var _a;
|
|
655
661
|
return __awaiter(this, void 0, void 0, function* () {
|
|
656
662
|
if (expectedProtocol === 'V2') {
|
|
@@ -668,17 +674,16 @@ class NodeUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
668
674
|
}
|
|
669
675
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
670
676
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
this.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
return 'V2';
|
|
677
|
+
const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(path) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
678
|
+
for (const [index, protocol] of probeOrder.entries()) {
|
|
679
|
+
if (index > 0) {
|
|
680
|
+
yield this.resetConnectionAfterProbe(path);
|
|
681
|
+
}
|
|
682
|
+
const detected = protocol === 'V1' ? yield this.probeProtocolV1(path) : yield this.probeProtocolV2(path);
|
|
683
|
+
if (detected) {
|
|
684
|
+
this.deviceProtocol.set(path, protocol);
|
|
685
|
+
return protocol;
|
|
686
|
+
}
|
|
682
687
|
}
|
|
683
688
|
this.deviceProtocol.delete(path);
|
|
684
689
|
throw this.createProtocolDetectionError();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-usb",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.34",
|
|
4
4
|
"description": "OneKey hardware wallet direct USB transport plugin (libusb)",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.34",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.34",
|
|
26
26
|
"bytebuffer": "^5.0.1",
|
|
27
27
|
"usb": "^2.14.0"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "07f10b4c9fab177da7c36d976ec18b075492b57f"
|
|
30
30
|
}
|
package/src/index.ts
CHANGED
|
@@ -346,10 +346,15 @@ export default class NodeUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
346
346
|
await this.rotateProtocolV2UsbGeneration(path, 'Node USB transport acquired');
|
|
347
347
|
await this.closeOpenDevice(path);
|
|
348
348
|
await this.openDevice(path);
|
|
349
|
-
await this.detectProtocol(path, input.expectedProtocol);
|
|
349
|
+
await this.detectProtocol(path, input.expectedProtocol, input.protocolHint);
|
|
350
350
|
return path;
|
|
351
351
|
} catch (error: any) {
|
|
352
352
|
this.Log?.debug('NodeUsbTransport acquire error: ', error);
|
|
353
|
+
try {
|
|
354
|
+
await this.release(path);
|
|
355
|
+
} catch (cleanupError) {
|
|
356
|
+
this.Log?.debug('NodeUsbTransport acquire cleanup error: ', cleanupError);
|
|
357
|
+
}
|
|
353
358
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound, error.message ?? String(error));
|
|
354
359
|
}
|
|
355
360
|
}
|
|
@@ -843,7 +848,8 @@ export default class NodeUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
843
848
|
|
|
844
849
|
private async detectProtocol(
|
|
845
850
|
path: string,
|
|
846
|
-
expectedProtocol?: ProtocolType
|
|
851
|
+
expectedProtocol?: ProtocolType,
|
|
852
|
+
protocolHint?: ProtocolType
|
|
847
853
|
): Promise<ProtocolType> {
|
|
848
854
|
if (expectedProtocol === 'V2') {
|
|
849
855
|
if (await this.probeProtocolV2(path)) {
|
|
@@ -862,19 +868,19 @@ export default class NodeUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
862
868
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
863
869
|
}
|
|
864
870
|
|
|
865
|
-
|
|
866
|
-
this.deviceProtocol.
|
|
867
|
-
return 'V2';
|
|
868
|
-
}
|
|
871
|
+
const probeOrder: ProtocolType[] =
|
|
872
|
+
protocolHint === 'V2' || this.deviceProtocol.get(path) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
869
873
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
874
|
+
for (const [index, protocol] of probeOrder.entries()) {
|
|
875
|
+
if (index > 0) {
|
|
876
|
+
await this.resetConnectionAfterProbe(path);
|
|
877
|
+
}
|
|
878
|
+
const detected =
|
|
879
|
+
protocol === 'V1' ? await this.probeProtocolV1(path) : await this.probeProtocolV2(path);
|
|
880
|
+
if (detected) {
|
|
881
|
+
this.deviceProtocol.set(path, protocol);
|
|
882
|
+
return protocol;
|
|
883
|
+
}
|
|
878
884
|
}
|
|
879
885
|
|
|
880
886
|
this.deviceProtocol.delete(path);
|