@onekeyfe/hd-core 1.1.4-alpha.1 → 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 (62) 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/device/DeviceCommands.d.ts +4 -4
  25. package/dist/events/call.d.ts +9 -0
  26. package/dist/events/call.d.ts.map +1 -1
  27. package/dist/events/core.d.ts +2 -2
  28. package/dist/events/core.d.ts.map +1 -1
  29. package/dist/events/iframe.d.ts +11 -1
  30. package/dist/events/iframe.d.ts.map +1 -1
  31. package/dist/index.d.ts +43 -13
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +400 -143
  34. package/dist/inject.d.ts +3 -0
  35. package/dist/inject.d.ts.map +1 -1
  36. package/dist/types/api/allNetworkGetAddress.d.ts +12 -3
  37. package/dist/types/api/allNetworkGetAddress.d.ts.map +1 -1
  38. package/dist/types/api/evmGetPublicKey.d.ts +1 -0
  39. package/dist/types/api/evmGetPublicKey.d.ts.map +1 -1
  40. package/dist/types/api/index.d.ts +2 -1
  41. package/dist/types/api/index.d.ts.map +1 -1
  42. package/package.json +4 -4
  43. package/src/api/BaseMethod.ts +3 -0
  44. package/src/api/allnetwork/AllNetworkGetAddress.ts +19 -408
  45. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +480 -0
  46. package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +161 -0
  47. package/src/api/btc/BTCGetPublicKey.ts +13 -0
  48. package/src/api/cosmos/CosmosGetPublicKey.ts +1 -1
  49. package/src/api/device/DeviceUnlock.ts +1 -48
  50. package/src/api/evm/EVMGetPublicKey.ts +9 -3
  51. package/src/api/index.ts +1 -0
  52. package/src/core/RequestQueue.ts +26 -0
  53. package/src/core/index.ts +30 -3
  54. package/src/device/Device.ts +66 -0
  55. package/src/events/call.ts +10 -0
  56. package/src/events/core.ts +7 -1
  57. package/src/events/iframe.ts +12 -1
  58. package/src/index.ts +2 -1
  59. package/src/inject.ts +47 -0
  60. package/src/types/api/allNetworkGetAddress.ts +17 -3
  61. package/src/types/api/evmGetPublicKey.ts +1 -0
  62. package/src/types/api/index.ts +2 -1
@@ -1,59 +1,12 @@
1
1
  import { LockDevice } from '@onekeyfe/hd-transport';
2
- import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
3
- import semver from 'semver';
4
2
  import { BaseMethod } from '../BaseMethod';
5
- import { toHardened } from '../helpers/pathUtils';
6
- import { DeviceFirmwareRange } from '../../types';
7
- import { getDeviceFirmwareVersion, getMethodVersionRange } from '../../utils';
8
3
 
9
4
  export default class DeviceUnlock extends BaseMethod<LockDevice> {
10
5
  init() {
11
6
  this.useDevicePassphraseState = false;
12
7
  }
13
8
 
14
- supportUnlockVersionRange(): DeviceFirmwareRange {
15
- return {
16
- pro: {
17
- min: '4.15.0',
18
- },
19
- };
20
- }
21
-
22
9
  async run() {
23
- const firmwareVersion = getDeviceFirmwareVersion(this.device.features)?.join('.');
24
- const versionRange = getMethodVersionRange(
25
- this.device.features,
26
- type => this.supportUnlockVersionRange()[type]
27
- );
28
-
29
- if (versionRange && semver.gte(firmwareVersion, versionRange.min)) {
30
- const res = await this.device.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
31
- if (this.device.features) {
32
- this.device.features.unlocked = res.message.unlocked == null ? null : res.message.unlocked;
33
- this.device.features.unlocked_attach_pin =
34
- res.message.unlocked_attach_pin == null ? undefined : res.message.unlocked_attach_pin;
35
- this.device.features.passphrase_protection =
36
- res.message.passphrase_protection == null ? null : res.message.passphrase_protection;
37
-
38
- return Promise.resolve(this.device.features);
39
- }
40
-
41
- const featuresRes = await this.device.commands.typedCall('GetFeatures', 'Features');
42
- return Promise.resolve(featuresRes.message);
43
- }
44
-
45
- const { type } = await this.device.commands.typedCall('GetAddress', 'Address', {
46
- address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
47
- coin_name: 'Testnet',
48
- script_type: 'SPENDADDRESS',
49
- show_display: false,
50
- });
51
-
52
- // @ts-expect-error
53
- if (type === 'CallMethodError') {
54
- throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Get the passphrase state error');
55
- }
56
- const res = await this.device.commands.typedCall('GetFeatures', 'Features');
57
- return Promise.resolve(res.message);
10
+ return this.device.unlockDevice();
58
11
  }
59
12
  }
@@ -13,6 +13,8 @@ import { batchGetPublickeys } from '../helpers/batchGetPublickeys';
13
13
  export default class EVMGetPublicKey extends BaseMethod<EthereumGetPublicKeyOneKey[]> {
14
14
  hasBundle = false;
15
15
 
16
+ confirmShowOnOneKey = false;
17
+
16
18
  useBatch = false;
17
19
 
18
20
  init() {
@@ -20,9 +22,13 @@ export default class EVMGetPublicKey extends BaseMethod<EthereumGetPublicKeyOneK
20
22
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
21
23
 
22
24
  this.hasBundle = !!this.payload?.bundle;
23
- this.useBatch = this.payload?.bundle?.every(
24
- (item: EVMGetPublicKeyParams) => item.showOnOneKey !== true
25
+
26
+ this.confirmShowOnOneKey = this.payload?.bundle?.some(
27
+ (item: EVMGetPublicKeyParams) => !!item.showOnOneKey
25
28
  );
29
+
30
+ this.useBatch = !this.confirmShowOnOneKey && this.hasBundle && this.payload.useBatch;
31
+
26
32
  const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };
27
33
 
28
34
  // check payload
@@ -66,7 +72,7 @@ export default class EVMGetPublicKey extends BaseMethod<EthereumGetPublicKeyOneK
66
72
  async run() {
67
73
  const responses: EVMPublicKey[] = [];
68
74
 
69
- if (this.useBatch && this.hasBundle && supportBatchPublicKey(this.device?.features)) {
75
+ if (this.useBatch && supportBatchPublicKey(this.device?.features)) {
70
76
  try {
71
77
  const res = await batchGetPublickeys(this.device, this.params, 'secp256k1', 60, {
72
78
  includeNode: false,
package/src/api/index.ts CHANGED
@@ -41,6 +41,7 @@ export { default as promptWebDeviceAccess } from './PromptWebDeviceAccess';
41
41
  export { default as cipherKeyValue } from './CipherKeyValue';
42
42
 
43
43
  export { default as allNetworkGetAddress } from './allnetwork/AllNetworkGetAddress';
44
+ export { default as allNetworkGetAddressByLoop } from './allnetwork/AllNetworkGetAddressByLoop';
44
45
 
45
46
  export { default as btcGetAddress } from './btc/BTCGetAddress';
46
47
  export { default as btcGetPublicKey } from './btc/BTCGetPublicKey';
@@ -13,6 +13,8 @@ export type RequestTask = {
13
13
  export default class RequestQueue {
14
14
  private requestQueue = new Map<number, RequestTask>();
15
15
 
16
+ private pendingCallbackTasks = new Map<string, Deferred<void>>();
17
+
16
18
  // 生成唯一请求ID
17
19
  public generateRequestId = (method?: BaseMethod) => {
18
20
  if (method && method.responseID != null) {
@@ -104,4 +106,28 @@ export default class RequestQueue {
104
106
  public releaseTask(requestId: number) {
105
107
  this.requestQueue.delete(requestId);
106
108
  }
109
+
110
+ public registerPendingCallbackTask(connectId: string, callbackPromise: Deferred<void>) {
111
+ this.pendingCallbackTasks.set(connectId, callbackPromise);
112
+
113
+ callbackPromise.promise.finally(() => {
114
+ Log.debug(`Callback task completed for connectId: ${connectId}`);
115
+ this.pendingCallbackTasks.delete(connectId);
116
+ });
117
+ }
118
+
119
+ public async waitForPendingCallbackTasks(connectId: string): Promise<void> {
120
+ const pendingTask = this.pendingCallbackTasks.get(connectId);
121
+ if (pendingTask) {
122
+ Log.debug(`Waiting for pending callback task to complete for connectId: ${connectId}`);
123
+ await pendingTask.promise;
124
+ }
125
+ }
126
+
127
+ public cancelCallbackTasks(connectId: string) {
128
+ const pendingTask = this.pendingCallbackTasks.get(connectId);
129
+ if (pendingTask) {
130
+ pendingTask.resolve();
131
+ }
132
+ }
107
133
  }
package/src/core/index.ts CHANGED
@@ -52,7 +52,7 @@ import { getSynchronize } from '../utils/getSynchronize';
52
52
 
53
53
  const Log = getLogger(LoggerNames.Core);
54
54
 
55
- type CoreContext = ReturnType<Core['getCoreContext']>;
55
+ export type CoreContext = ReturnType<Core['getCoreContext']>;
56
56
 
57
57
  function hasDeriveCardano(method: BaseMethod): boolean {
58
58
  if (
@@ -195,6 +195,11 @@ const onCallDevice = async (
195
195
  DevicePool.clearDeviceCache(method.payload.connectId);
196
196
  }
197
197
 
198
+ // wait for previous callback tasks to complete (ensure device does not call concurrently)
199
+ if (method.connectId) {
200
+ await context.waitForCallbackTasks(method.connectId);
201
+ }
202
+
198
203
  await waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
199
204
 
200
205
  const task = requestQueue.createTask(method);
@@ -225,6 +230,7 @@ const onCallDevice = async (
225
230
 
226
231
  Log.debug('Call API - setDevice: ', device.mainId);
227
232
  method.setDevice?.(device);
233
+ method.context = context;
228
234
 
229
235
  device.on(DEVICE.PIN, onDevicePinHandler);
230
236
  device.on(DEVICE.BUTTON, onDeviceButtonHandler);
@@ -240,6 +246,10 @@ const onCallDevice = async (
240
246
  );
241
247
 
242
248
  try {
249
+ if (method.connectId) {
250
+ await context.waitForCallbackTasks(method.connectId);
251
+ }
252
+
243
253
  await waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
244
254
 
245
255
  const inner = async (): Promise<void> => {
@@ -668,6 +678,7 @@ const ensureConnected = async (
668
678
  HardwareErrorCode.BleWriteCharacteristicError,
669
679
  HardwareErrorCode.BleAlreadyConnected,
670
680
  HardwareErrorCode.FirmwareUpdateLimitOneDevice,
681
+ HardwareErrorCode.SelectDevice,
671
682
  HardwareErrorCode.DeviceDetectInBootloaderMode,
672
683
  HardwareErrorCode.BleCharacteristicNotifyChangeFailure,
673
684
  HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission,
@@ -710,6 +721,10 @@ export const cancel = (context: CoreContext, connectId?: string) => {
710
721
  // }
711
722
  // setPrePendingCallPromise(device?.interruptionFromUser());
712
723
  // requestQueue.abortRequestsByConnectId(connectId);
724
+
725
+ // cancel callback tasks
726
+ requestQueue.cancelCallbackTasks(connectId);
727
+
713
728
  const requestIds = requestQueue.getRequestTasksId();
714
729
  Log.debug(
715
730
  `Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(
@@ -843,7 +858,7 @@ const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin
843
858
  callback(null, uiResp.payload);
844
859
  };
845
860
 
846
- const onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
861
+ export const onDeviceButtonHandler = (...[device, request]: [...DeviceEvents['button']]) => {
847
862
  postMessage(createDeviceMessage(DEVICE.BUTTON, { ...request, device: device.toMessageObject() }));
848
863
 
849
864
  if (request.code === 'ButtonRequest_PinEntry' || request.code === 'ButtonRequest_AttachPin') {
@@ -947,7 +962,7 @@ const removeUiPromise = (promise: Deferred<any>) => {
947
962
  export default class Core extends EventEmitter {
948
963
  private requestQueue = new RequestQueue();
949
964
 
950
- // 上一个请求的 promise 完成,后续需要清理的工作,需要在下一次请求前完成
965
+ // background task
951
966
  private prePendingCallPromise: Promise<void> | undefined;
952
967
 
953
968
  private methodSynchronize = getSynchronize();
@@ -960,6 +975,13 @@ export default class Core extends EventEmitter {
960
975
  setPrePendingCallPromise: (promise: Promise<void> | undefined) => {
961
976
  this.prePendingCallPromise = promise;
962
977
  },
978
+ // callback 任务管理
979
+ registerCallbackTask: (connectId: string, callbackPromise: Deferred<any>) => {
980
+ this.requestQueue.registerPendingCallbackTask(connectId, callbackPromise);
981
+ },
982
+ waitForCallbackTasks: (connectId: string) =>
983
+ this.requestQueue.waitForPendingCallbackTasks(connectId),
984
+ cancelCallbackTasks: (connectId: string) => this.requestQueue.cancelCallbackTasks(connectId),
963
985
  };
964
986
  }
965
987
 
@@ -1010,6 +1032,11 @@ export default class Core extends EventEmitter {
1010
1032
  cancel(this.getCoreContext(), message.payload.connectId);
1011
1033
  break;
1012
1034
  }
1035
+ case IFRAME.CALLBACK: {
1036
+ Log.log('callback message: ', message);
1037
+ postMessage(message);
1038
+ break;
1039
+ }
1013
1040
  default:
1014
1041
  break;
1015
1042
  }
@@ -1,4 +1,5 @@
1
1
  import EventEmitter from 'events';
2
+ import semver from 'semver';
2
3
  import { OneKeyDeviceInfo as DeviceDescriptor } from '@onekeyfe/hd-transport';
3
4
  import {
4
5
  createDeferred,
@@ -16,6 +17,7 @@ import {
16
17
  getDeviceType,
17
18
  getDeviceUUID,
18
19
  getLogger,
20
+ getMethodVersionRange,
19
21
  LoggerNames,
20
22
  } from '../utils';
21
23
  import {
@@ -28,6 +30,7 @@ import type DeviceConnector from './DeviceConnector';
28
30
  import { DeviceCommands, PassphrasePromptResponse } from './DeviceCommands';
29
31
 
30
32
  import {
33
+ type DeviceFirmwareRange,
31
34
  EOneKeyDeviceMode,
32
35
  type Device as DeviceTyped,
33
36
  type Features,
@@ -43,6 +46,7 @@ import {
43
46
  import { PROTO } from '../constants';
44
47
  import { DataManager } from '../data-manager';
45
48
  import TransportManager from '../data-manager/TransportManager';
49
+ import { toHardened } from '../api/helpers/pathUtils';
46
50
 
47
51
  export type InitOptions = {
48
52
  initSession?: boolean;
@@ -151,6 +155,8 @@ export class Device extends EventEmitter {
151
155
 
152
156
  passphraseState: string | undefined = undefined;
153
157
 
158
+ pendingCallbackPromise?: Deferred<void>;
159
+
154
160
  constructor(descriptor: DeviceDescriptor) {
155
161
  super();
156
162
  this.originalDescriptor = descriptor;
@@ -264,6 +270,18 @@ export class Device extends EventEmitter {
264
270
  (this.isUsedHere() && !this.keepSession && this.mainId) ||
265
271
  (this.mainId && DataManager.isBleConnect(env))
266
272
  ) {
273
+ // wait for callback tasks to complete before releasing device
274
+ if (this.pendingCallbackPromise) {
275
+ try {
276
+ Log.debug(
277
+ 'Waiting for callback tasks to complete before releasing device (in release method)'
278
+ );
279
+ await this.pendingCallbackPromise.promise;
280
+ } catch (error) {
281
+ Log.error('Error waiting for callback tasks in release method:', error);
282
+ }
283
+ }
284
+
267
285
  if (this.commands) {
268
286
  this.commands.dispose(false);
269
287
  if (this.commands.callPromise) {
@@ -732,6 +750,54 @@ export class Device extends EventEmitter {
732
750
  return res.message;
733
751
  }
734
752
 
753
+ supportUnlockVersionRange(): DeviceFirmwareRange {
754
+ return {
755
+ pro: {
756
+ min: '4.15.0',
757
+ },
758
+ };
759
+ }
760
+
761
+ async unlockDevice() {
762
+ const firmwareVersion = getDeviceFirmwareVersion(this.features)?.join('.');
763
+ const versionRange = getMethodVersionRange(
764
+ this.features,
765
+ type => this.supportUnlockVersionRange()[type]
766
+ );
767
+
768
+ if (versionRange && semver.gte(firmwareVersion, versionRange.min)) {
769
+ const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
770
+ if (this.features) {
771
+ this.features.unlocked = res.message.unlocked == null ? null : res.message.unlocked;
772
+ this.features.unlocked_attach_pin =
773
+ res.message.unlocked_attach_pin == null ? undefined : res.message.unlocked_attach_pin;
774
+ this.features.passphrase_protection =
775
+ res.message.passphrase_protection == null ? null : res.message.passphrase_protection;
776
+
777
+ return Promise.resolve(this.features);
778
+ }
779
+
780
+ const featuresRes = await this.commands.typedCall('GetFeatures', 'Features');
781
+ this._updateFeatures(featuresRes.message);
782
+ return Promise.resolve(featuresRes.message);
783
+ }
784
+
785
+ const { type } = await this.commands.typedCall('GetAddress', 'Address', {
786
+ address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
787
+ coin_name: 'Testnet',
788
+ script_type: 'SPENDADDRESS',
789
+ show_display: false,
790
+ });
791
+
792
+ // @ts-expect-error
793
+ if (type === 'CallMethodError') {
794
+ throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'unlock device error');
795
+ }
796
+ const res = await this.commands.typedCall('GetFeatures', 'Features');
797
+ this._updateFeatures(res.message);
798
+ return Promise.resolve(res.message);
799
+ }
800
+
735
801
  async checkPassphraseStateSafety(
736
802
  passphraseState?: string,
737
803
  useEmptyPassphrase?: boolean,
@@ -58,6 +58,16 @@ export interface IFrameSwitchTransportMessage {
58
58
  payload: { env: ConnectSettings['env'] };
59
59
  }
60
60
 
61
+ export interface IFrameCallbackMessage {
62
+ event: typeof IFRAME.CALLBACK;
63
+ type: typeof IFRAME.CALLBACK;
64
+ payload: {
65
+ callbackId: string;
66
+ data?: any;
67
+ error?: any;
68
+ };
69
+ }
70
+
61
71
  export const RESPONSE_EVENT = 'RESPONSE_EVENT';
62
72
 
63
73
  export interface MethodResponseMessage {
@@ -1,6 +1,11 @@
1
1
  import { HardwareError } from '@onekeyfe/hd-shared';
2
2
  import { Unsuccessful } from '../types/params';
3
- import { IFrameCallMessage, IFrameCancelMessage, IFrameSwitchTransportMessage } from './call';
3
+ import {
4
+ IFrameCallMessage,
5
+ IFrameCancelMessage,
6
+ IFrameSwitchTransportMessage,
7
+ IFrameCallbackMessage,
8
+ } from './call';
4
9
  import { DeviceEventMessage } from './device';
5
10
  import { IFrameEventMessage } from './iframe';
6
11
  import { UiEventMessage } from './ui-request';
@@ -18,6 +23,7 @@ export type CoreMessage = {
18
23
  | IFrameCallMessage
19
24
  | IFrameCancelMessage
20
25
  | IFrameSwitchTransportMessage
26
+ | IFrameCallbackMessage
21
27
  | UiResponseMessage
22
28
  | UiEventMessage
23
29
  | DeviceEventMessage
@@ -8,6 +8,7 @@ export const IFRAME = {
8
8
  CALL: 'iframe-call',
9
9
  CANCEL: 'iframe-cancel',
10
10
  SWITCH_TRANSPORT: 'iframe-switch-transport',
11
+ CALLBACK: 'iframe-callback',
11
12
  } as const;
12
13
 
13
14
  export interface IFrameInit {
@@ -29,7 +30,17 @@ export interface IFrameSwitchTransport {
29
30
  };
30
31
  }
31
32
 
32
- export type IFrameEvent = IFrameInit | IFrameBridge | IFrameSwitchTransport;
33
+ export interface IFrameCallback {
34
+ type: typeof IFRAME.CALLBACK;
35
+ payload: {
36
+ callbackId: string;
37
+ data?: any;
38
+ error?: any;
39
+ finished?: boolean;
40
+ };
41
+ }
42
+
43
+ export type IFrameEvent = IFrameInit | IFrameBridge | IFrameSwitchTransport | IFrameCallback;
33
44
  export type IFrameEventMessage = IFrameEvent & { event: typeof UI_EVENT };
34
45
 
35
46
  export const createIFrameMessage: MessageFactoryFn<typeof UI_EVENT, IFrameEvent> = (
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { inject, InjectApi } from './inject';
1
+ import { inject, InjectApi, executeCallback, cleanupCallback } from './inject';
2
2
  import { lowLevelInject, LowLevelInjectApi, LowLevelCoreApi } from './lowLevelInject';
3
3
  import { topLevelInject } from './topLevelInject';
4
4
  import { CoreApi } from './types/api';
@@ -14,6 +14,7 @@ export * from './data-manager';
14
14
  export * from './events';
15
15
  export * from './types';
16
16
  export { whitelist, whitelistExtension } from './data/config';
17
+ export { executeCallback, cleanupCallback };
17
18
 
18
19
  const HardwareSdk = ({
19
20
  init,
package/src/inject.ts CHANGED
@@ -1,6 +1,31 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { CallMethod } from './events';
3
3
  import { CoreApi } from './types/api';
4
+ import type { AllNetworkAddress } from './types/api/allNetworkGetAddress';
5
+
6
+ type CallbackFunction = (data?: any, error?: { message: string; code?: number }) => void;
7
+
8
+ const callbackManager = new Map<string, CallbackFunction>();
9
+
10
+ const generateCallbackId = () =>
11
+ `callback_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
12
+
13
+ const registerCallback = (id: string, callback: CallbackFunction) => {
14
+ callbackManager.set(id, callback);
15
+ };
16
+
17
+ const executeCallback = (id: string, ...args: any[]) => {
18
+ const callback = callbackManager.get(id);
19
+ if (callback) {
20
+ callback(...args);
21
+ }
22
+ };
23
+
24
+ const cleanupCallback = (id: string) => {
25
+ callbackManager.delete(id);
26
+ };
27
+
28
+ export { executeCallback, cleanupCallback };
4
29
 
5
30
  export interface InjectApi {
6
31
  call: CallMethod;
@@ -147,6 +172,28 @@ export const createCoreApi = (
147
172
 
148
173
  allNetworkGetAddress: (connectId, deviceId, params) =>
149
174
  call({ ...params, connectId, deviceId, method: 'allNetworkGetAddress' }),
175
+ allNetworkGetAddressByLoop: (connectId, deviceId, params) => {
176
+ const { onLoopItemResponse, onAllItemsResponse, ...restParams } = params;
177
+
178
+ const callbackId = generateCallbackId();
179
+ registerCallback(callbackId, onLoopItemResponse);
180
+
181
+ const callbackIdFinish = generateCallbackId();
182
+ registerCallback(callbackIdFinish, (data?: AllNetworkAddress[]) => {
183
+ onAllItemsResponse?.(data);
184
+ cleanupCallback(callbackIdFinish);
185
+ cleanupCallback(callbackId);
186
+ });
187
+
188
+ return call({
189
+ ...restParams,
190
+ connectId,
191
+ deviceId,
192
+ method: 'allNetworkGetAddressByLoop',
193
+ callbackId,
194
+ callbackIdFinish,
195
+ });
196
+ },
150
197
 
151
198
  evmGetAddress: (connectId, deviceId, params) =>
152
199
  call({ ...params, connectId, deviceId, method: 'evmGetAddress' }),
@@ -1,4 +1,4 @@
1
- import type { CommonParams, Response } from '../params';
1
+ import type { CommonParams, Response, Unsuccessful } from '../params';
2
2
  import type { CardanoAddressParameters } from './cardano';
3
3
 
4
4
  export type INetwork =
@@ -91,10 +91,10 @@ type AllNetworkAddressPayload =
91
91
  xpubSegwit: string;
92
92
  };
93
93
 
94
- export type AllNetworkAddress = CommonResponseParams & {
94
+ export type AllNetworkAddress = AllNetworkAddressParams & {
95
95
  success: boolean;
96
96
  payload?:
97
- | AllNetworkAddressPayload
97
+ | (AllNetworkAddressPayload & { rootFingerprint: number })
98
98
  | {
99
99
  error: string;
100
100
  code: number;
@@ -108,8 +108,22 @@ export type AllNetworkGetAddressParams = {
108
108
  bundle: AllNetworkAddressParams[];
109
109
  };
110
110
 
111
+ export type AllNetworkGetAddressParamsByLoop = AllNetworkGetAddressParams & {
112
+ callbackId?: string;
113
+ callbackIdFinish?: string;
114
+ onLoopItemResponse: (data?: AllNetworkAddress) => void;
115
+ onAllItemsResponse: (data?: AllNetworkAddress[], error?: Unsuccessful) => void;
116
+ };
117
+
111
118
  export declare function allNetworkGetAddress(
112
119
  connectId: string,
113
120
  deviceId: string,
114
121
  params: CommonParams & AllNetworkGetAddressParams
115
122
  ): Response<AllNetworkAddress[]>;
123
+
124
+ export declare function allNetworkGetAddressByLoop(
125
+ connectId: string,
126
+ deviceId: string,
127
+ params: CommonParams & AllNetworkGetAddressParamsByLoop
128
+ // only return empty array
129
+ ): Response<AllNetworkAddress[]>;
@@ -14,6 +14,7 @@ export type EVMGetPublicKeyParams = {
14
14
  path: string | number[];
15
15
  showOnOneKey?: boolean;
16
16
  chainId?: number;
17
+ useBatch?: boolean;
17
18
  };
18
19
 
19
20
  export declare function evmGetPublicKey(
@@ -43,7 +43,7 @@ import { setU2FCounter } from './setU2FCounter';
43
43
 
44
44
  import { cipherKeyValue } from './cipherKeyValue';
45
45
 
46
- import { allNetworkGetAddress } from './allNetworkGetAddress';
46
+ import { allNetworkGetAddress, allNetworkGetAddressByLoop } from './allNetworkGetAddress';
47
47
 
48
48
  import { evmGetAddress } from './evmGetAddress';
49
49
  import { evmGetPublicKey } from './evmGetPublicKey';
@@ -230,6 +230,7 @@ export type CoreApi = {
230
230
  * All network function
231
231
  */
232
232
  allNetworkGetAddress: typeof allNetworkGetAddress;
233
+ allNetworkGetAddressByLoop: typeof allNetworkGetAddressByLoop;
233
234
 
234
235
  /**
235
236
  * EVM function