@trezor/connect 9.4.1 → 9.4.2-beta.2

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 (61) hide show
  1. package/CHANGELOG.md +54 -9
  2. package/README.md +1 -1
  3. package/lib/api/bitcoin/inputs.js +1 -1
  4. package/lib/api/cardano/cardanoInputs.d.ts +7 -7
  5. package/lib/api/cardano/cardanoOutputs.d.ts +22 -22
  6. package/lib/api/cardano/cardanoTokenBundle.d.ts +5 -5
  7. package/lib/api/ethereum/api/ethereumSignTypedData.d.ts +56 -56
  8. package/lib/api/ethereum/ethereumDefinitions.d.ts +20 -20
  9. package/lib/backend/Blockchain.js +10 -3
  10. package/lib/constants/nem.d.ts +3 -3
  11. package/lib/core/index.js +25 -14
  12. package/lib/data/connectSettings.js +3 -0
  13. package/lib/data/deviceAuthenticityConfigTypes.d.ts +23 -23
  14. package/lib/data/version.d.ts +1 -1
  15. package/lib/data/version.js +1 -1
  16. package/lib/device/Device.d.ts +17 -13
  17. package/lib/device/Device.js +22 -16
  18. package/lib/device/DeviceCommands.d.ts +40 -10
  19. package/lib/device/DeviceCommands.js +25 -90
  20. package/lib/device/DeviceList.d.ts +5 -2
  21. package/lib/device/DeviceList.js +35 -11
  22. package/lib/device/prompts.d.ts +15 -0
  23. package/lib/device/prompts.js +63 -0
  24. package/lib/events/call.d.ts +4 -2
  25. package/lib/events/call.js +8 -1
  26. package/lib/events/core.js +1 -0
  27. package/lib/events/ui-response.d.ts +3 -3
  28. package/lib/index.js +2 -2
  29. package/lib/types/api/applySettings.d.ts +13 -13
  30. package/lib/types/api/authenticateDevice.d.ts +24 -24
  31. package/lib/types/api/authorizeCoinjoin.d.ts +9 -9
  32. package/lib/types/api/binance/index.d.ts +142 -142
  33. package/lib/types/api/bitcoin/index.d.ts +10 -10
  34. package/lib/types/api/cancelCoinjoinAuthorization.d.ts +1 -1
  35. package/lib/types/api/cardano/index.d.ts +507 -507
  36. package/lib/types/api/changeLanguage.d.ts +6 -6
  37. package/lib/types/api/cipherKeyValue.d.ts +7 -7
  38. package/lib/types/api/eos/index.d.ts +525 -525
  39. package/lib/types/api/ethereum/index.d.ts +100 -100
  40. package/lib/types/api/firmwareUpdate.d.ts +5 -5
  41. package/lib/types/api/getAccountDescriptor.d.ts +4 -4
  42. package/lib/types/api/getAddress.d.ts +32 -32
  43. package/lib/types/api/getOwnershipId.d.ts +24 -24
  44. package/lib/types/api/getOwnershipProof.d.ts +28 -28
  45. package/lib/types/api/getPublicKey.d.ts +23 -23
  46. package/lib/types/api/nem/index.d.ts +611 -611
  47. package/lib/types/api/nemGetAddress.d.ts +6 -6
  48. package/lib/types/api/pushTransaction.d.ts +3 -3
  49. package/lib/types/api/recoveryDevice.d.ts +9 -9
  50. package/lib/types/api/requestLogin.d.ts +25 -25
  51. package/lib/types/api/ripple/index.d.ts +21 -21
  52. package/lib/types/api/solana/index.d.ts +23 -23
  53. package/lib/types/api/stellar/index.d.ts +581 -581
  54. package/lib/types/api/tezos/index.d.ts +120 -120
  55. package/lib/types/api/unlockPath.d.ts +2 -2
  56. package/lib/types/coinInfo.d.ts +224 -224
  57. package/lib/types/fees.d.ts +19 -19
  58. package/lib/types/firmware.d.ts +1 -1
  59. package/lib/types/params.d.ts +24 -20
  60. package/lib/types/settings.d.ts +4 -0
  61. package/package.json +4 -4
@@ -1,38 +1,38 @@
1
1
  import { Static } from '@trezor/schema-utils';
2
2
  export type DeviceAuthenticityConfig = Static<typeof DeviceAuthenticityConfig>;
3
- export declare const DeviceAuthenticityConfig: import("@sinclair/typebox/build/esm/index.mjs").TIntersect<[import("@sinclair/typebox/build/esm/index.mjs").TIntersect<[import("@trezor/schema-utils").TObject<{
4
- T2B1: import("@sinclair/typebox/build/esm/index.mjs").TIntersect<[import("@trezor/schema-utils").TObject<{
5
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
6
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
3
+ export declare const DeviceAuthenticityConfig: import("@sinclair/typebox").TIntersect<[import("@sinclair/typebox").TIntersect<[import("@trezor/schema-utils").TObject<{
4
+ T2B1: import("@sinclair/typebox").TIntersect<[import("@trezor/schema-utils").TObject<{
5
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
6
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
7
7
  }>, import("@trezor/schema-utils").TObject<{
8
- debug: import("@sinclair/typebox/build/esm/index.mjs").TOptional<import("@trezor/schema-utils").TObject<{
9
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
10
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
8
+ debug: import("@sinclair/typebox").TOptional<import("@trezor/schema-utils").TObject<{
9
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
10
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
11
11
  }>>;
12
12
  }>]>;
13
- T3B1: import("@sinclair/typebox/build/esm/index.mjs").TIntersect<[import("@trezor/schema-utils").TObject<{
14
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
15
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
13
+ T3B1: import("@sinclair/typebox").TIntersect<[import("@trezor/schema-utils").TObject<{
14
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
15
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
16
16
  }>, import("@trezor/schema-utils").TObject<{
17
- debug: import("@sinclair/typebox/build/esm/index.mjs").TOptional<import("@trezor/schema-utils").TObject<{
18
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
19
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
17
+ debug: import("@sinclair/typebox").TOptional<import("@trezor/schema-utils").TObject<{
18
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
19
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
20
20
  }>>;
21
21
  }>]>;
22
- T3T1: import("@sinclair/typebox/build/esm/index.mjs").TIntersect<[import("@trezor/schema-utils").TObject<{
23
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
24
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
22
+ T3T1: import("@sinclair/typebox").TIntersect<[import("@trezor/schema-utils").TObject<{
23
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
24
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
25
25
  }>, import("@trezor/schema-utils").TObject<{
26
- debug: import("@sinclair/typebox/build/esm/index.mjs").TOptional<import("@trezor/schema-utils").TObject<{
27
- rootPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
28
- caPubKeys: import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TString>;
26
+ debug: import("@sinclair/typebox").TOptional<import("@trezor/schema-utils").TObject<{
27
+ rootPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
28
+ caPubKeys: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
29
29
  }>>;
30
30
  }>]>;
31
31
  }>, import("@trezor/schema-utils").TObject<{
32
- T1B1: import("@sinclair/typebox/build/esm/index.mjs").TOptional<import("@sinclair/typebox/build/esm/index.mjs").TUndefined>;
33
- T2T1: import("@sinclair/typebox/build/esm/index.mjs").TOptional<import("@sinclair/typebox/build/esm/index.mjs").TUndefined>;
32
+ T1B1: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUndefined>;
33
+ T2T1: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUndefined>;
34
34
  }>]>, import("@trezor/schema-utils").TObject<{
35
- version: import("@sinclair/typebox/build/esm/index.mjs").TNumber;
36
- timestamp: import("@sinclair/typebox/build/esm/index.mjs").TString;
35
+ version: import("@sinclair/typebox").TNumber;
36
+ timestamp: import("@sinclair/typebox").TString;
37
37
  }>]>;
38
38
  //# sourceMappingURL=deviceAuthenticityConfigTypes.d.ts.map
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "9.4.1";
1
+ export declare const VERSION = "9.4.2-beta.2";
2
2
  export declare const DEFAULT_DOMAIN: string;
3
3
  export declare const CONTENT_SCRIPT_VERSION = 1;
4
4
  //# sourceMappingURL=version.d.ts.map
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CONTENT_SCRIPT_VERSION = exports.DEFAULT_DOMAIN = exports.VERSION = void 0;
4
- exports.VERSION = '9.4.1';
4
+ exports.VERSION = '9.4.2-beta.2';
5
5
  const versionN = exports.VERSION.split('.').map(s => parseInt(s, 10));
6
6
  const isBeta = exports.VERSION.includes('beta');
7
7
  exports.DEFAULT_DOMAIN = isBeta
@@ -1,11 +1,13 @@
1
1
  import { Deferred, TypedEmitter } from '@trezor/utils';
2
+ import { Session } from '@trezor/transport';
2
3
  import { TransportProtocol } from '@trezor/protocol';
3
- import { DeviceCommands, PassphrasePromptResponse } from './DeviceCommands';
4
+ import { DeviceCommands } from './DeviceCommands';
4
5
  import { PROTO, NETWORK } from '../constants';
5
- import { DEVICE, DeviceButtonRequestPayload } from '../events';
6
+ import { DEVICE, DeviceButtonRequestPayload, UiResponsePin, UiResponsePassphrase, UiResponseWord } from '../events';
6
7
  import { type Transport, type Descriptor } from '@trezor/transport';
7
8
  import { Device as DeviceTyped, DeviceFirmwareStatus, DeviceState, Features, ReleaseInfo, UnavailableCapabilities, FirmwareType, VersionArray, KnownDevice } from '../types';
8
9
  import { IStateStorage } from './StateStorage';
10
+ import type { PromptCallback } from './prompts';
9
11
  export type RunOptions = {
10
12
  skipFinalReload?: boolean;
11
13
  waiting?: boolean;
@@ -17,9 +19,9 @@ export type RunOptions = {
17
19
  export declare const GET_FEATURES_TIMEOUT = 3000;
18
20
  export declare const GET_FEATURES_TIMEOUT_REACT_NATIVE = 20000;
19
21
  export interface DeviceEvents {
20
- [DEVICE.PIN]: (device: Device, b: PROTO.PinMatrixRequestType | undefined, callback: (err: any, pin: string) => void) => void;
21
- [DEVICE.WORD]: (device: Device, b: PROTO.WordRequestType, callback: (err: any, word: string) => void) => void;
22
- [DEVICE.PASSPHRASE]: (device: Device, callback: (response: PassphrasePromptResponse) => void) => void;
22
+ [DEVICE.PIN]: (device: Device, type: PROTO.PinMatrixRequestType | undefined, callback: PromptCallback<UiResponsePin['payload']>) => void;
23
+ [DEVICE.WORD]: (device: Device, type: PROTO.WordRequestType, callback: PromptCallback<UiResponseWord['payload']>) => void;
24
+ [DEVICE.PASSPHRASE]: (device: Device, callback: PromptCallback<UiResponsePassphrase['payload']>) => void;
23
25
  [DEVICE.PASSPHRASE_ON_DEVICE]: () => void;
24
26
  [DEVICE.BUTTON]: (device: Device, payload: DeviceButtonRequestPayload) => void;
25
27
  [DEVICE.ACQUIRED]: () => void;
@@ -36,9 +38,10 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
36
38
  private acquirePromise?;
37
39
  private releasePromise?;
38
40
  private runPromise?;
39
- private transportSession?;
41
+ transportSession?: Session | null;
40
42
  keepTransportSession: boolean;
41
43
  commands?: DeviceCommands;
44
+ private cancelableAction?;
42
45
  loaded: boolean;
43
46
  inconsistent: boolean;
44
47
  firstRunPromise: Deferred<boolean>;
@@ -61,6 +64,8 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
61
64
  cleanup(): Promise<void>;
62
65
  run(fn?: () => Promise<void>, options?: RunOptions): Promise<void>;
63
66
  override(error: Error): Promise<void>;
67
+ setCancelableAction(callback: NonNullable<typeof this.cancelableAction>): void;
68
+ clearCancelableAction(): void;
64
69
  interruptionFromUser(error: Error): Promise<void>;
65
70
  interruptionFromOutside(): void;
66
71
  _runInner<X>(fn: (() => Promise<X>) | undefined, options: RunOptions): Promise<void>;
@@ -84,9 +89,9 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
84
89
  message: string;
85
90
  }>;
86
91
  private _uploadTranslationData;
87
- _updateFeatures(feat: Features): void;
92
+ private _updateFeatures;
88
93
  isUnacquired(): boolean;
89
- disconnect(): void;
94
+ disconnect(): Promise<void>;
90
95
  isBootloader(): boolean;
91
96
  isInitialized(): boolean;
92
97
  isSeedless(): boolean;
@@ -99,11 +104,14 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
99
104
  isRunning(): boolean;
100
105
  isLoaded(): boolean;
101
106
  waitForFirstRun(): Promise<boolean>;
102
- getDevicePath(): `${number}`;
107
+ getDevicePath(): import("@trezor/transport/lib/types").PathPublic;
103
108
  isT1(): boolean;
104
109
  hasUnexpectedMode(allow: string[], require: string[]): "ui-device_bootloader_mode" | "ui-device_not_in_bootloader_mode" | "ui-device_not_initialized" | "ui-device_seedless" | null;
105
110
  updateDescriptor(descriptor: Descriptor): void;
106
111
  dispose(): Promise<{
112
+ success: false;
113
+ error: "session not found";
114
+ } | {
107
115
  success: false;
108
116
  error: "Network request failed";
109
117
  } | {
@@ -115,9 +123,6 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
115
123
  } | {
116
124
  success: false;
117
125
  error: "unexpected error";
118
- } | {
119
- success: false;
120
- error: "session not found";
121
126
  } | {
122
127
  success: false;
123
128
  error: "Aborted by timeout";
@@ -139,6 +144,5 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
139
144
  } | import("@trezor/transport/lib/types").Success<void> | undefined>;
140
145
  getMode(): "normal" | "bootloader" | "initialize" | "seedless";
141
146
  toMessageObject(): DeviceTyped;
142
- legacyForceRelease(): Promise<void>;
143
147
  }
144
148
  //# sourceMappingURL=Device.d.ts.map
@@ -142,15 +142,27 @@ class Device extends utils_1.TypedEmitter {
142
142
  await this.releasePromise;
143
143
  }
144
144
  }
145
+ setCancelableAction(callback) {
146
+ this.cancelableAction = (e) => callback(e)
147
+ .catch(e => {
148
+ _log.debug('cancelableAction error', e);
149
+ })
150
+ .finally(() => {
151
+ this.clearCancelableAction();
152
+ });
153
+ }
154
+ clearCancelableAction() {
155
+ this.cancelableAction = undefined;
156
+ }
145
157
  async interruptionFromUser(error) {
158
+ var _a, _b;
146
159
  _log.debug('interruptionFromUser');
160
+ await ((_a = this.cancelableAction) === null || _a === void 0 ? void 0 : _a.call(this, error));
161
+ await ((_b = this.commands) === null || _b === void 0 ? void 0 : _b.cancel());
147
162
  if (this.runPromise) {
148
163
  this.runPromise.reject(error);
149
164
  delete this.runPromise;
150
165
  }
151
- if (this.commands) {
152
- await this.commands.cancel();
153
- }
154
166
  }
155
167
  interruptionFromOutside() {
156
168
  _log.debug('interruptionFromOutside');
@@ -161,7 +173,9 @@ class Device extends utils_1.TypedEmitter {
161
173
  this.runPromise.reject(constants_1.ERRORS.TypedError('Device_UsedElsewhere'));
162
174
  delete this.runPromise;
163
175
  }
164
- this.transport.releaseDevice(this.originalDescriptor.path);
176
+ if (this.originalDescriptor.session) {
177
+ this.transport.releaseDevice(this.originalDescriptor.session);
178
+ }
165
179
  }
166
180
  async _runInner(fn, options) {
167
181
  var _a, _b;
@@ -446,8 +460,7 @@ class Device extends utils_1.TypedEmitter {
446
460
  disconnect() {
447
461
  _log.debug('Disconnect cleanup');
448
462
  this.transportSession = null;
449
- this.interruptionFromUser(constants_1.ERRORS.TypedError('Device_Disconnected'));
450
- delete this.runPromise;
463
+ return this.interruptionFromUser(constants_1.ERRORS.TypedError('Device_Disconnected'));
451
464
  }
452
465
  isBootloader() {
453
466
  return this.features && !!this.features.bootloader_mode;
@@ -527,12 +540,12 @@ class Device extends utils_1.TypedEmitter {
527
540
  };
528
541
  }
529
542
  async dispose() {
543
+ var _a, _b;
530
544
  this.removeAllListeners();
531
545
  if (this.isUsedHere() && this.transportSession) {
532
546
  try {
533
- if (this.commands) {
534
- await this.commands.cancel();
535
- }
547
+ await ((_a = this.cancelableAction) === null || _a === void 0 ? void 0 : _a.call(this));
548
+ await ((_b = this.commands) === null || _b === void 0 ? void 0 : _b.cancel());
536
549
  return this.transport.release({
537
550
  session: this.transportSession,
538
551
  path: this.originalDescriptor.path,
@@ -596,13 +609,6 @@ class Device extends utils_1.TypedEmitter {
596
609
  authenticityChecks: this.authenticityChecks,
597
610
  };
598
611
  }
599
- async legacyForceRelease() {
600
- if (this.isUsedHere()) {
601
- await this.acquire();
602
- await this.getFeatures();
603
- await this.release();
604
- }
605
- }
606
612
  }
607
613
  exports.Device = Device;
608
614
  //# sourceMappingURL=Device.js.map
@@ -13,19 +13,12 @@ type TypedCallResponseMap = {
13
13
  [K in keyof MessageType]: TypedPayload<K>;
14
14
  };
15
15
  type DefaultPayloadMessage = TypedCallResponseMap[keyof MessageType];
16
- export type PassphrasePromptResponse = {
17
- passphrase?: string;
18
- passphraseOnDevice?: boolean;
19
- cache?: boolean;
20
- };
21
16
  export declare class DeviceCommands {
22
17
  device: Device;
23
18
  transport: Transport;
24
19
  transportSession: Session;
25
20
  disposed: boolean;
26
21
  callPromise?: ReturnType<Transport['call']>;
27
- _cancelableRequest?: (error?: any) => void;
28
- _cancelableRequestBySend?: boolean;
29
22
  constructor(device: Device, transport: Transport, transportSession: Session);
30
23
  dispose(): void;
31
24
  isDisposed(): boolean;
@@ -78,15 +71,52 @@ export declare class DeviceCommands {
78
71
  _commonCall(type: MessageKey, msg?: DefaultPayloadMessage['message']): Promise<DefaultPayloadMessage>;
79
72
  _filterCommonTypes(res: DefaultPayloadMessage): Promise<DefaultPayloadMessage>;
80
73
  private _getAddress;
81
- _promptPin(type?: Messages.PinMatrixRequestType): Promise<string>;
82
- _promptPassphrase(): Promise<PassphrasePromptResponse>;
83
- _promptWord(type: Messages.WordRequestType): Promise<string>;
84
74
  getAccountDescriptor(coinInfo: CoinInfo, indexOrPath: number | number[], derivationType?: Messages.CardanoDerivationType): Promise<{
85
75
  descriptor: string;
86
76
  legacyXpub?: string;
87
77
  address_n: number[];
88
78
  descriptorChecksum?: string;
89
79
  }>;
80
+ cancelWithFallback(): Promise<{
81
+ readonly success: false;
82
+ readonly error: "session not found";
83
+ } | import("@trezor/transport/lib/types").Success<import("@trezor/protobuf").MessageFromTrezor> | {
84
+ success: false;
85
+ error: "Network request failed";
86
+ } | {
87
+ success: false;
88
+ error: "Wrong result type.";
89
+ } | {
90
+ success: false;
91
+ error: "other call in progress";
92
+ } | {
93
+ success: false;
94
+ error: "Malformed protocol format";
95
+ } | {
96
+ success: false;
97
+ error: "device disconnected during action";
98
+ } | {
99
+ success: false;
100
+ error: "unexpected error";
101
+ } | {
102
+ success: false;
103
+ error: "Aborted by timeout";
104
+ } | {
105
+ success: false;
106
+ error: "Aborted by signal";
107
+ } | {
108
+ success: false;
109
+ error: "This transport can not be used in this environment";
110
+ } | {
111
+ success: false;
112
+ error: "device not found";
113
+ } | {
114
+ success: false;
115
+ error: "Unable to open device";
116
+ } | {
117
+ success: false;
118
+ error: "A transfer error has occurred.";
119
+ } | import("@trezor/transport/lib/types").Success<undefined> | undefined>;
90
120
  cancel(): Promise<void>;
91
121
  }
92
122
  export type TypedCall = DeviceCommands['typedCall'];
@@ -14,6 +14,7 @@ const coinInfo_1 = require("../data/coinInfo");
14
14
  const debug_1 = require("../utils/debug");
15
15
  const schema_utils_1 = require("@trezor/schema-utils");
16
16
  const resolveDescriptorForTaproot_1 = require("./resolveDescriptorForTaproot");
17
+ const prompts_1 = require("./prompts");
17
18
  const logger = (0, debug_1.initLog)('DeviceCommands');
18
19
  const assertType = (res, resType) => {
19
20
  const splitResTypes = Array.isArray(resType) ? resType : resType.split('|');
@@ -45,7 +46,6 @@ class DeviceCommands {
45
46
  }
46
47
  dispose() {
47
48
  this.disposed = true;
48
- this._cancelableRequest = undefined;
49
49
  }
50
50
  isDisposed() {
51
51
  return this.disposed;
@@ -243,7 +243,7 @@ class DeviceCommands {
243
243
  return this._filterCommonTypes(resp);
244
244
  }
245
245
  _filterCommonTypes(res) {
246
- this._cancelableRequestBySend = false;
246
+ this.device.clearCancelableAction();
247
247
  if (res.type === 'Failure') {
248
248
  const { code } = res.message;
249
249
  let { message } = res.message;
@@ -259,7 +259,7 @@ class DeviceCommands {
259
259
  return Promise.resolve(res);
260
260
  }
261
261
  if (res.type === 'ButtonRequest') {
262
- this._cancelableRequestBySend = true;
262
+ this.device.setCancelableAction(() => this.cancelWithFallback());
263
263
  if (res.message.code === 'ButtonRequest_PassphraseEntry') {
264
264
  this.device.emit(events_1.DEVICE.PASSPHRASE_ON_DEVICE);
265
265
  }
@@ -274,25 +274,22 @@ class DeviceCommands {
274
274
  });
275
275
  }
276
276
  if (res.type === 'PinMatrixRequest') {
277
- return this._promptPin(res.message.type).then(pin => this._commonCall('PinMatrixAck', { pin }).then(response => {
277
+ return (0, prompts_1.promptPin)(this.device, res.message.type).then(pin => this._commonCall('PinMatrixAck', { pin }).then(response => {
278
278
  if (!this.device.features.unlocked) {
279
279
  return this.device.getFeatures().then(() => response);
280
280
  }
281
281
  return response;
282
- }), () => this._commonCall('Cancel', {}));
282
+ }), error => Promise.reject(error));
283
283
  }
284
284
  if (res.type === 'PassphraseRequest') {
285
- return this._promptPassphrase().then(response => {
286
- const { passphrase, passphraseOnDevice } = response;
285
+ return (0, prompts_1.promptPassphrase)(this.device).then(({ value, passphraseOnDevice }) => {
287
286
  return !passphraseOnDevice
288
- ? this._commonCall('PassphraseAck', { passphrase })
287
+ ? this._commonCall('PassphraseAck', { passphrase: value.normalize('NFKD') })
289
288
  : this._commonCall('PassphraseAck', { on_device: true });
290
- }, err => this._commonCall('Cancel', {}).catch((e) => {
291
- throw err || e;
292
- }));
289
+ }, error => Promise.reject(error));
293
290
  }
294
291
  if (res.type === 'WordRequest') {
295
- return this._promptWord(res.message.type).then(word => this._commonCall('WordAck', { word }), () => this._commonCall('Cancel', {}));
292
+ return (0, prompts_1.promptWord)(this.device, res.message.type).then(word => this._commonCall('WordAck', { word }), error => Promise.reject(error));
296
293
  }
297
294
  return Promise.resolve(res);
298
295
  }
@@ -304,60 +301,6 @@ class DeviceCommands {
304
301
  });
305
302
  return message.address;
306
303
  }
307
- _promptPin(type) {
308
- return new Promise((resolve, reject) => {
309
- if (this.device.listenerCount(events_1.DEVICE.PIN) > 0) {
310
- this._cancelableRequest = reject;
311
- this.device.emit(events_1.DEVICE.PIN, this.device, type, (err, pin) => {
312
- this._cancelableRequest = undefined;
313
- if (err || pin == null) {
314
- reject(err);
315
- }
316
- else {
317
- resolve(pin);
318
- }
319
- });
320
- }
321
- else {
322
- console.warn('[DeviceCommands] [call] PIN callback not configured, cancelling request');
323
- reject(constants_1.ERRORS.TypedError('Runtime', '_promptPin: PIN callback not configured'));
324
- }
325
- });
326
- }
327
- _promptPassphrase() {
328
- return new Promise((resolve, reject) => {
329
- if (this.device.listenerCount(events_1.DEVICE.PASSPHRASE) > 0) {
330
- this._cancelableRequest = reject;
331
- this.device.emit(events_1.DEVICE.PASSPHRASE, this.device, (response, error) => {
332
- this._cancelableRequest = undefined;
333
- if (error) {
334
- reject(error);
335
- }
336
- else {
337
- resolve(response);
338
- }
339
- });
340
- }
341
- else {
342
- console.warn('[DeviceCommands] [call] Passphrase callback not configured, cancelling request');
343
- reject(constants_1.ERRORS.TypedError('Runtime', '_promptPassphrase: Passphrase callback not configured'));
344
- }
345
- });
346
- }
347
- _promptWord(type) {
348
- return new Promise((resolve, reject) => {
349
- this._cancelableRequest = reject;
350
- this.device.emit(events_1.DEVICE.WORD, this.device, type, (err, word) => {
351
- this._cancelableRequest = undefined;
352
- if (err || word == null) {
353
- reject(err);
354
- }
355
- else {
356
- resolve(word.toLocaleLowerCase());
357
- }
358
- });
359
- });
360
- }
361
304
  async getAccountDescriptor(coinInfo, indexOrPath, derivationType) {
362
305
  const address_n = Array.isArray(indexOrPath)
363
306
  ? indexOrPath
@@ -410,40 +353,32 @@ class DeviceCommands {
410
353
  }
411
354
  throw constants_1.ERRORS.TypedError('Runtime', 'DeviceCommands.getAccountDescriptor: unsupported coinInfo.type');
412
355
  }
413
- async cancel() {
414
- if (this._cancelableRequest) {
415
- this._cancelableRequest();
416
- this._cancelableRequest = undefined;
417
- return;
418
- }
419
- if (this.disposed) {
420
- return;
421
- }
422
- this.dispose();
423
- if (!this._cancelableRequestBySend) {
424
- if (this.callPromise) {
425
- await this.callPromise;
426
- }
427
- return;
428
- }
356
+ async cancelWithFallback() {
429
357
  const { name, version } = this.transport;
430
358
  if (name === 'BridgeTransport' && !utils_1.versionUtils.isNewer(version, '2.0.28')) {
431
359
  try {
432
- await this.device.legacyForceRelease();
360
+ await (0, utils_1.createTimeoutPromise)(1);
361
+ await this.device.acquire();
362
+ await (0, prompts_1.cancelPrompt)(this.device, false);
433
363
  }
434
364
  catch (err) {
435
365
  }
436
366
  }
437
367
  else {
438
- await this.transport.send({
439
- protocol: this.device.protocol,
440
- session: this.transportSession,
441
- name: 'Cancel',
442
- data: {},
443
- });
444
- if (this.callPromise) {
368
+ return (0, prompts_1.cancelPrompt)(this.device, false);
369
+ }
370
+ }
371
+ async cancel() {
372
+ if (this.disposed) {
373
+ return;
374
+ }
375
+ this.dispose();
376
+ if (this.callPromise) {
377
+ try {
445
378
  await this.callPromise;
446
379
  }
380
+ catch {
381
+ }
447
382
  }
448
383
  }
449
384
  }
@@ -25,7 +25,7 @@ export interface IDeviceList {
25
25
  dispose: DeviceList['dispose'];
26
26
  }
27
27
  export declare const assertDeviceListConnected: (deviceList: IDeviceList) => asserts deviceList is DeviceList;
28
- type ConstructorParams = Pick<ConnectSettings, 'priority' | 'debug'> & {
28
+ type ConstructorParams = Pick<ConnectSettings, 'priority' | 'debug' | '_sessionsBackgroundUrl'> & {
29
29
  messages: Record<string, any>;
30
30
  };
31
31
  type InitParams = Pick<ConnectSettings, 'pendingTransportEvent' | 'transportReconnect'>;
@@ -34,16 +34,19 @@ export declare class DeviceList extends TypedEmitter<DeviceListEvents> implement
34
34
  private transports;
35
35
  private devices;
36
36
  private creatingDevicesDescriptors;
37
+ private createDevicesQueue;
37
38
  private readonly authPenaltyManager;
38
39
  private initPromise?;
39
40
  private rejectPending?;
40
41
  private transportCommonArgs;
41
42
  isConnected(): this is DeviceList;
42
43
  pendingConnection(): Promise<void> | undefined;
43
- constructor({ messages, priority, debug }: ConstructorParams);
44
+ constructor({ messages, priority, debug, _sessionsBackgroundUrl }: ConstructorParams);
44
45
  private createTransport;
45
46
  setTransports(transports: ConnectSettings['transports']): void;
46
47
  private onTransportUpdate;
48
+ private waitForCreateDevicesQueue;
49
+ private removeFromCreateDevicesQueue;
47
50
  init(initParams?: InitParams): Promise<void>;
48
51
  private createInitPromise;
49
52
  private createReconnectPromise;
@@ -42,17 +42,17 @@ class DeviceList extends utils_1.TypedEmitter {
42
42
  pendingConnection() {
43
43
  return this.initPromise;
44
44
  }
45
- constructor({ messages, priority, debug }) {
45
+ constructor({ messages, priority, debug, _sessionsBackgroundUrl }) {
46
46
  super();
47
47
  this.devices = {};
48
48
  this.creatingDevicesDescriptors = {};
49
+ this.createDevicesQueue = [];
49
50
  const transportLogger = (0, debug_1.initLog)('@trezor/transport', debug);
50
- const abortController = new AbortController();
51
51
  this.authPenaltyManager = createAuthPenaltyManager(priority);
52
52
  this.transportCommonArgs = {
53
53
  messages,
54
54
  logger: transportLogger,
55
- signal: abortController.signal,
55
+ sessionsBackgroundUrl: _sessionsBackgroundUrl,
56
56
  };
57
57
  this.transports = [
58
58
  new transport_1.BridgeTransport({
@@ -104,6 +104,7 @@ class DeviceList extends utils_1.TypedEmitter {
104
104
  this.creatingDevicesDescriptors[path] = descriptor;
105
105
  switch (category.type) {
106
106
  case 'disconnected':
107
+ this.removeFromCreateDevicesQueue(path);
107
108
  if (!device)
108
109
  break;
109
110
  device.disconnect();
@@ -111,6 +112,9 @@ class DeviceList extends utils_1.TypedEmitter {
111
112
  this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
112
113
  break;
113
114
  case 'connected':
115
+ if (!(await this.waitForCreateDevicesQueue(path))) {
116
+ break;
117
+ }
114
118
  const penalty = this.authPenaltyManager.get();
115
119
  if (penalty) {
116
120
  await (0, promiseUtils_1.resolveAfter)(501 + penalty, null).promise;
@@ -123,14 +127,18 @@ class DeviceList extends utils_1.TypedEmitter {
123
127
  this.devices[path] = device;
124
128
  this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
125
129
  }
130
+ this.removeFromCreateDevicesQueue(path);
126
131
  break;
127
132
  case 'acquired':
128
- if (!device)
129
- break;
130
133
  if (category.subtype === 'elsewhere') {
131
- device.featuresNeedsReload = true;
132
- device.interruptionFromOutside();
134
+ this.removeFromCreateDevicesQueue(path);
135
+ if (device) {
136
+ device.featuresNeedsReload = true;
137
+ device.interruptionFromOutside();
138
+ }
133
139
  }
140
+ if (!device)
141
+ break;
134
142
  _log.debug('Event', events_1.DEVICE.CHANGED, device.toMessageObject());
135
143
  this.emit(events_1.DEVICE.CHANGED, device.toMessageObject());
136
144
  _log.debug('Event', events_1.DEVICE.ACQUIRED, device.toMessageObject());
@@ -159,6 +167,20 @@ class DeviceList extends utils_1.TypedEmitter {
159
167
  device === null || device === void 0 ? void 0 : device.updateDescriptor(descriptor);
160
168
  });
161
169
  }
170
+ async waitForCreateDevicesQueue(path) {
171
+ const dfd = (0, utils_1.createDeferred)(path);
172
+ const prevQueue = this.createDevicesQueue.slice();
173
+ this.createDevicesQueue.push(dfd);
174
+ await (0, utils_1.promiseAllSequence)(prevQueue.map(pr => () => pr.promise));
175
+ return this.createDevicesQueue.includes(dfd);
176
+ }
177
+ removeFromCreateDevicesQueue(path) {
178
+ const index = this.createDevicesQueue.findIndex(dfd => dfd.id === path);
179
+ if (index >= 0) {
180
+ const [dfd] = this.createDevicesQueue.splice(index, 1);
181
+ dfd.resolve();
182
+ }
183
+ }
162
184
  init(initParams = {}) {
163
185
  if (!this.initPromise) {
164
186
  _log.debug('Initializing transports');
@@ -210,12 +232,12 @@ class DeviceList extends utils_1.TypedEmitter {
210
232
  throw new Error(enumerateResult.error);
211
233
  }
212
234
  const descriptors = enumerateResult.payload;
235
+ const waitForDevicesPromise = initParams.pendingTransportEvent && descriptors.length
236
+ ? this.waitForDevices(descriptors.length, 10000)
237
+ : Promise.resolve();
213
238
  transport.handleDescriptorsChange(descriptors);
214
239
  transport.listen();
215
- const awaitedDevices = descriptors.length - Object.keys(this.devices).length;
216
- if (awaitedDevices > 0 && initParams.pendingTransportEvent) {
217
- await this.waitForDevices(awaitedDevices, 10000);
218
- }
240
+ await waitForDevicesPromise;
219
241
  return transport;
220
242
  }
221
243
  waitForDevices(deviceCount, autoResolveMs) {
@@ -294,6 +316,8 @@ class DeviceList extends utils_1.TypedEmitter {
294
316
  devices.forEach(device => {
295
317
  this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
296
318
  });
319
+ this.createDevicesQueue.forEach(dfd => dfd.resolve());
320
+ this.createDevicesQueue = [];
297
321
  await Promise.all(devices.map(device => device.dispose()));
298
322
  transport === null || transport === void 0 ? void 0 : transport.stop();
299
323
  }