@onekeyfe/hd-core 1.2.2-alpha.8 → 1.2.2-alpha.9
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__/device-lifecycle-events.test.ts +37 -0
- package/__tests__/open-wallet-session.test.ts +86 -5
- package/__tests__/protocol-v2.test.ts +2 -2
- package/dist/core/RequestQueue.d.ts +2 -0
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/index.js +33 -11
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/core/RequestQueue.ts +16 -1
- package/src/core/index.ts +19 -11
- package/src/protocols/protocol-v2/walletSession.ts +4 -0
|
@@ -2,6 +2,7 @@ import { EDeviceType, ERRORS, HardwareErrorCode, createDeferred } from '@onekeyf
|
|
|
2
2
|
import { DeviceType, TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
+
cancel,
|
|
5
6
|
initConnector,
|
|
6
7
|
initCore,
|
|
7
8
|
isMissingDetectedProtocolV2Error,
|
|
@@ -120,6 +121,42 @@ describe('public device lifecycle events', () => {
|
|
|
120
121
|
expect(context.getPrePendingCallPromise('device-a')).toBe(replacementCleanup.promise);
|
|
121
122
|
});
|
|
122
123
|
|
|
124
|
+
test('cancels only requests associated with the requested connect id', () => {
|
|
125
|
+
core = initCore();
|
|
126
|
+
const context = (core as any).getCoreContext();
|
|
127
|
+
const deviceA = {
|
|
128
|
+
mainId: 'transport-session-a',
|
|
129
|
+
getConnectId: jest.fn(() => 'serial-a'),
|
|
130
|
+
interruptionFromUser: jest.fn().mockResolvedValue(undefined),
|
|
131
|
+
};
|
|
132
|
+
const deviceB = {
|
|
133
|
+
mainId: 'device-b',
|
|
134
|
+
getConnectId: jest.fn(() => 'serial-b'),
|
|
135
|
+
interruptionFromUser: jest.fn().mockResolvedValue(undefined),
|
|
136
|
+
};
|
|
137
|
+
const taskA = context.requestQueue.createTask({
|
|
138
|
+
responseID: 101,
|
|
139
|
+
connectId: '',
|
|
140
|
+
device: deviceA,
|
|
141
|
+
} as never);
|
|
142
|
+
const taskB = context.requestQueue.createTask({
|
|
143
|
+
responseID: 102,
|
|
144
|
+
connectId: 'device-b',
|
|
145
|
+
device: deviceB,
|
|
146
|
+
} as never);
|
|
147
|
+
const signalA = taskA.abortController?.signal;
|
|
148
|
+
const signalB = taskB.abortController?.signal;
|
|
149
|
+
|
|
150
|
+
cancel(context, 'serial-a');
|
|
151
|
+
|
|
152
|
+
expect(signalA?.aborted).toBe(true);
|
|
153
|
+
expect(context.requestQueue.getTask(taskA.id)).toBeUndefined();
|
|
154
|
+
expect(signalB?.aborted).toBe(false);
|
|
155
|
+
expect(context.requestQueue.getTask(taskB.id)).toBe(taskB);
|
|
156
|
+
expect(deviceA.interruptionFromUser).toHaveBeenCalledTimes(1);
|
|
157
|
+
expect(deviceB.interruptionFromUser).not.toHaveBeenCalled();
|
|
158
|
+
});
|
|
159
|
+
|
|
123
160
|
test('keeps shared device lifecycle listeners across a device cache reset', () => {
|
|
124
161
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
125
162
|
core = initCore();
|
|
@@ -26,12 +26,16 @@ jest.mock('../src/data/config', () => ({
|
|
|
26
26
|
const createDevice = ({
|
|
27
27
|
passphraseProtection = true,
|
|
28
28
|
unlockedAttachPin = false,
|
|
29
|
+
refreshedUnlocked = true,
|
|
30
|
+
refreshedPassphraseProtection = passphraseProtection,
|
|
29
31
|
refreshedUnlockedAttachPin = unlockedAttachPin,
|
|
30
32
|
typedCall = jest.fn(),
|
|
31
33
|
promptPassphrase = jest.fn(),
|
|
32
34
|
}: {
|
|
33
35
|
passphraseProtection?: boolean;
|
|
34
36
|
unlockedAttachPin?: boolean;
|
|
37
|
+
refreshedUnlocked?: boolean;
|
|
38
|
+
refreshedPassphraseProtection?: boolean;
|
|
35
39
|
refreshedUnlockedAttachPin?: boolean;
|
|
36
40
|
typedCall?: jest.Mock;
|
|
37
41
|
promptPassphrase?: jest.Mock;
|
|
@@ -50,11 +54,11 @@ const createDevice = ({
|
|
|
50
54
|
return {
|
|
51
55
|
message: {
|
|
52
56
|
device_id: 'device-1',
|
|
53
|
-
unlocked:
|
|
57
|
+
unlocked: refreshedUnlocked,
|
|
54
58
|
attach_to_pin_enabled: unlockedAttachPin,
|
|
55
59
|
unlocked_attach_pin: refreshedUnlockedAttachPin,
|
|
56
60
|
unlocked_by_attach_to_pin: refreshedUnlockedAttachPin,
|
|
57
|
-
passphrase_enabled:
|
|
61
|
+
passphrase_enabled: refreshedPassphraseProtection,
|
|
58
62
|
},
|
|
59
63
|
};
|
|
60
64
|
}
|
|
@@ -95,6 +99,8 @@ const createDevice = ({
|
|
|
95
99
|
unlockDevice: jest.fn(),
|
|
96
100
|
updateProtocolV2Status: jest.fn((status: Record<string, unknown>) => {
|
|
97
101
|
device.features.unlocked = status.unlocked ?? device.features.unlocked;
|
|
102
|
+
device.features.passphraseProtection =
|
|
103
|
+
status.passphrase_enabled ?? device.features.passphraseProtection;
|
|
98
104
|
device.features.attachToPinEnabled =
|
|
99
105
|
status.attach_to_pin_enabled ?? device.features.attachToPinEnabled;
|
|
100
106
|
device.features.unlockedAttachPin =
|
|
@@ -182,6 +188,65 @@ describe('openWalletSession', () => {
|
|
|
182
188
|
expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', standardSessionGet);
|
|
183
189
|
});
|
|
184
190
|
|
|
191
|
+
test('refreshes stale wallet status before accepting an only-Main-PIN session', async () => {
|
|
192
|
+
let attachPinSelected = true;
|
|
193
|
+
const typedCall = jest.fn((request: string) => {
|
|
194
|
+
if (request === 'ProtocolInfoRequest') {
|
|
195
|
+
return { message: { version: 2 } };
|
|
196
|
+
}
|
|
197
|
+
if (request === 'DeviceSessionGet') {
|
|
198
|
+
return {
|
|
199
|
+
message: {
|
|
200
|
+
btc_test_address: 'standard-state',
|
|
201
|
+
session_id: 'standard-session',
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (request === 'DeviceSessionAskPassphrase') {
|
|
206
|
+
return { message: {} };
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`Unexpected request: ${request}`);
|
|
209
|
+
});
|
|
210
|
+
const device = createDevice({
|
|
211
|
+
passphraseProtection: false,
|
|
212
|
+
unlockedAttachPin: false,
|
|
213
|
+
typedCall,
|
|
214
|
+
});
|
|
215
|
+
device.commands.typedCall.mockImplementation((request: string, ...args: unknown[]) => {
|
|
216
|
+
if (request === 'DeviceStatusGet') {
|
|
217
|
+
return {
|
|
218
|
+
message: {
|
|
219
|
+
device_id: 'device-1',
|
|
220
|
+
unlocked: true,
|
|
221
|
+
attach_to_pin_enabled: true,
|
|
222
|
+
unlocked_attach_pin: attachPinSelected,
|
|
223
|
+
unlocked_by_attach_to_pin: attachPinSelected,
|
|
224
|
+
passphrase_enabled: true,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return typedCall(request, ...args);
|
|
229
|
+
});
|
|
230
|
+
device.unlockDevice.mockImplementation(() => {
|
|
231
|
+
attachPinSelected = false;
|
|
232
|
+
device.features.unlockedAttachPin = false;
|
|
233
|
+
return Promise.resolve(device.features);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
await expect(
|
|
237
|
+
getProtocolV2WalletSession(device as any, { onlyMainPin: true })
|
|
238
|
+
).resolves.toMatchObject({
|
|
239
|
+
unlockedAttachPin: false,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
expect(device.commands.typedCall).toHaveBeenCalledWith('DeviceStatusGet', 'DeviceStatus', {});
|
|
243
|
+
expect(device.unlockDevice).toHaveBeenCalledWith(DeviceSessionPinType.Main, {
|
|
244
|
+
source: 'wallet-session-coordinator',
|
|
245
|
+
reason: 'open-wallet',
|
|
246
|
+
deviceOnly: true,
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
185
250
|
test('still requires Main PIN when a cached standard session resolves to another wallet', async () => {
|
|
186
251
|
let sessionGetCount = 0;
|
|
187
252
|
const typedCall = jest.fn((request: string) => {
|
|
@@ -267,8 +332,7 @@ describe('openWalletSession', () => {
|
|
|
267
332
|
}
|
|
268
333
|
throw new Error(`Unexpected request: ${request}`);
|
|
269
334
|
});
|
|
270
|
-
const device = createDevice({ typedCall });
|
|
271
|
-
device.features.unlockedAttachPin = true;
|
|
335
|
+
const device = createDevice({ refreshedUnlockedAttachPin: true, typedCall });
|
|
272
336
|
|
|
273
337
|
await getProtocolV2WalletSession(device as any, { onlyMainPin: true });
|
|
274
338
|
|
|
@@ -1157,7 +1221,7 @@ describe('openWalletSession', () => {
|
|
|
1157
1221
|
payload: { method: 'openWalletSession', connectId: 'connect-id', mode: 'standard' },
|
|
1158
1222
|
});
|
|
1159
1223
|
method.init();
|
|
1160
|
-
const device = createDevice({ typedCall });
|
|
1224
|
+
const device = createDevice({ refreshedUnlocked: false, typedCall });
|
|
1161
1225
|
device.features.unlocked = false;
|
|
1162
1226
|
device.getDeviceState = jest
|
|
1163
1227
|
.fn()
|
|
@@ -1257,6 +1321,7 @@ describe('openWalletSession', () => {
|
|
|
1257
1321
|
});
|
|
1258
1322
|
|
|
1259
1323
|
test('switches from Attach PIN to Main PIN before opening the standard wallet', async () => {
|
|
1324
|
+
let attachPinSelected = true;
|
|
1260
1325
|
const typedCall = jest
|
|
1261
1326
|
.fn()
|
|
1262
1327
|
.mockResolvedValueOnce({ message: { version: 2 } })
|
|
@@ -1273,6 +1338,21 @@ describe('openWalletSession', () => {
|
|
|
1273
1338
|
method.init();
|
|
1274
1339
|
const device = createDevice({ typedCall });
|
|
1275
1340
|
device.features.unlockedAttachPin = true;
|
|
1341
|
+
device.commands.typedCall.mockImplementation((request: string, ...args: unknown[]) => {
|
|
1342
|
+
if (request === 'DeviceStatusGet') {
|
|
1343
|
+
return {
|
|
1344
|
+
message: {
|
|
1345
|
+
device_id: 'device-1',
|
|
1346
|
+
unlocked: true,
|
|
1347
|
+
attach_to_pin_enabled: true,
|
|
1348
|
+
unlocked_attach_pin: attachPinSelected,
|
|
1349
|
+
unlocked_by_attach_to_pin: attachPinSelected,
|
|
1350
|
+
passphrase_enabled: true,
|
|
1351
|
+
},
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
return typedCall(request, ...args);
|
|
1355
|
+
});
|
|
1276
1356
|
device.getDeviceState = jest
|
|
1277
1357
|
.fn()
|
|
1278
1358
|
.mockResolvedValueOnce({
|
|
@@ -1292,6 +1372,7 @@ describe('openWalletSession', () => {
|
|
|
1292
1372
|
},
|
|
1293
1373
|
});
|
|
1294
1374
|
device.unlockDevice = jest.fn().mockImplementation(() => {
|
|
1375
|
+
attachPinSelected = false;
|
|
1295
1376
|
device.features.unlockedAttachPin = false;
|
|
1296
1377
|
return Promise.resolve(device.features);
|
|
1297
1378
|
});
|
|
@@ -2786,7 +2786,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2786
2786
|
await expect(
|
|
2787
2787
|
device.checkPassphraseStateSafety('stale-hidden-state', true, false)
|
|
2788
2788
|
).resolves.toBe(true);
|
|
2789
|
-
expect(typedCall).toHaveBeenCalledTimes(
|
|
2789
|
+
expect(typedCall).toHaveBeenCalledTimes(6);
|
|
2790
2790
|
expect(typedCall).toHaveBeenCalledWith('ProtocolInfoRequest', 'ProtocolInfo', {
|
|
2791
2791
|
eventless_wallet_session: true,
|
|
2792
2792
|
});
|
|
@@ -2798,7 +2798,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2798
2798
|
});
|
|
2799
2799
|
expect(typedCall).toHaveBeenCalledWith('DeviceStatusGet', 'DeviceStatus', {});
|
|
2800
2800
|
expect(typedCall.mock.calls.filter(([request]) => request === 'DeviceStatusGet')).toHaveLength(
|
|
2801
|
-
|
|
2801
|
+
3
|
|
2802
2802
|
);
|
|
2803
2803
|
expect(typedCall).not.toHaveBeenCalledWith('DeviceSessionAskPin', 'Success', expect.anything());
|
|
2804
2804
|
});
|
|
@@ -14,7 +14,9 @@ export default class RequestQueue {
|
|
|
14
14
|
getTask(requestId: number): RequestTask | undefined;
|
|
15
15
|
getAbortController(requestId: number): AbortController | undefined;
|
|
16
16
|
abortRequest(requestId: number): boolean;
|
|
17
|
+
private isRequestForConnectId;
|
|
17
18
|
abortRequestsByConnectId(connectId: string): number;
|
|
19
|
+
getRequestTasksIdByConnectId(connectId: string): number[];
|
|
18
20
|
abortAllRequests(): number;
|
|
19
21
|
getRequestTasksId(): number[];
|
|
20
22
|
resolveRequest(requestId: number, response: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestQueue.d.ts","sourceRoot":"","sources":["../../src/core/RequestQueue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACxC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,YAAY,CAAkC;IAEtD,OAAO,CAAC,oBAAoB,CAAqC;IAG1D,iBAAiB,YAAa,UAAU,YAK7C;IAEK,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW;IAY3C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAKnD,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAKpC,YAAY,CAAC,SAAS,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"RequestQueue.d.ts","sourceRoot":"","sources":["../../src/core/RequestQueue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACxC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,YAAY,CAAkC;IAEtD,OAAO,CAAC,oBAAoB,CAAqC;IAG1D,iBAAiB,YAAa,UAAU,YAK7C;IAEK,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW;IAY3C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAKnD,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAKpC,YAAY,CAAC,SAAS,EAAE,MAAM;IAUrC,OAAO,CAAC,qBAAqB;IAUtB,wBAAwB,CAAC,SAAS,EAAE,MAAM;IAY1C,4BAA4B,CAAC,SAAS,EAAE,MAAM;IAO9C,gBAAgB;IAYhB,iBAAiB;IAKjB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG;IAS/C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG;IAS3C,WAAW,CAAC,SAAS,EAAE,MAAM;IAI7B,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,CAAC,IAAI,CAAC;IAYxE,2BAA2B,CACtC,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC;IAST,mBAAmB,CAAC,SAAS,EAAE,MAAM;CAM7C"}
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAEL,KAAK,6BAA6B,EAElC,KAAK,YAAY,EAIlB,MAAM,wBAAwB,CAAC;AA+BhC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AA0E7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAyqBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAWpF;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAW/E;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAQlF;AAED,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAMrF;AA6JD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,CAMtF;AAwLD,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAEL,KAAK,6BAA6B,EAElC,KAAK,YAAY,EAIlB,MAAM,wBAAwB,CAAC;AA+BhC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AA0E7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAyqBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAWpF;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAW/E;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAQlF;AAED,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAMrF;AA6JD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,CAMtF;AAwLD,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SA2G9D,CAAC;AA8GF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IA6BhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -41909,6 +41909,10 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41909
41909
|
const markWalletStatusRefreshed = () => {
|
|
41910
41910
|
walletStatusRefreshed = true;
|
|
41911
41911
|
};
|
|
41912
|
+
if ((options === null || options === void 0 ? void 0 : options.onlyMainPin) && options.mainPinSelected !== true) {
|
|
41913
|
+
yield refreshProtocolV2DeviceStatus(device);
|
|
41914
|
+
markWalletStatusRefreshed();
|
|
41915
|
+
}
|
|
41912
41916
|
let mainPinAuthenticated = (options === null || options === void 0 ? void 0 : options.mainPinSelected) === true ||
|
|
41913
41917
|
((options === null || options === void 0 ? void 0 : options.onlyMainPin) === true &&
|
|
41914
41918
|
((_d = device.features) === null || _d === void 0 ? void 0 : _d.unlocked) === true &&
|
|
@@ -65591,10 +65595,17 @@ class RequestQueue {
|
|
|
65591
65595
|
}
|
|
65592
65596
|
return false;
|
|
65593
65597
|
}
|
|
65598
|
+
isRequestForConnectId(request, connectId) {
|
|
65599
|
+
var _a, _b;
|
|
65600
|
+
const { method } = request;
|
|
65601
|
+
return (method.connectId === connectId ||
|
|
65602
|
+
((_a = method.device) === null || _a === void 0 ? void 0 : _a.mainId) === connectId ||
|
|
65603
|
+
((_b = method.device) === null || _b === void 0 ? void 0 : _b.getConnectId()) === connectId);
|
|
65604
|
+
}
|
|
65594
65605
|
abortRequestsByConnectId(connectId) {
|
|
65595
65606
|
let count = 0;
|
|
65596
65607
|
this.requestQueue.forEach((request, _) => {
|
|
65597
|
-
if (request.abortController && request
|
|
65608
|
+
if (request.abortController && this.isRequestForConnectId(request, connectId)) {
|
|
65598
65609
|
request.abortController.abort();
|
|
65599
65610
|
request.abortController = undefined;
|
|
65600
65611
|
count++;
|
|
@@ -65602,6 +65613,11 @@ class RequestQueue {
|
|
|
65602
65613
|
});
|
|
65603
65614
|
return count;
|
|
65604
65615
|
}
|
|
65616
|
+
getRequestTasksIdByConnectId(connectId) {
|
|
65617
|
+
return Array.from(this.requestQueue.values())
|
|
65618
|
+
.filter(request => this.isRequestForConnectId(request, connectId))
|
|
65619
|
+
.map(request => request.id);
|
|
65620
|
+
}
|
|
65605
65621
|
abortAllRequests() {
|
|
65606
65622
|
let count = 0;
|
|
65607
65623
|
this.requestQueue.forEach(request => {
|
|
@@ -66644,14 +66660,14 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
|
|
|
66644
66660
|
return poll();
|
|
66645
66661
|
});
|
|
66646
66662
|
const cancel = (context, connectId) => {
|
|
66647
|
-
var _a, _b
|
|
66663
|
+
var _a, _b;
|
|
66648
66664
|
const { requestQueue, setPrePendingCallPromise } = context;
|
|
66649
66665
|
if (connectId) {
|
|
66650
66666
|
try {
|
|
66651
66667
|
requestQueue.cancelCallbackTasks(connectId);
|
|
66652
|
-
const requestIds = requestQueue.
|
|
66668
|
+
const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
|
|
66653
66669
|
Log.debug(`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(',')}`);
|
|
66654
|
-
requestQueue.
|
|
66670
|
+
requestQueue.abortRequestsByConnectId(connectId);
|
|
66655
66671
|
const canceledDevices = [];
|
|
66656
66672
|
const interruptDevice = (device, deviceConnectId) => {
|
|
66657
66673
|
if (!device || canceledDevices.includes(device)) {
|
|
@@ -66664,7 +66680,7 @@ const cancel = (context, connectId) => {
|
|
|
66664
66680
|
const task = requestQueue.getTask(requestId);
|
|
66665
66681
|
Log.debug('Cancel Api connect task: ', task);
|
|
66666
66682
|
if (task) {
|
|
66667
|
-
interruptDevice((_a = task.method) === null || _a === void 0 ? void 0 : _a.device,
|
|
66683
|
+
interruptDevice((_a = task.method) === null || _a === void 0 ? void 0 : _a.device, connectId);
|
|
66668
66684
|
interruptDevice(deviceCacheMap.get(connectId), connectId);
|
|
66669
66685
|
requestQueue.rejectRequest(requestId, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled));
|
|
66670
66686
|
}
|
|
@@ -66693,7 +66709,7 @@ const cancel = (context, connectId) => {
|
|
|
66693
66709
|
const task = requestQueue.getTask(requestId);
|
|
66694
66710
|
Log.debug('Cancel Api connect task: ', task);
|
|
66695
66711
|
if (task) {
|
|
66696
|
-
interruptDevice((
|
|
66712
|
+
interruptDevice((_b = task.method) === null || _b === void 0 ? void 0 : _b.device);
|
|
66697
66713
|
if (task.method.connectId) {
|
|
66698
66714
|
interruptDevice(deviceCacheMap.get(task.method.connectId));
|
|
66699
66715
|
pollingManager.stop(task.method.connectId);
|
|
@@ -66716,8 +66732,10 @@ const cancel = (context, connectId) => {
|
|
|
66716
66732
|
});
|
|
66717
66733
|
}
|
|
66718
66734
|
}
|
|
66719
|
-
cleanup();
|
|
66720
|
-
|
|
66735
|
+
cleanup(connectId);
|
|
66736
|
+
if (!connectId || _uiPromises.length === 0) {
|
|
66737
|
+
closePopup();
|
|
66738
|
+
}
|
|
66721
66739
|
};
|
|
66722
66740
|
const checkPassphraseEnableState = (method, features) => {
|
|
66723
66741
|
if (!method.useDevicePassphraseState)
|
|
@@ -66747,9 +66765,13 @@ const shouldCheckPassphraseState = (method, device) => {
|
|
|
66747
66765
|
}
|
|
66748
66766
|
return device.hasUsePassphrase();
|
|
66749
66767
|
};
|
|
66750
|
-
const cleanup = () => {
|
|
66751
|
-
const pendingUiPromises =
|
|
66752
|
-
|
|
66768
|
+
const cleanup = (connectId) => {
|
|
66769
|
+
const pendingUiPromises = connectId
|
|
66770
|
+
? _uiPromises.filter(uiPromise => { var _a, _b; return ((_a = uiPromise.data) === null || _a === void 0 ? void 0 : _a.mainId) === connectId || ((_b = uiPromise.data) === null || _b === void 0 ? void 0 : _b.getConnectId()) === connectId; })
|
|
66771
|
+
: _uiPromises;
|
|
66772
|
+
_uiPromises = connectId
|
|
66773
|
+
? _uiPromises.filter(uiPromise => !pendingUiPromises.includes(uiPromise))
|
|
66774
|
+
: [];
|
|
66753
66775
|
rejectUiPromises(pendingUiPromises, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, 'UI request was cancelled'));
|
|
66754
66776
|
};
|
|
66755
66777
|
const removeDeviceListener = (device) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAuBlD,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,0DAGjE;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,qCAGjE;AAED,wBAAsB,qCAAqC,CAAC,MAAM,EAAE,MAAM,oBAgBzE;AA8JD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;;;;;;
|
|
1
|
+
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAuBlD,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,0DAGjE;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,qCAGjE;AAED,wBAAsB,qCAAqC,CAAC,MAAM,EAAE,MAAM,oBAgBzE;AA8JD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;;;;;;GA6XF;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,MAAM,EACd,uBAAuB,EAAE,MAAM,EAC/B,aAAa,CAAC,EAAE,OAAO;;;;;;GAOxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.9",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.2-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.9",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.9",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
47
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "c097e98f32c451ccdda468da1195daf679e991e6"
|
|
50
50
|
}
|
package/src/core/RequestQueue.ts
CHANGED
|
@@ -56,11 +56,20 @@ export default class RequestQueue {
|
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
private isRequestForConnectId(request: RequestTask, connectId: string) {
|
|
60
|
+
const { method } = request;
|
|
61
|
+
return (
|
|
62
|
+
method.connectId === connectId ||
|
|
63
|
+
method.device?.mainId === connectId ||
|
|
64
|
+
method.device?.getConnectId() === connectId
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
// 取消与指定connectId相关的所有请求
|
|
60
69
|
public abortRequestsByConnectId(connectId: string) {
|
|
61
70
|
let count = 0;
|
|
62
71
|
this.requestQueue.forEach((request, _) => {
|
|
63
|
-
if (request.abortController && request
|
|
72
|
+
if (request.abortController && this.isRequestForConnectId(request, connectId)) {
|
|
64
73
|
request.abortController.abort();
|
|
65
74
|
request.abortController = undefined;
|
|
66
75
|
count++;
|
|
@@ -69,6 +78,12 @@ export default class RequestQueue {
|
|
|
69
78
|
return count;
|
|
70
79
|
}
|
|
71
80
|
|
|
81
|
+
public getRequestTasksIdByConnectId(connectId: string) {
|
|
82
|
+
return Array.from(this.requestQueue.values())
|
|
83
|
+
.filter(request => this.isRequestForConnectId(request, connectId))
|
|
84
|
+
.map(request => request.id);
|
|
85
|
+
}
|
|
86
|
+
|
|
72
87
|
// 取消所有请求
|
|
73
88
|
public abortAllRequests() {
|
|
74
89
|
let count = 0;
|
package/src/core/index.ts
CHANGED
|
@@ -1333,7 +1333,7 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1333
1333
|
// cancel callback tasks
|
|
1334
1334
|
requestQueue.cancelCallbackTasks(connectId);
|
|
1335
1335
|
|
|
1336
|
-
const requestIds = requestQueue.
|
|
1336
|
+
const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
|
|
1337
1337
|
Log.debug(
|
|
1338
1338
|
`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(
|
|
1339
1339
|
','
|
|
@@ -1341,10 +1341,9 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1341
1341
|
);
|
|
1342
1342
|
// Abort before rejecting: rejectRequest releases the task and would make
|
|
1343
1343
|
// its AbortController unreachable to an in-flight method loop.
|
|
1344
|
-
//
|
|
1345
|
-
//
|
|
1346
|
-
|
|
1347
|
-
requestQueue.abortAllRequests();
|
|
1344
|
+
// Match both the requested connectId and a device selected internally by the
|
|
1345
|
+
// method, such as Desktop WebUSB firmwareUpdateV4.
|
|
1346
|
+
requestQueue.abortRequestsByConnectId(connectId);
|
|
1348
1347
|
const canceledDevices: Device[] = [];
|
|
1349
1348
|
const interruptDevice = (device: Device | undefined, deviceConnectId: string) => {
|
|
1350
1349
|
if (!device || canceledDevices.includes(device)) {
|
|
@@ -1360,7 +1359,7 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1360
1359
|
// During ensureConnected the method has a connectId but device is
|
|
1361
1360
|
// assigned only after the poll succeeds. Interrupt the cached BLE
|
|
1362
1361
|
// Device so an in-flight acquire/initialize cannot finish.
|
|
1363
|
-
interruptDevice(task.method?.device,
|
|
1362
|
+
interruptDevice(task.method?.device, connectId);
|
|
1364
1363
|
interruptDevice(deviceCacheMap.get(connectId), connectId);
|
|
1365
1364
|
requestQueue.rejectRequest(
|
|
1366
1365
|
requestId,
|
|
@@ -1421,8 +1420,10 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1421
1420
|
}
|
|
1422
1421
|
}
|
|
1423
1422
|
|
|
1424
|
-
cleanup();
|
|
1425
|
-
|
|
1423
|
+
cleanup(connectId);
|
|
1424
|
+
if (!connectId || _uiPromises.length === 0) {
|
|
1425
|
+
closePopup();
|
|
1426
|
+
}
|
|
1426
1427
|
};
|
|
1427
1428
|
|
|
1428
1429
|
const checkPassphraseEnableState = (method: BaseMethod, features?: Features) => {
|
|
@@ -1460,9 +1461,16 @@ const shouldCheckPassphraseState = (method: BaseMethod, device: Device) => {
|
|
|
1460
1461
|
return device.hasUsePassphrase();
|
|
1461
1462
|
};
|
|
1462
1463
|
|
|
1463
|
-
const cleanup = () => {
|
|
1464
|
-
const pendingUiPromises =
|
|
1465
|
-
|
|
1464
|
+
const cleanup = (connectId?: string) => {
|
|
1465
|
+
const pendingUiPromises = connectId
|
|
1466
|
+
? _uiPromises.filter(
|
|
1467
|
+
uiPromise =>
|
|
1468
|
+
uiPromise.data?.mainId === connectId || uiPromise.data?.getConnectId() === connectId
|
|
1469
|
+
)
|
|
1470
|
+
: _uiPromises;
|
|
1471
|
+
_uiPromises = connectId
|
|
1472
|
+
? _uiPromises.filter(uiPromise => !pendingUiPromises.includes(uiPromise))
|
|
1473
|
+
: [];
|
|
1466
1474
|
rejectUiPromises(
|
|
1467
1475
|
pendingUiPromises,
|
|
1468
1476
|
ERRORS.TypedError(HardwareErrorCode.ActionCancelled, 'UI request was cancelled')
|
|
@@ -273,6 +273,10 @@ export async function getProtocolV2WalletSession(
|
|
|
273
273
|
const markWalletStatusRefreshed = () => {
|
|
274
274
|
walletStatusRefreshed = true;
|
|
275
275
|
};
|
|
276
|
+
if (options?.onlyMainPin && options.mainPinSelected !== true) {
|
|
277
|
+
await refreshProtocolV2DeviceStatus(device);
|
|
278
|
+
markWalletStatusRefreshed();
|
|
279
|
+
}
|
|
276
280
|
let mainPinAuthenticated =
|
|
277
281
|
options?.mainPinSelected === true ||
|
|
278
282
|
(options?.onlyMainPin === true &&
|