@onekeyfe/hd-core 1.2.2-alpha.7 → 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 +129 -11
- 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 +37 -14
- 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 +10 -4
|
@@ -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 =
|
|
@@ -154,7 +160,7 @@ describe('openWalletSession', () => {
|
|
|
154
160
|
expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', standardSessionGet);
|
|
155
161
|
});
|
|
156
162
|
|
|
157
|
-
test('
|
|
163
|
+
test('opens the already-unlocked standard wallet without repeating Main PIN when passphrase is disabled', async () => {
|
|
158
164
|
const typedCall = jest.fn((request: string) => {
|
|
159
165
|
if (request === 'ProtocolInfoRequest') {
|
|
160
166
|
return { message: { version: 2 } };
|
|
@@ -173,11 +179,7 @@ describe('openWalletSession', () => {
|
|
|
173
179
|
|
|
174
180
|
await getProtocolV2WalletSession(device as any, { onlyMainPin: true });
|
|
175
181
|
|
|
176
|
-
expect(device.unlockDevice).
|
|
177
|
-
source: 'wallet-session-coordinator',
|
|
178
|
-
reason: 'open-wallet',
|
|
179
|
-
deviceOnly: true,
|
|
180
|
-
});
|
|
182
|
+
expect(device.unlockDevice).not.toHaveBeenCalled();
|
|
181
183
|
expect(typedCall).not.toHaveBeenCalledWith(
|
|
182
184
|
'DeviceSessionAskPassphrase',
|
|
183
185
|
'Success',
|
|
@@ -186,6 +188,106 @@ describe('openWalletSession', () => {
|
|
|
186
188
|
expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', standardSessionGet);
|
|
187
189
|
});
|
|
188
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
|
+
|
|
250
|
+
test('still requires Main PIN when a cached standard session resolves to another wallet', async () => {
|
|
251
|
+
let sessionGetCount = 0;
|
|
252
|
+
const typedCall = jest.fn((request: string) => {
|
|
253
|
+
if (request === 'ProtocolInfoRequest') {
|
|
254
|
+
return { message: { version: 2 } };
|
|
255
|
+
}
|
|
256
|
+
if (request === 'DeviceSessionGet') {
|
|
257
|
+
sessionGetCount += 1;
|
|
258
|
+
return {
|
|
259
|
+
message: {
|
|
260
|
+
btc_test_address:
|
|
261
|
+
sessionGetCount === 1 ? 'unexpected-wallet-state' : 'cached-standard-state',
|
|
262
|
+
session_id:
|
|
263
|
+
sessionGetCount === 1 ? 'unexpected-wallet-session' : 'cached-standard-session',
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
throw new Error(`Unexpected request: ${request}`);
|
|
268
|
+
});
|
|
269
|
+
const device = createDevice({ passphraseProtection: false, typedCall });
|
|
270
|
+
device.getStandardInternalState = jest.fn(() => ({
|
|
271
|
+
passphraseState: 'cached-standard-state',
|
|
272
|
+
sessionId: 'cached-standard-session',
|
|
273
|
+
}));
|
|
274
|
+
device.clearStandardInternalState = jest.fn();
|
|
275
|
+
|
|
276
|
+
await expect(
|
|
277
|
+
getProtocolV2WalletSession(device as any, { onlyMainPin: true })
|
|
278
|
+
).resolves.toMatchObject({
|
|
279
|
+
passphraseState: 'cached-standard-state',
|
|
280
|
+
newSession: 'cached-standard-session',
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
expect(device.unlockDevice).toHaveBeenCalledWith(DeviceSessionPinType.Main, {
|
|
284
|
+
source: 'wallet-session-coordinator',
|
|
285
|
+
reason: 'session-recovery',
|
|
286
|
+
deviceOnly: true,
|
|
287
|
+
});
|
|
288
|
+
expect(sessionGetCount).toBe(2);
|
|
289
|
+
});
|
|
290
|
+
|
|
189
291
|
test('reuses a Main PIN selected by the current preflight when passphrase is disabled', async () => {
|
|
190
292
|
const typedCall = jest.fn((request: string) => {
|
|
191
293
|
if (request === 'ProtocolInfoRequest') {
|
|
@@ -230,8 +332,7 @@ describe('openWalletSession', () => {
|
|
|
230
332
|
}
|
|
231
333
|
throw new Error(`Unexpected request: ${request}`);
|
|
232
334
|
});
|
|
233
|
-
const device = createDevice({ typedCall });
|
|
234
|
-
device.features.unlockedAttachPin = true;
|
|
335
|
+
const device = createDevice({ refreshedUnlockedAttachPin: true, typedCall });
|
|
235
336
|
|
|
236
337
|
await getProtocolV2WalletSession(device as any, { onlyMainPin: true });
|
|
237
338
|
|
|
@@ -1120,7 +1221,7 @@ describe('openWalletSession', () => {
|
|
|
1120
1221
|
payload: { method: 'openWalletSession', connectId: 'connect-id', mode: 'standard' },
|
|
1121
1222
|
});
|
|
1122
1223
|
method.init();
|
|
1123
|
-
const device = createDevice({ typedCall });
|
|
1224
|
+
const device = createDevice({ refreshedUnlocked: false, typedCall });
|
|
1124
1225
|
device.features.unlocked = false;
|
|
1125
1226
|
device.getDeviceState = jest
|
|
1126
1227
|
.fn()
|
|
@@ -1220,6 +1321,7 @@ describe('openWalletSession', () => {
|
|
|
1220
1321
|
});
|
|
1221
1322
|
|
|
1222
1323
|
test('switches from Attach PIN to Main PIN before opening the standard wallet', async () => {
|
|
1324
|
+
let attachPinSelected = true;
|
|
1223
1325
|
const typedCall = jest
|
|
1224
1326
|
.fn()
|
|
1225
1327
|
.mockResolvedValueOnce({ message: { version: 2 } })
|
|
@@ -1236,6 +1338,21 @@ describe('openWalletSession', () => {
|
|
|
1236
1338
|
method.init();
|
|
1237
1339
|
const device = createDevice({ typedCall });
|
|
1238
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
|
+
});
|
|
1239
1356
|
device.getDeviceState = jest
|
|
1240
1357
|
.fn()
|
|
1241
1358
|
.mockResolvedValueOnce({
|
|
@@ -1255,6 +1372,7 @@ describe('openWalletSession', () => {
|
|
|
1255
1372
|
},
|
|
1256
1373
|
});
|
|
1257
1374
|
device.unlockDevice = jest.fn().mockImplementation(() => {
|
|
1375
|
+
attachPinSelected = false;
|
|
1258
1376
|
device.features.unlockedAttachPin = false;
|
|
1259
1377
|
return Promise.resolve(device.features);
|
|
1260
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 &&
|
|
@@ -41981,7 +41985,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41981
41985
|
standardWalletSelected = true;
|
|
41982
41986
|
}
|
|
41983
41987
|
});
|
|
41984
|
-
const selectStandardWallet = () => __awaiter(this, void 0, void 0, function* () {
|
|
41988
|
+
const selectStandardWallet = (forceMainPin = false) => __awaiter(this, void 0, void 0, function* () {
|
|
41985
41989
|
var _q;
|
|
41986
41990
|
if (((_q = device.features) === null || _q === void 0 ? void 0 : _q.passphraseProtection) === true) {
|
|
41987
41991
|
yield selectMainPin();
|
|
@@ -41992,7 +41996,8 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
41992
41996
|
standardWalletSelected = true;
|
|
41993
41997
|
}
|
|
41994
41998
|
else if (!standardWalletSelected) {
|
|
41995
|
-
yield selectMainPin(
|
|
41999
|
+
yield selectMainPin(forceMainPin);
|
|
42000
|
+
standardWalletSelected = true;
|
|
41996
42001
|
}
|
|
41997
42002
|
});
|
|
41998
42003
|
if (readCurrentAttachPinSession) {
|
|
@@ -42091,7 +42096,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
42091
42096
|
}
|
|
42092
42097
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
42093
42098
|
(_h = device.clearStandardInternalState) === null || _h === void 0 ? void 0 : _h.call(device);
|
|
42094
|
-
yield selectStandardWallet();
|
|
42099
|
+
yield selectStandardWallet(true);
|
|
42095
42100
|
response = yield getDeviceSession(device, sessionGetRequest());
|
|
42096
42101
|
}
|
|
42097
42102
|
else {
|
|
@@ -65590,10 +65595,17 @@ class RequestQueue {
|
|
|
65590
65595
|
}
|
|
65591
65596
|
return false;
|
|
65592
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
|
+
}
|
|
65593
65605
|
abortRequestsByConnectId(connectId) {
|
|
65594
65606
|
let count = 0;
|
|
65595
65607
|
this.requestQueue.forEach((request, _) => {
|
|
65596
|
-
if (request.abortController && request
|
|
65608
|
+
if (request.abortController && this.isRequestForConnectId(request, connectId)) {
|
|
65597
65609
|
request.abortController.abort();
|
|
65598
65610
|
request.abortController = undefined;
|
|
65599
65611
|
count++;
|
|
@@ -65601,6 +65613,11 @@ class RequestQueue {
|
|
|
65601
65613
|
});
|
|
65602
65614
|
return count;
|
|
65603
65615
|
}
|
|
65616
|
+
getRequestTasksIdByConnectId(connectId) {
|
|
65617
|
+
return Array.from(this.requestQueue.values())
|
|
65618
|
+
.filter(request => this.isRequestForConnectId(request, connectId))
|
|
65619
|
+
.map(request => request.id);
|
|
65620
|
+
}
|
|
65604
65621
|
abortAllRequests() {
|
|
65605
65622
|
let count = 0;
|
|
65606
65623
|
this.requestQueue.forEach(request => {
|
|
@@ -66643,14 +66660,14 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
|
|
|
66643
66660
|
return poll();
|
|
66644
66661
|
});
|
|
66645
66662
|
const cancel = (context, connectId) => {
|
|
66646
|
-
var _a, _b
|
|
66663
|
+
var _a, _b;
|
|
66647
66664
|
const { requestQueue, setPrePendingCallPromise } = context;
|
|
66648
66665
|
if (connectId) {
|
|
66649
66666
|
try {
|
|
66650
66667
|
requestQueue.cancelCallbackTasks(connectId);
|
|
66651
|
-
const requestIds = requestQueue.
|
|
66668
|
+
const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
|
|
66652
66669
|
Log.debug(`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(',')}`);
|
|
66653
|
-
requestQueue.
|
|
66670
|
+
requestQueue.abortRequestsByConnectId(connectId);
|
|
66654
66671
|
const canceledDevices = [];
|
|
66655
66672
|
const interruptDevice = (device, deviceConnectId) => {
|
|
66656
66673
|
if (!device || canceledDevices.includes(device)) {
|
|
@@ -66663,7 +66680,7 @@ const cancel = (context, connectId) => {
|
|
|
66663
66680
|
const task = requestQueue.getTask(requestId);
|
|
66664
66681
|
Log.debug('Cancel Api connect task: ', task);
|
|
66665
66682
|
if (task) {
|
|
66666
|
-
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);
|
|
66667
66684
|
interruptDevice(deviceCacheMap.get(connectId), connectId);
|
|
66668
66685
|
requestQueue.rejectRequest(requestId, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled));
|
|
66669
66686
|
}
|
|
@@ -66692,7 +66709,7 @@ const cancel = (context, connectId) => {
|
|
|
66692
66709
|
const task = requestQueue.getTask(requestId);
|
|
66693
66710
|
Log.debug('Cancel Api connect task: ', task);
|
|
66694
66711
|
if (task) {
|
|
66695
|
-
interruptDevice((
|
|
66712
|
+
interruptDevice((_b = task.method) === null || _b === void 0 ? void 0 : _b.device);
|
|
66696
66713
|
if (task.method.connectId) {
|
|
66697
66714
|
interruptDevice(deviceCacheMap.get(task.method.connectId));
|
|
66698
66715
|
pollingManager.stop(task.method.connectId);
|
|
@@ -66715,8 +66732,10 @@ const cancel = (context, connectId) => {
|
|
|
66715
66732
|
});
|
|
66716
66733
|
}
|
|
66717
66734
|
}
|
|
66718
|
-
cleanup();
|
|
66719
|
-
|
|
66735
|
+
cleanup(connectId);
|
|
66736
|
+
if (!connectId || _uiPromises.length === 0) {
|
|
66737
|
+
closePopup();
|
|
66738
|
+
}
|
|
66720
66739
|
};
|
|
66721
66740
|
const checkPassphraseEnableState = (method, features) => {
|
|
66722
66741
|
if (!method.useDevicePassphraseState)
|
|
@@ -66746,9 +66765,13 @@ const shouldCheckPassphraseState = (method, device) => {
|
|
|
66746
66765
|
}
|
|
66747
66766
|
return device.hasUsePassphrase();
|
|
66748
66767
|
};
|
|
66749
|
-
const cleanup = () => {
|
|
66750
|
-
const pendingUiPromises =
|
|
66751
|
-
|
|
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
|
+
: [];
|
|
66752
66775
|
rejectUiPromises(pendingUiPromises, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, 'UI request was cancelled'));
|
|
66753
66776
|
};
|
|
66754
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 &&
|
|
@@ -371,7 +375,7 @@ export async function getProtocolV2WalletSession(
|
|
|
371
375
|
}
|
|
372
376
|
};
|
|
373
377
|
|
|
374
|
-
const selectStandardWallet = async () => {
|
|
378
|
+
const selectStandardWallet = async (forceMainPin = false) => {
|
|
375
379
|
if (device.features?.passphraseProtection === true) {
|
|
376
380
|
// Main PIN authenticates the device; an empty host passphrase selects the standard derivation.
|
|
377
381
|
await selectMainPin();
|
|
@@ -387,8 +391,10 @@ export async function getProtocolV2WalletSession(
|
|
|
387
391
|
standardWalletSelected = true;
|
|
388
392
|
} else if (!standardWalletSelected) {
|
|
389
393
|
// Without passphrase protection there is no empty-passphrase selector.
|
|
390
|
-
//
|
|
391
|
-
|
|
394
|
+
// An unlocked non-Attach-PIN device is already in the only available wallet context.
|
|
395
|
+
// Force Main PIN only when recovering from a mismatched cached standard session.
|
|
396
|
+
await selectMainPin(forceMainPin);
|
|
397
|
+
standardWalletSelected = true;
|
|
392
398
|
}
|
|
393
399
|
};
|
|
394
400
|
|
|
@@ -499,7 +505,7 @@ export async function getProtocolV2WalletSession(
|
|
|
499
505
|
}
|
|
500
506
|
if (options?.onlyMainPin) {
|
|
501
507
|
device.clearStandardInternalState?.();
|
|
502
|
-
await selectStandardWallet();
|
|
508
|
+
await selectStandardWallet(true);
|
|
503
509
|
response = await getDeviceSession(device, sessionGetRequest());
|
|
504
510
|
} else {
|
|
505
511
|
device.clearInternalState();
|