@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.
@@ -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: true,
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: passphraseProtection,
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(5);
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
- 2
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;IAW9B,wBAAwB,CAAC,SAAS,EAAE,MAAM;IAa1C,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"}
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"}
@@ -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,SA0G9D,CAAC;AAuGF,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"}
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.method.connectId === connectId) {
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, _c;
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.getRequestTasksId();
66668
+ const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
66653
66669
  Log.debug(`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(',')}`);
66654
- requestQueue.abortAllRequests();
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, (_b = task.method.connectId) !== null && _b !== void 0 ? _b : connectId);
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((_c = task.method) === null || _c === void 0 ? void 0 : _c.device);
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
- closePopup();
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 = _uiPromises;
66752
- _uiPromises = [];
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;;;;;;GAyXF;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,MAAM,EACd,uBAAuB,EAAE,MAAM,EAC/B,aAAa,CAAC,EAAE,OAAO;;;;;;GAOxB"}
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.8",
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.8",
29
- "@onekeyfe/hd-transport": "1.2.2-alpha.8",
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": "7a5d129ea1db0b3eb230e309ab29ed3e9e7f141e"
49
+ "gitHead": "c097e98f32c451ccdda468da1195daf679e991e6"
50
50
  }
@@ -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.method.connectId === connectId) {
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.getRequestTasksId();
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
- // This branch rejects every queued request below. Abort the same set first so
1345
- // methods whose physical connectId is selected internally (for example
1346
- // Desktop WebUSB firmwareUpdateV4) cannot keep retrying after rejection.
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, task.method.connectId ?? connectId);
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
- closePopup();
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 = _uiPromises;
1465
- _uiPromises = [];
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 &&