@onekeyfe/hd-core 1.1.4-alpha.2 → 1.1.4-alpha.3

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.
Files changed (64) hide show
  1. package/dist/api/BaseMethod.d.ts +2 -0
  2. package/dist/api/BaseMethod.d.ts.map +1 -1
  3. package/dist/api/allnetwork/AllNetworkGetAddress.d.ts +4 -28
  4. package/dist/api/allnetwork/AllNetworkGetAddress.d.ts.map +1 -1
  5. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +47 -0
  6. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -0
  7. package/dist/api/allnetwork/AllNetworkGetAddressByLoop.d.ts +8 -0
  8. package/dist/api/allnetwork/AllNetworkGetAddressByLoop.d.ts.map +1 -0
  9. package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
  10. package/dist/api/cosmos/CosmosGetPublicKey.d.ts +1 -1
  11. package/dist/api/cosmos/CosmosGetPublicKey.d.ts.map +1 -1
  12. package/dist/api/device/DeviceUnlock.d.ts +0 -2
  13. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  14. package/dist/api/evm/EVMGetPublicKey.d.ts +1 -0
  15. package/dist/api/evm/EVMGetPublicKey.d.ts.map +1 -1
  16. package/dist/api/index.d.ts +1 -0
  17. package/dist/api/index.d.ts.map +1 -1
  18. package/dist/core/RequestQueue.d.ts +4 -0
  19. package/dist/core/RequestQueue.d.ts.map +1 -1
  20. package/dist/core/index.d.ts +3 -2
  21. package/dist/core/index.d.ts.map +1 -1
  22. package/dist/device/Device.d.ts +4 -1
  23. package/dist/device/Device.d.ts.map +1 -1
  24. package/dist/events/call.d.ts +9 -0
  25. package/dist/events/call.d.ts.map +1 -1
  26. package/dist/events/core.d.ts +2 -2
  27. package/dist/events/core.d.ts.map +1 -1
  28. package/dist/events/iframe.d.ts +11 -1
  29. package/dist/events/iframe.d.ts.map +1 -1
  30. package/dist/index.d.ts +41 -11
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +408 -195
  33. package/dist/inject.d.ts +3 -0
  34. package/dist/inject.d.ts.map +1 -1
  35. package/dist/types/api/allNetworkGetAddress.d.ts +12 -3
  36. package/dist/types/api/allNetworkGetAddress.d.ts.map +1 -1
  37. package/dist/types/api/evmGetPublicKey.d.ts +1 -0
  38. package/dist/types/api/evmGetPublicKey.d.ts.map +1 -1
  39. package/dist/types/api/index.d.ts +2 -1
  40. package/dist/types/api/index.d.ts.map +1 -1
  41. package/dist/utils/findDefectiveBatchDevice.d.ts +0 -5
  42. package/dist/utils/findDefectiveBatchDevice.d.ts.map +1 -1
  43. package/package.json +4 -4
  44. package/src/api/BaseMethod.ts +3 -0
  45. package/src/api/allnetwork/AllNetworkGetAddress.ts +19 -408
  46. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +480 -0
  47. package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +161 -0
  48. package/src/api/btc/BTCGetPublicKey.ts +13 -0
  49. package/src/api/cosmos/CosmosGetPublicKey.ts +1 -1
  50. package/src/api/device/DeviceUnlock.ts +1 -48
  51. package/src/api/evm/EVMGetPublicKey.ts +9 -3
  52. package/src/api/index.ts +1 -0
  53. package/src/core/RequestQueue.ts +26 -0
  54. package/src/core/index.ts +42 -82
  55. package/src/device/Device.ts +66 -0
  56. package/src/events/call.ts +10 -0
  57. package/src/events/core.ts +7 -1
  58. package/src/events/iframe.ts +12 -1
  59. package/src/index.ts +2 -1
  60. package/src/inject.ts +47 -0
  61. package/src/types/api/allNetworkGetAddress.ts +17 -3
  62. package/src/types/api/evmGetPublicKey.ts +1 -0
  63. package/src/types/api/index.ts +2 -1
  64. package/src/utils/findDefectiveBatchDevice.ts +0 -29
@@ -0,0 +1,480 @@
1
+ import semver from 'semver';
2
+ import {
3
+ ERRORS,
4
+ HardwareError,
5
+ HardwareErrorCode,
6
+ HardwareErrorCodeMessage,
7
+ } from '@onekeyfe/hd-shared';
8
+
9
+ import { serializedPath, toHardened } from '../helpers/pathUtils';
10
+ import { BaseMethod } from '../BaseMethod';
11
+ import { validateParams } from '../helpers/paramsValidator';
12
+ import { CoreApi } from '../../types';
13
+ import type {
14
+ AllNetworkAddressParams,
15
+ INetwork,
16
+ AllNetworkAddress,
17
+ CommonResponseParams,
18
+ } from '../../types/api/allNetworkGetAddress';
19
+ import { PROTO } from '../../constants';
20
+
21
+ import { findMethod } from '../utils';
22
+ import { createUiMessage, DEVICE, IFRAME } from '../../events';
23
+ import { getDeviceFirmwareVersion, getMethodVersionRange } from '../../utils';
24
+ import { Device, DeviceEvents } from '../../device/Device';
25
+ import { UI_REQUEST } from '../../constants/ui-request';
26
+ import { onDeviceButtonHandler } from '../../core';
27
+ import { DevicePool } from '../../device/DevicePool';
28
+
29
+ const Mainnet = 'mainnet';
30
+
31
+ export type NetworkConfig = {
32
+ methodName: keyof CoreApi;
33
+ getParams?: (baseParams: AllNetworkAddressParams, chainName?: string, methodName?: string) => any;
34
+ dependOnMethodName?: (keyof CoreApi)[];
35
+ };
36
+
37
+ export type INetworkReal = Exclude<INetwork, 'tbtc' | 'bch' | 'doge' | 'ltc' | 'neurai'>;
38
+
39
+ export type NetworkConfigMap = {
40
+ [K in INetworkReal]: NetworkConfig;
41
+ };
42
+
43
+ export const networkAliases: {
44
+ [key: string]: { name: INetworkReal; coin: string };
45
+ } = {
46
+ tbtc: { name: 'btc', coin: 'Testnet' },
47
+ bch: { name: 'btc', coin: 'Bcash' },
48
+ doge: { name: 'btc', coin: 'Dogecoin' },
49
+ ltc: { name: 'btc', coin: 'Litecoin' },
50
+ neurai: { name: 'btc', coin: 'Neurai' },
51
+ };
52
+
53
+ const networkConfigMap: NetworkConfigMap = {
54
+ btc: {
55
+ methodName: 'btcGetPublicKey',
56
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => ({
57
+ coin: chainName,
58
+ ...baseParams,
59
+ }),
60
+ },
61
+ evm: {
62
+ methodName: 'evmGetAddress',
63
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
64
+ const { path, showOnOneKey } = baseParams;
65
+ let chainId;
66
+ if (chainName) {
67
+ chainId = parseInt(chainName);
68
+ }
69
+ return {
70
+ chainId,
71
+ path,
72
+ showOnOneKey,
73
+ };
74
+ },
75
+ },
76
+ sol: {
77
+ methodName: 'solGetAddress',
78
+ },
79
+ algo: {
80
+ methodName: 'algoGetAddress',
81
+ },
82
+ near: {
83
+ methodName: 'nearGetAddress',
84
+ },
85
+ stc: {
86
+ methodName: 'starcoinGetAddress',
87
+ },
88
+ cfx: {
89
+ methodName: 'confluxGetAddress',
90
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
91
+ const { path, showOnOneKey } = baseParams;
92
+ return {
93
+ chainId: parseInt(chainName ?? '1029'),
94
+ path,
95
+ showOnOneKey,
96
+ };
97
+ },
98
+ },
99
+ tron: {
100
+ methodName: 'tronGetAddress',
101
+ },
102
+ aptos: {
103
+ methodName: 'aptosGetAddress',
104
+ },
105
+ xrp: {
106
+ methodName: 'xrpGetAddress',
107
+ },
108
+ cosmos: {
109
+ methodName: 'cosmosGetPublicKey',
110
+ getParams: (baseParams: AllNetworkAddressParams) => {
111
+ const { path, prefix, showOnOneKey } = baseParams;
112
+ return {
113
+ hrp: prefix,
114
+ path,
115
+ showOnOneKey,
116
+ };
117
+ },
118
+ },
119
+ ada: {
120
+ methodName: 'cardanoGetAddress',
121
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
122
+ const { path, showOnOneKey } = baseParams;
123
+
124
+ const addressPath =
125
+ typeof path === 'string' ? `${path}/0/0` : serializedPath([...path, 0, 0]);
126
+ const stakingPath =
127
+ typeof path === 'string' ? `${path}/2/0` : serializedPath([...path, 2, 0]);
128
+
129
+ let networkId = 1;
130
+ if (chainName) {
131
+ networkId = chainName === Mainnet ? 1 : 0;
132
+ }
133
+
134
+ return {
135
+ addressParameters: {
136
+ addressType: PROTO.CardanoAddressType.BASE,
137
+ path: addressPath,
138
+ stakingPath,
139
+ },
140
+ protocolMagic: 764824073,
141
+ networkId,
142
+ derivationType: PROTO.CardanoDerivationType.ICARUS,
143
+ showOnOneKey,
144
+ address: '',
145
+ isCheck: false,
146
+ };
147
+ },
148
+ },
149
+ sui: {
150
+ methodName: 'suiGetAddress',
151
+ },
152
+ benfen: {
153
+ methodName: 'benfenGetAddress',
154
+ },
155
+ fil: {
156
+ methodName: 'filecoinGetAddress',
157
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
158
+ const { path, showOnOneKey } = baseParams;
159
+ let isTestnet = false;
160
+ if (chainName) {
161
+ isTestnet = chainName !== Mainnet;
162
+ }
163
+ return {
164
+ isTestnet,
165
+ path,
166
+ showOnOneKey,
167
+ };
168
+ },
169
+ },
170
+ dot: {
171
+ methodName: 'polkadotGetAddress',
172
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
173
+ const { path, prefix, showOnOneKey } = baseParams;
174
+ if (!prefix || !chainName) {
175
+ throw new Error('Invalid params');
176
+ }
177
+ return {
178
+ prefix: parseInt(prefix),
179
+ network: chainName,
180
+ path,
181
+ showOnOneKey,
182
+ };
183
+ },
184
+ },
185
+ kaspa: {
186
+ methodName: 'kaspaGetAddress',
187
+ getParams: (baseParams: AllNetworkAddressParams) => {
188
+ const { path, prefix, showOnOneKey, useTweak } = baseParams;
189
+ return {
190
+ scheme: 'schnorr',
191
+ prefix,
192
+ path,
193
+ showOnOneKey,
194
+ useTweak,
195
+ };
196
+ },
197
+ },
198
+ nexa: {
199
+ methodName: 'nexaGetAddress',
200
+ getParams: (baseParams: AllNetworkAddressParams) => {
201
+ const { path, prefix, showOnOneKey } = baseParams;
202
+ return {
203
+ scheme: 'Schnorr',
204
+ prefix,
205
+ path,
206
+ showOnOneKey,
207
+ };
208
+ },
209
+ },
210
+ dynex: {
211
+ methodName: 'dnxGetAddress',
212
+ },
213
+ nervos: {
214
+ methodName: 'nervosGetAddress',
215
+ getParams: (baseParams: AllNetworkAddressParams, chainName?: string) => {
216
+ const { path, showOnOneKey } = baseParams;
217
+ return {
218
+ network: chainName,
219
+ path,
220
+ showOnOneKey,
221
+ };
222
+ },
223
+ },
224
+ scdo: {
225
+ methodName: 'scdoGetAddress',
226
+ },
227
+ ton: {
228
+ methodName: 'tonGetAddress',
229
+ },
230
+ alph: {
231
+ methodName: 'alephiumGetAddress',
232
+ },
233
+ nostr: {
234
+ methodName: 'nostrGetPublicKey',
235
+ },
236
+ neo: {
237
+ methodName: 'neoGetAddress',
238
+ },
239
+ };
240
+
241
+ type MethodParams = {
242
+ methodName: keyof CoreApi;
243
+ params: Parameters<CoreApi[keyof CoreApi]>[0];
244
+ _originRequestParams: AllNetworkAddressParams;
245
+ _originalIndex: number;
246
+ };
247
+
248
+ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
249
+ {
250
+ address_n: number[];
251
+ show_display: boolean;
252
+ network: string;
253
+ chain_name?: string;
254
+ }[]
255
+ > {
256
+ abortController: AbortController | null = null;
257
+
258
+ init() {
259
+ this.checkDeviceId = true;
260
+ this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
261
+
262
+ // check payload
263
+ validateParams(this.payload, [{ name: 'bundle', type: 'array' }]);
264
+
265
+ // check bundle
266
+ this.payload?.bundle?.forEach((batch: AllNetworkAddressParams) => {
267
+ validateParams(batch, [
268
+ { name: 'path', required: true },
269
+ { name: 'network', type: 'string', required: true },
270
+ { name: 'chainName', type: 'string' },
271
+ { name: 'showOnOneKey', type: 'boolean' },
272
+ ]);
273
+ });
274
+ }
275
+
276
+ generateMethodName({
277
+ network,
278
+ payload,
279
+ originalIndex,
280
+ }: {
281
+ network: INetwork;
282
+ payload: AllNetworkAddressParams;
283
+ originalIndex: number;
284
+ }): MethodParams {
285
+ const { name: networkName, coin } = networkAliases[network] || {
286
+ name: network,
287
+ coin: payload?.chainName,
288
+ };
289
+ const config = networkConfigMap[networkName];
290
+ if (!config) {
291
+ throw new Error(`Unsupported network: ${network}`);
292
+ }
293
+
294
+ return {
295
+ methodName: config.methodName,
296
+ params: {
297
+ ...(config?.getParams?.(payload, coin, config.methodName) ?? payload),
298
+ originPayload: payload,
299
+ },
300
+ _originRequestParams: payload,
301
+ _originalIndex: originalIndex,
302
+ };
303
+ }
304
+
305
+ async callMethod(
306
+ methodName: keyof CoreApi,
307
+ params: any & {
308
+ bundle: (any & { _originRequestParams: CommonResponseParams })[];
309
+ },
310
+ rootFingerprint: number
311
+ ) {
312
+ const method: BaseMethod = findMethod({
313
+ event: IFRAME.CALL,
314
+ type: IFRAME.CALL,
315
+ payload: {
316
+ connectId: this.payload.connectId,
317
+ deviceId: this.payload.deviceId,
318
+ method: methodName,
319
+ ...params,
320
+ },
321
+ });
322
+
323
+ method.connector = this.connector;
324
+ method.postMessage = this.postMessage;
325
+
326
+ let result: AllNetworkAddress[];
327
+ try {
328
+ method.init();
329
+ method.setDevice?.(this.device);
330
+ method.context = this.context;
331
+
332
+ const onSignalAbort = () => {
333
+ this.abortController?.abort(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
334
+ };
335
+
336
+ const _onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
337
+ if (
338
+ request.code === 'ButtonRequest_PinEntry' ||
339
+ request.code === 'ButtonRequest_AttachPin'
340
+ ) {
341
+ onSignalAbort();
342
+ } else {
343
+ onDeviceButtonHandler(device, request);
344
+ }
345
+ };
346
+
347
+ // pro pin event
348
+ this.device.on(DEVICE.BUTTON, _onDeviceButtonHandler);
349
+ // classic pin event
350
+ this.device.on(DEVICE.PIN, onSignalAbort);
351
+ this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
352
+
353
+ preCheckDeviceSupport(this.device, method);
354
+
355
+ const response = await method.run();
356
+
357
+ if (!Array.isArray(response) || response.length === 0) {
358
+ throw new Error('No response');
359
+ }
360
+
361
+ result = response.map((item, index) => ({
362
+ ...params.bundle[index]._originRequestParams,
363
+ success: true,
364
+ payload: {
365
+ ...item,
366
+ rootFingerprint,
367
+ },
368
+ }));
369
+ } catch (e: any) {
370
+ const error = handleSkippableHardwareError(e, this.device, method);
371
+
372
+ if (error) {
373
+ result = params.bundle.map((item: { _originRequestParams: any }) => ({
374
+ ...item._originRequestParams,
375
+ success: false,
376
+ payload: {
377
+ error: error.message,
378
+ code: error.errorCode,
379
+ params: error.params,
380
+ connectId: method.connectId,
381
+ deviceId: method.deviceId,
382
+ },
383
+ }));
384
+ } else {
385
+ throw e;
386
+ }
387
+ }
388
+
389
+ return result;
390
+ }
391
+
392
+ abstract getAllNetworkAddress(rootFingerprint: number): Promise<AllNetworkAddress[]>;
393
+
394
+ async run() {
395
+ const res = await this.device.commands.typedCall('GetPublicKey', 'PublicKey', {
396
+ address_n: [toHardened(44), toHardened(1), toHardened(0)],
397
+ coin_name: 'Testnet',
398
+ script_type: 'SPENDADDRESS',
399
+ show_display: false,
400
+ });
401
+
402
+ this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
403
+
404
+ if (res.message.root_fingerprint == null) {
405
+ throw ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter);
406
+ }
407
+
408
+ this.abortController = new AbortController();
409
+
410
+ return this.getAllNetworkAddress(res.message.root_fingerprint).catch(e => {
411
+ if (e instanceof HardwareError && e.errorCode === HardwareErrorCode.RepeatUnlocking) {
412
+ throw ERRORS.TypedError(HardwareErrorCode.RepeatUnlocking, e.message);
413
+ }
414
+ throw e;
415
+ });
416
+ }
417
+ }
418
+
419
+ /**
420
+ * @experiment Check if the device supports the method
421
+ * @param device
422
+ * @param method BaseMethod
423
+ */
424
+ function preCheckDeviceSupport(device: Device, method: BaseMethod) {
425
+ const versionRange = getMethodVersionRange(
426
+ device.features,
427
+ type => method.getVersionRange()[type]
428
+ );
429
+ const currentVersion = getDeviceFirmwareVersion(device.features).join('.');
430
+
431
+ if (
432
+ versionRange &&
433
+ semver.valid(versionRange.min) &&
434
+ semver.lt(currentVersion, versionRange.min)
435
+ ) {
436
+ throw ERRORS.createNeedUpgradeFirmwareHardwareError(currentVersion, versionRange.min);
437
+ } else if (method.strictCheckDeviceSupport && !versionRange) {
438
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceNotSupportMethod);
439
+ }
440
+ }
441
+
442
+ function handleSkippableHardwareError(
443
+ e: any,
444
+ device: Device,
445
+ method: BaseMethod
446
+ ): HardwareError | undefined {
447
+ let error: HardwareError | undefined;
448
+
449
+ if (e instanceof HardwareError && e.errorCode !== HardwareErrorCode.RuntimeError) {
450
+ const { errorCode } = e;
451
+ if (errorCode === HardwareErrorCode.CallMethodNeedUpgradeFirmware) {
452
+ error = e;
453
+ } else if (errorCode === HardwareErrorCode.DeviceNotSupportMethod) {
454
+ error = e;
455
+ }
456
+ } else if (e.message?.includes('Failure_UnexpectedMessage')) {
457
+ const versionRange = getMethodVersionRange(
458
+ device.features,
459
+ type => method.getVersionRange()[type]
460
+ );
461
+ const currentVersion = getDeviceFirmwareVersion(device.features).join('.');
462
+
463
+ if (
464
+ versionRange &&
465
+ semver.valid(versionRange.min) &&
466
+ semver.lt(currentVersion, versionRange.min)
467
+ ) {
468
+ error = ERRORS.createNeedUpgradeFirmwareHardwareError(currentVersion, versionRange.min);
469
+ } else {
470
+ error = ERRORS.TypedError(HardwareErrorCode.DeviceNotSupportMethod, e.message);
471
+ }
472
+ } else if (
473
+ e.message?.toLowerCase()?.includes('forbidden key path') ||
474
+ e.message?.toLowerCase()?.includes('invalid path')
475
+ ) {
476
+ error = ERRORS.TypedError(HardwareErrorCode.CallMethodInvalidParameter, e.message);
477
+ }
478
+
479
+ return error;
480
+ }
@@ -0,0 +1,161 @@
1
+ import {
2
+ createDeferred,
3
+ ERRORS,
4
+ HardwareError,
5
+ HardwareErrorCode,
6
+ HardwareErrorCodeMessage,
7
+ } from '@onekeyfe/hd-shared';
8
+ import type {
9
+ AllNetworkAddress,
10
+ AllNetworkGetAddressParamsByLoop,
11
+ } from '../../types/api/allNetworkGetAddress';
12
+
13
+ import { IFRAME } from '../../events';
14
+ import AllNetworkGetAddressBase from './AllNetworkGetAddressBase';
15
+ import { Unsuccessful } from '../../types';
16
+
17
+ export default class AllNetworkGetAddressByLoop extends AllNetworkGetAddressBase {
18
+ async getAllNetworkAddress(rootFingerprint: number) {
19
+ const { callbackId, callbackIdFinish } = this.payload as AllNetworkGetAddressParamsByLoop;
20
+ if (!callbackId) {
21
+ throw new Error('callbackId is required');
22
+ }
23
+ if (!callbackIdFinish) {
24
+ throw new Error('callbackIdFinish is required');
25
+ }
26
+
27
+ const bundle = this.payload.bundle || [this.payload];
28
+
29
+ // process callbacks in background
30
+ const callbackPromise = this.processCallbacksInBackground(
31
+ bundle,
32
+ rootFingerprint,
33
+ callbackId,
34
+ callbackIdFinish
35
+ );
36
+ this.device.pendingCallbackPromise = createDeferred(callbackPromise);
37
+
38
+ // register to context for scheduling management
39
+ if (this.context && this.payload.connectId) {
40
+ this.context.registerCallbackTask(this.payload.connectId, this.device.pendingCallbackPromise);
41
+ }
42
+
43
+ // return empty array immediately
44
+ return Promise.resolve([]);
45
+ }
46
+
47
+ private async processCallbacksInBackground(
48
+ bundle: any[],
49
+ rootFingerprint: number,
50
+ callbackId: string,
51
+ callbackIdFinish: string
52
+ ): Promise<void> {
53
+ try {
54
+ const allResults: AllNetworkAddress[] = [];
55
+
56
+ for (let i = 0; i < bundle.length; i++) {
57
+ const item = bundle[i];
58
+
59
+ if (this.abortController?.signal.aborted) {
60
+ throw new Error(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
61
+ }
62
+
63
+ const methodParams = this.generateMethodName({
64
+ network: item.network,
65
+ payload: item,
66
+ originalIndex: i,
67
+ });
68
+
69
+ const singleMethodParams = {
70
+ bundle: [methodParams.params],
71
+ };
72
+
73
+ const response = await this.callMethod(
74
+ methodParams.methodName,
75
+ singleMethodParams,
76
+ rootFingerprint
77
+ );
78
+
79
+ if (this.abortController?.signal.aborted) {
80
+ throw new Error(HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]);
81
+ }
82
+
83
+ const singleResult = {
84
+ ...item,
85
+ ...response[0],
86
+ };
87
+ allResults.push(singleResult);
88
+
89
+ this.sendItemCallback(callbackId, singleResult, i);
90
+ }
91
+
92
+ this.sendFinishCallback({
93
+ callbackId: callbackIdFinish,
94
+ data: allResults,
95
+ });
96
+ } catch (error: any) {
97
+ let errorCode = error.errorCode || error.code;
98
+ let errorMessage = error.message;
99
+
100
+ if (error instanceof HardwareError) {
101
+ errorCode = error.errorCode;
102
+ errorMessage = error.message;
103
+ } else if (error.message === HardwareErrorCodeMessage[HardwareErrorCode.RepeatUnlocking]) {
104
+ errorCode = HardwareErrorCode.RepeatUnlocking;
105
+ errorMessage = error.message;
106
+ } else {
107
+ const hardwareError = ERRORS.TypedError(HardwareErrorCode.RuntimeError, error.message);
108
+ errorCode = hardwareError.errorCode;
109
+ errorMessage = hardwareError.message;
110
+ }
111
+
112
+ this.sendFinishCallback({
113
+ callbackId: callbackIdFinish,
114
+ error: {
115
+ success: false,
116
+ payload: {
117
+ error: errorMessage,
118
+ code: errorCode,
119
+ },
120
+ },
121
+ });
122
+ } finally {
123
+ this.context?.cancelCallbackTasks(this.payload.connectId);
124
+ this.abortController = null;
125
+ }
126
+ }
127
+
128
+ private sendFinishCallback({
129
+ callbackId,
130
+ data,
131
+ error,
132
+ }: {
133
+ callbackId: string;
134
+ data?: AllNetworkAddress[];
135
+ error?: Unsuccessful;
136
+ }) {
137
+ this.postMessage({
138
+ event: IFRAME.CALLBACK,
139
+ type: IFRAME.CALLBACK,
140
+ payload: {
141
+ callbackId,
142
+ data,
143
+ error,
144
+ },
145
+ });
146
+ }
147
+
148
+ private sendItemCallback(callbackId: string, data: any, itemIndex: number) {
149
+ this.postMessage({
150
+ event: IFRAME.CALLBACK,
151
+ type: IFRAME.CALLBACK,
152
+ payload: {
153
+ callbackId,
154
+ data: {
155
+ ...data,
156
+ index: itemIndex,
157
+ },
158
+ },
159
+ });
160
+ }
161
+ }
@@ -1,4 +1,5 @@
1
1
  import type { GetPublicKey } from '@onekeyfe/hd-transport';
2
+ import { HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
3
  import { UI_REQUEST } from '../../constants/ui-request';
3
4
  import { getScriptType, isTaprootPath, serializedPath, validatePath } from '../helpers/pathUtils';
4
5
  import { BaseMethod } from '../BaseMethod';
@@ -121,6 +122,18 @@ export default class BTCGetPublicKey extends BaseMethod<GetPublicKey[]> {
121
122
  });
122
123
  }
123
124
  } catch (error) {
125
+ if (error instanceof HardwareError) {
126
+ const { errorCode } = error;
127
+ if (
128
+ errorCode === HardwareErrorCode.PinCancelled ||
129
+ errorCode === HardwareErrorCode.ActionCancelled ||
130
+ errorCode === HardwareErrorCode.ResponseUnexpectTypeError ||
131
+ errorCode === HardwareErrorCode.PinInvalid
132
+ ) {
133
+ throw error;
134
+ }
135
+ }
136
+
124
137
  // clear responses
125
138
  responses = [];
126
139
 
@@ -2,7 +2,7 @@ import { UI_REQUEST } from '../../constants/ui-request';
2
2
  import { serializedPath, validatePath } from '../helpers/pathUtils';
3
3
  import { BaseMethod } from '../BaseMethod';
4
4
  import { validateParams, validateResult } from '../helpers/paramsValidator';
5
- import { CosmosAddress, CosmosGetPublicKeyParams } from '../../types';
5
+ import type { CosmosAddress, CosmosGetPublicKeyParams } from '../../types';
6
6
  import { batchGetPublickeys } from '../helpers/batchGetPublickeys';
7
7
 
8
8
  export default class CosmosGetPublicKey extends BaseMethod<any> {