@trezor/connect 9.4.3-beta.1 → 9.4.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 (200) hide show
  1. package/CHANGELOG.md +80 -49
  2. package/README.md +1 -1
  3. package/lib/api/applyFlags.js +1 -1
  4. package/lib/api/applySettings.js +1 -1
  5. package/lib/api/authenticateDevice.js +1 -1
  6. package/lib/api/authorizeCoinjoin.js +1 -1
  7. package/lib/api/backupDevice.js +1 -1
  8. package/lib/api/binance/api/binanceGetAddress.js +2 -1
  9. package/lib/api/binance/api/binanceGetPublicKey.js +2 -1
  10. package/lib/api/binance/api/binanceSignTransaction.js +2 -1
  11. package/lib/api/binance/binanceSignTx.js +1 -1
  12. package/lib/api/bitcoin/Fees.js +2 -2
  13. package/lib/api/bitcoin/TransactionComposer.d.ts +3 -3
  14. package/lib/api/bitcoin/TransactionComposer.js +2 -2
  15. package/lib/api/bitcoin/refTx.js +1 -1
  16. package/lib/api/blockchainDisconnect.js +1 -1
  17. package/lib/api/blockchainEvmRpcCall.d.ts +16 -0
  18. package/lib/api/blockchainEvmRpcCall.js +45 -0
  19. package/lib/api/cancelCoinjoinAuthorization.js +1 -1
  20. package/lib/api/cardano/api/cardanoGetAddress.js +2 -1
  21. package/lib/api/cardano/api/cardanoGetNativeScriptHash.js +2 -1
  22. package/lib/api/cardano/api/cardanoGetPublicKey.js +2 -1
  23. package/lib/api/cardano/api/cardanoSignTransaction.js +2 -1
  24. package/lib/api/cardano/cardanoAddressParameters.js +1 -1
  25. package/lib/api/cardano/cardanoAuxiliaryData.js +1 -1
  26. package/lib/api/cardano/cardanoCertificate.js +1 -1
  27. package/lib/api/cardano/cardanoInputs.d.ts +8 -8
  28. package/lib/api/cardano/cardanoInputs.js +1 -1
  29. package/lib/api/cardano/cardanoOutputs.d.ts +22 -22
  30. package/lib/api/cardano/cardanoOutputs.js +1 -1
  31. package/lib/api/cardano/cardanoTokenBundle.d.ts +6 -6
  32. package/lib/api/cardano/cardanoTokenBundle.js +1 -1
  33. package/lib/api/changeLanguage.js +1 -1
  34. package/lib/api/changePin.js +1 -1
  35. package/lib/api/cipherKeyValue.js +1 -1
  36. package/lib/api/common/paramsValidator.js +1 -1
  37. package/lib/api/composeTransaction.d.ts +9 -3
  38. package/lib/api/composeTransaction.js +7 -4
  39. package/lib/api/eos/api/eosGetPublicKey.js +2 -1
  40. package/lib/api/eos/api/eosSignTransaction.js +2 -1
  41. package/lib/api/eos/eosSignTx.d.ts +3 -3
  42. package/lib/api/ethereum/api/ethereumGetAddress.js +2 -1
  43. package/lib/api/ethereum/api/ethereumGetPublicKey.js +2 -1
  44. package/lib/api/ethereum/api/ethereumSignMessage.d.ts +1 -1
  45. package/lib/api/ethereum/api/ethereumSignMessage.js +2 -1
  46. package/lib/api/ethereum/api/ethereumSignTransaction.d.ts +1 -1
  47. package/lib/api/ethereum/api/ethereumSignTransaction.js +13 -7
  48. package/lib/api/ethereum/api/ethereumSignTypedData.d.ts +58 -57
  49. package/lib/api/ethereum/api/ethereumSignTypedData.js +3 -2
  50. package/lib/api/ethereum/api/ethereumVerifyMessage.js +2 -1
  51. package/lib/api/ethereum/ethereumDefinitions.d.ts +21 -21
  52. package/lib/api/ethereum/ethereumDefinitions.js +6 -5
  53. package/lib/api/firmware/getBinary.js +1 -1
  54. package/lib/api/firmware/x509certificate.js +3 -5
  55. package/lib/api/getAccountDescriptor.js +1 -1
  56. package/lib/api/getAddress.js +1 -1
  57. package/lib/api/getCoinInfo.d.ts +3 -0
  58. package/lib/api/getCoinInfo.js +1 -1
  59. package/lib/api/getFirmwareHash.js +1 -1
  60. package/lib/api/getOwnershipId.js +1 -1
  61. package/lib/api/getOwnershipProof.js +1 -1
  62. package/lib/api/getPublicKey.js +1 -1
  63. package/lib/api/index.d.ts +2 -1
  64. package/lib/api/index.js +5 -3
  65. package/lib/api/loadDevice.d.ts +14 -0
  66. package/lib/api/loadDevice.js +44 -0
  67. package/lib/api/nem/api/nemGetAddress.js +2 -1
  68. package/lib/api/nem/api/nemSignTransaction.js +2 -1
  69. package/lib/api/pushTransaction.js +1 -1
  70. package/lib/api/rebootToBootloader.js +1 -1
  71. package/lib/api/recoveryDevice.js +1 -1
  72. package/lib/api/requestLogin.js +1 -1
  73. package/lib/api/resetDevice.js +1 -1
  74. package/lib/api/ripple/api/rippleGetAddress.js +2 -1
  75. package/lib/api/ripple/api/rippleSignTransaction.js +2 -1
  76. package/lib/api/setBrightness.js +1 -1
  77. package/lib/api/setBusy.js +1 -1
  78. package/lib/api/signMessage.js +1 -1
  79. package/lib/api/solana/api/solanaGetAddress.js +2 -1
  80. package/lib/api/solana/api/solanaGetPublicKey.js +2 -1
  81. package/lib/api/solana/api/solanaSignTransaction.js +2 -1
  82. package/lib/api/stellar/api/stellarGetAddress.js +2 -1
  83. package/lib/api/stellar/api/stellarSignTransaction.js +2 -1
  84. package/lib/api/stellar/stellarSignTx.js +1 -1
  85. package/lib/api/tezos/api/tezosGetAddress.js +2 -1
  86. package/lib/api/tezos/api/tezosGetPublicKey.js +2 -1
  87. package/lib/api/tezos/api/tezosSignTransaction.js +2 -1
  88. package/lib/api/tezos/tezosSignTx.js +1 -1
  89. package/lib/api/unlockPath.js +1 -1
  90. package/lib/api/verifyMessage.js +1 -1
  91. package/lib/backend/Blockchain.d.ts +3 -0
  92. package/lib/backend/Blockchain.js +3 -0
  93. package/lib/constants/errors.d.ts +3 -0
  94. package/lib/constants/errors.js +3 -0
  95. package/lib/constants/index.d.ts +1 -0
  96. package/lib/constants/index.js +3 -1
  97. package/lib/constants/nem.d.ts +3 -3
  98. package/lib/constants/utxo.d.ts +3 -0
  99. package/lib/constants/utxo.js +5 -0
  100. package/lib/core/AbstractMethod.d.ts +13 -5
  101. package/lib/core/AbstractMethod.js +50 -24
  102. package/lib/core/index.js +41 -30
  103. package/lib/core/onCallFirmwareUpdate.d.ts +2 -2
  104. package/lib/core/onCallFirmwareUpdate.js +5 -5
  105. package/lib/data/DataManager.d.ts +0 -181
  106. package/lib/data/DataManager.js +40 -6
  107. package/lib/data/analyticsInfo.js +2 -1
  108. package/lib/data/coinInfo.d.ts +14 -0
  109. package/lib/data/config.d.ts +20 -22
  110. package/lib/data/config.js +15 -40
  111. package/lib/data/connectSettings.js +5 -4
  112. package/lib/data/deviceAuthenticityConfig.js +17 -0
  113. package/lib/data/deviceAuthenticityConfigTypes.d.ts +32 -23
  114. package/lib/data/firmwareInfo.d.ts +1 -1
  115. package/lib/data/models.d.ts +9 -0
  116. package/lib/data/models.js +9 -0
  117. package/lib/data/version.d.ts +1 -1
  118. package/lib/data/version.js +1 -1
  119. package/lib/device/Device.d.ts +143 -36
  120. package/lib/device/Device.js +226 -119
  121. package/lib/device/DeviceCommands.js +4 -4
  122. package/lib/device/DeviceList.d.ts +13 -21
  123. package/lib/device/DeviceList.js +54 -168
  124. package/lib/device/prompts.js +3 -2
  125. package/lib/device/resolveDescriptorForTaproot.d.ts +1 -1
  126. package/lib/events/call.d.ts +5 -5
  127. package/lib/events/call.js +2 -2
  128. package/lib/events/device.d.ts +0 -6
  129. package/lib/events/device.js +0 -6
  130. package/lib/events/transport.d.ts +1 -1
  131. package/lib/factory.d.ts +6 -6
  132. package/lib/factory.js +132 -136
  133. package/lib/impl/dynamic.d.ts +13 -19
  134. package/lib/impl/dynamic.js +0 -9
  135. package/lib/index-browser.d.ts +3 -1
  136. package/lib/index-browser.js +0 -3
  137. package/lib/index.d.ts +3 -1
  138. package/lib/index.js +1 -13
  139. package/lib/types/api/applySettings.d.ts +13 -13
  140. package/lib/types/api/authenticateDevice.d.ts +33 -24
  141. package/lib/types/api/authorizeCoinjoin.d.ts +10 -10
  142. package/lib/types/api/binance/index.d.ts +143 -143
  143. package/lib/types/api/binance/index.js +1 -1
  144. package/lib/types/api/bitcoin/index.d.ts +11 -11
  145. package/lib/types/api/bitcoin/index.js +1 -1
  146. package/lib/types/api/blockchainEvmRpcCall.d.ts +4 -0
  147. package/lib/types/api/{checkFirmwareAuthenticity.js → blockchainEvmRpcCall.js} +1 -1
  148. package/lib/types/api/cancelCoinjoinAuthorization.d.ts +1 -1
  149. package/lib/types/api/cardano/index.d.ts +507 -507
  150. package/lib/types/api/changeLanguage.d.ts +6 -6
  151. package/lib/types/api/cipherKeyValue.d.ts +8 -8
  152. package/lib/types/api/cipherKeyValue.js +1 -1
  153. package/lib/types/api/composeTransaction.d.ts +13 -7
  154. package/lib/types/api/eos/index.d.ts +525 -525
  155. package/lib/types/api/eos/index.js +1 -1
  156. package/lib/types/api/ethereum/index.d.ts +100 -100
  157. package/lib/types/api/firmwareUpdate.d.ts +5 -5
  158. package/lib/types/api/getAccountDescriptor.d.ts +4 -4
  159. package/lib/types/api/getAddress.d.ts +32 -32
  160. package/lib/types/api/getOwnershipId.d.ts +24 -24
  161. package/lib/types/api/getOwnershipProof.d.ts +28 -28
  162. package/lib/types/api/getPublicKey.d.ts +24 -24
  163. package/lib/types/api/getPublicKey.js +1 -1
  164. package/lib/types/api/index.d.ts +4 -8
  165. package/lib/types/api/init.d.ts +4 -2
  166. package/lib/types/api/loadDevice.d.ts +4 -0
  167. package/lib/types/api/loadDevice.js +3 -0
  168. package/lib/types/api/nem/index.d.ts +612 -612
  169. package/lib/types/api/nem/index.js +1 -1
  170. package/lib/types/api/nemGetAddress.d.ts +6 -6
  171. package/lib/types/api/pushTransaction.d.ts +3 -3
  172. package/lib/types/api/recoveryDevice.d.ts +9 -9
  173. package/lib/types/api/requestLogin.d.ts +25 -25
  174. package/lib/types/api/ripple/index.d.ts +21 -21
  175. package/lib/types/api/ripple/index.js +1 -1
  176. package/lib/types/api/solana/index.d.ts +23 -23
  177. package/lib/types/api/solana/index.js +1 -1
  178. package/lib/types/api/stellar/index.d.ts +582 -582
  179. package/lib/types/api/stellar/index.js +1 -1
  180. package/lib/types/api/tezos/index.d.ts +120 -120
  181. package/lib/types/api/tezos/index.js +1 -1
  182. package/lib/types/api/unlockPath.d.ts +2 -2
  183. package/lib/types/coinInfo.d.ts +231 -224
  184. package/lib/types/device.d.ts +13 -1
  185. package/lib/types/device.js +3 -1
  186. package/lib/types/fees.d.ts +19 -19
  187. package/lib/types/firmware.d.ts +1 -1
  188. package/lib/types/params.d.ts +21 -18
  189. package/lib/types/settings.d.ts +15 -9
  190. package/lib/types/utils.d.ts +1 -0
  191. package/lib/types/utils.js +3 -0
  192. package/lib/utils/addressUtils.js +2 -2
  193. package/lib/utils/assetUtils.js +3 -3
  194. package/lib/utils/deviceFeaturesUtils.js +1 -1
  195. package/lib/utils/uiPromiseManager.d.ts +2 -1
  196. package/lib/utils/uiPromiseManager.js +3 -3
  197. package/package.json +13 -13
  198. package/lib/api/checkFirmwareAuthenticity.d.ts +0 -11
  199. package/lib/api/checkFirmwareAuthenticity.js +0 -63
  200. package/lib/types/api/checkFirmwareAuthenticity.d.ts +0 -11
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Device = exports.GET_FEATURES_TIMEOUT_REACT_NATIVE = exports.GET_FEATURES_TIMEOUT = void 0;
4
+ const crypto_1 = require("crypto");
4
5
  const utils_1 = require("@trezor/utils");
5
6
  const protocol_1 = require("@trezor/protocol");
7
+ const transport_1 = require("@trezor/transport");
6
8
  const DeviceCommands_1 = require("./DeviceCommands");
7
9
  const constants_1 = require("../constants");
8
10
  const events_1 = require("../events");
@@ -11,13 +13,11 @@ const DataManager_1 = require("../data/DataManager");
11
13
  const firmwareInfo_1 = require("../data/firmwareInfo");
12
14
  const deviceFeaturesUtils_1 = require("../utils/deviceFeaturesUtils");
13
15
  const debug_1 = require("../utils/debug");
14
- const transport_1 = require("@trezor/transport");
15
16
  const types_1 = require("../types");
16
17
  const models_1 = require("../data/models");
17
18
  const getLanguage_1 = require("../data/getLanguage");
18
19
  const checkFirmwareRevision_1 = require("./checkFirmwareRevision");
19
20
  const firmware_1 = require("../api/firmware");
20
- const crypto_1 = require("crypto");
21
21
  const _log = (0, debug_1.initLog)('Device');
22
22
  exports.GET_FEATURES_TIMEOUT = 3000;
23
23
  exports.GET_FEATURES_TIMEOUT_REACT_NATIVE = 20000;
@@ -27,99 +27,192 @@ const parseRunOptions = (options) => {
27
27
  return options;
28
28
  };
29
29
  class Device extends utils_1.TypedEmitter {
30
- constructor(transport, descriptor) {
30
+ get firmwareStatus() {
31
+ return this._firmwareStatus;
32
+ }
33
+ get firmwareRelease() {
34
+ return this._firmwareRelease;
35
+ }
36
+ get features() {
37
+ return this._features;
38
+ }
39
+ get unavailableCapabilities() {
40
+ return this._unavailableCapabilities;
41
+ }
42
+ get firmwareType() {
43
+ return this._firmwareType;
44
+ }
45
+ constructor({ id, transport, descriptor, listener }) {
31
46
  super();
32
- this.featuresNeedsReload = false;
47
+ this._featuresNeedsReload = false;
33
48
  this.keepTransportSession = false;
34
49
  this.loaded = false;
35
50
  this.inconsistent = false;
36
51
  this.instance = 0;
37
52
  this.state = [];
38
53
  this.stateStorage = undefined;
39
- this.unavailableCapabilities = {};
40
- this.networkTypeState = [];
54
+ this._unavailableCapabilities = {};
41
55
  this.name = 'Trezor';
42
56
  this.availableTranslations = [];
43
57
  this.authenticityChecks = {
44
58
  firmwareRevision: null,
45
59
  firmwareHash: null,
46
60
  };
47
- this.useCardanoDerivation = false;
61
+ this.emitLifecycle = listener;
48
62
  this.protocol = protocol_1.v1;
63
+ this.uniquePath = id;
49
64
  this.transport = transport;
50
- this.originalDescriptor = descriptor;
65
+ this.transportPath = descriptor.path;
66
+ this.transportSessionOwner = descriptor.sessionOwner;
67
+ this.transportDescriptorType = descriptor.type;
68
+ this.session = descriptor.session;
69
+ this.lastAcquiredHere = false;
51
70
  this.firstRunPromise = (0, utils_1.createDeferred)();
52
71
  }
53
- static fromDescriptor(transport, originalDescriptor) {
54
- const descriptor = { ...originalDescriptor, session: null };
55
- try {
56
- const device = new Device(transport, descriptor);
57
- return device;
58
- }
59
- catch (error) {
60
- _log.error('Device.fromDescriptor', error);
61
- throw error;
72
+ getSessionChangePromise() {
73
+ if (!this.sessionDfd) {
74
+ this.sessionDfd = (0, utils_1.createDeferred)();
75
+ this.sessionDfd.promise.finally(() => {
76
+ this.sessionDfd = undefined;
77
+ });
62
78
  }
79
+ return this.sessionDfd.promise;
63
80
  }
64
- static createUnacquired(transport, descriptor, unreadableError) {
65
- const device = new Device(transport, descriptor);
66
- device.unreadableError = unreadableError;
67
- return device;
68
- }
69
- async acquire() {
70
- this.acquirePromise = this.transport.acquire({
71
- input: {
72
- path: this.originalDescriptor.path,
73
- previous: this.originalDescriptor.session,
74
- },
75
- });
76
- const acquireResult = await this.acquirePromise;
77
- this.acquirePromise = undefined;
78
- if (!acquireResult.success) {
79
- if (this.runPromise) {
80
- this.runPromise.reject(new Error(acquireResult.error));
81
- delete this.runPromise;
81
+ async waitAndCompareSession(response, sessionPromise) {
82
+ if (response.success) {
83
+ try {
84
+ if ((await sessionPromise) !== response.payload) {
85
+ return {
86
+ success: false,
87
+ error: transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS,
88
+ };
89
+ }
90
+ }
91
+ catch {
92
+ return {
93
+ success: false,
94
+ error: transport_1.TRANSPORT_ERROR.DEVICE_DISCONNECTED_DURING_ACTION,
95
+ };
96
+ }
97
+ }
98
+ return response;
99
+ }
100
+ acquire() {
101
+ const sessionPromise = this.getSessionChangePromise();
102
+ this.acquirePromise = this.transport
103
+ .acquire({ input: { path: this.transportPath, previous: this.session } })
104
+ .then(result => this.waitAndCompareSession(result, sessionPromise))
105
+ .then(result => {
106
+ var _a;
107
+ if (result.success) {
108
+ this.session = result.payload;
109
+ this.lastAcquiredHere = true;
110
+ (_a = this.commands) === null || _a === void 0 ? void 0 : _a.dispose();
111
+ this.commands = new DeviceCommands_1.DeviceCommands(this, this.transport, this.session);
112
+ return result;
82
113
  }
83
- throw acquireResult.error;
114
+ else {
115
+ if (this.runPromise) {
116
+ this.runPromise.reject(new Error(result.error));
117
+ delete this.runPromise;
118
+ }
119
+ throw result.error;
120
+ }
121
+ })
122
+ .finally(() => {
123
+ this.acquirePromise = undefined;
124
+ });
125
+ return this.acquirePromise;
126
+ }
127
+ async release() {
128
+ const localSession = this.getLocalSession();
129
+ if (!localSession || this.keepTransportSession || this.releasePromise) {
130
+ return;
84
131
  }
85
- const transportSession = acquireResult.payload;
86
- _log.debug('Expected workflow id:', transportSession);
87
- this.transportSession = transportSession;
88
- this.originalDescriptor.session = transportSession;
89
132
  if (this.commands) {
90
133
  this.commands.dispose();
134
+ if (this.commands.callPromise) {
135
+ await this.commands.callPromise;
136
+ }
91
137
  }
92
- this.commands = new DeviceCommands_1.DeviceCommands(this, this.transport, transportSession);
93
- }
94
- async release() {
95
- if (this.isUsedHere() &&
96
- this.transportSession &&
97
- !this.keepTransportSession &&
98
- !this.releasePromise) {
99
- if (this.commands) {
100
- this.commands.dispose();
101
- if (this.commands.callPromise) {
102
- await this.commands.callPromise;
103
- }
138
+ const sessionPromise = this.getSessionChangePromise();
139
+ this.releasePromise = this.transport
140
+ .release({ session: localSession, path: this.transportPath })
141
+ .then(result => this.waitAndCompareSession(result, sessionPromise))
142
+ .then(result => {
143
+ if (result.success) {
144
+ this.session = null;
104
145
  }
105
- this.releasePromise = this.transport.release({
106
- session: this.transportSession,
107
- path: this.originalDescriptor.path,
108
- });
109
- const releaseResponse = await this.releasePromise;
146
+ return result;
147
+ })
148
+ .finally(() => {
110
149
  this.releasePromise = undefined;
111
- if (releaseResponse.success) {
112
- this.transportSession = null;
113
- this.originalDescriptor.session = null;
114
- }
115
- }
150
+ });
151
+ return this.releasePromise;
152
+ }
153
+ releaseTransportSession() {
154
+ this.keepTransportSession = false;
116
155
  }
117
156
  async cleanup() {
118
- const acquiredListeners = this.listeners(events_1.DEVICE.ACQUIRED);
119
- this.removeAllListeners();
157
+ this.eventNames().forEach(e => this.removeAllListeners(e));
120
158
  delete this.runPromise;
121
159
  await this.release();
122
- acquiredListeners.forEach(l => this.once(events_1.DEVICE.ACQUIRED, l));
160
+ }
161
+ async handshake(delay) {
162
+ var _a;
163
+ if (delay) {
164
+ await (0, utils_1.createTimeoutPromise)(501 + delay);
165
+ }
166
+ while (true) {
167
+ if (this.isUsedElsewhere()) {
168
+ this.emitLifecycle(events_1.DEVICE.CONNECT_UNACQUIRED);
169
+ }
170
+ else {
171
+ try {
172
+ await this.run();
173
+ }
174
+ catch (error) {
175
+ if (error.code === 'Device_NotFound' ||
176
+ error.message === transport_1.TRANSPORT_ERROR.DEVICE_NOT_FOUND ||
177
+ error.message === transport_1.TRANSPORT_ERROR.DEVICE_DISCONNECTED_DURING_ACTION ||
178
+ error.message === transport_1.TRANSPORT_ERROR.UNEXPECTED_ERROR ||
179
+ error.message === transport_1.TRANSPORT_ERROR.DESCRIPTOR_NOT_FOUND ||
180
+ error.message === transport_1.TRANSPORT_ERROR.HTTP_ERROR) {
181
+ }
182
+ else if (error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS ||
183
+ error.code === 'Device_UsedElsewhere') {
184
+ this.emitLifecycle(events_1.DEVICE.CONNECT_UNACQUIRED);
185
+ }
186
+ else if (error.message === transport_1.TRANSPORT_ERROR.INTERFACE_UNABLE_TO_OPEN_DEVICE ||
187
+ ((_a = error.message) === null || _a === void 0 ? void 0 : _a.indexOf(constants_1.ERRORS.LIBUSB_ERROR_MESSAGE)) >= 0 ||
188
+ error.code === 'Device_InitializeFailed') {
189
+ this.unreadableError = error === null || error === void 0 ? void 0 : error.message;
190
+ this.emitLifecycle(events_1.DEVICE.CONNECT_UNACQUIRED);
191
+ }
192
+ else {
193
+ await (0, utils_1.createTimeoutPromise)(501);
194
+ continue;
195
+ }
196
+ }
197
+ }
198
+ return;
199
+ }
200
+ }
201
+ async updateDescriptor(descriptor) {
202
+ var _a, _b;
203
+ (_a = this.sessionDfd) === null || _a === void 0 ? void 0 : _a.resolve(descriptor.session);
204
+ await Promise.all([this.acquirePromise, this.releasePromise]);
205
+ if (descriptor.session && descriptor.session !== this.session) {
206
+ this.usedElsewhere();
207
+ }
208
+ if (!descriptor.session) {
209
+ const methodStillRunning = !((_b = this.commands) === null || _b === void 0 ? void 0 : _b.isDisposed());
210
+ if (methodStillRunning) {
211
+ this.releaseTransportSession();
212
+ }
213
+ }
214
+ this.session = descriptor.session;
215
+ this.emitLifecycle(events_1.DEVICE.CHANGED);
123
216
  }
124
217
  run(fn, options) {
125
218
  if (this.runPromise) {
@@ -127,9 +220,16 @@ class Device extends utils_1.TypedEmitter {
127
220
  throw constants_1.ERRORS.TypedError('Device_CallInProgress');
128
221
  }
129
222
  options = parseRunOptions(options);
223
+ const wasUnacquired = this.isUnacquired();
130
224
  const runPromise = (0, utils_1.createDeferred)();
131
225
  this.runPromise = runPromise;
132
- this._runInner(fn, options).catch(err => {
226
+ this._runInner(fn, options)
227
+ .then(() => {
228
+ if (wasUnacquired && !this.isUnacquired()) {
229
+ this.emitLifecycle(events_1.DEVICE.CONNECT);
230
+ }
231
+ })
232
+ .catch(err => {
133
233
  runPromise.reject(err);
134
234
  });
135
235
  return runPromise.promise;
@@ -167,7 +267,12 @@ class Device extends utils_1.TypedEmitter {
167
267
  delete this.runPromise;
168
268
  }
169
269
  }
170
- interruptionFromOutside() {
270
+ usedElsewhere() {
271
+ if (!this.lastAcquiredHere) {
272
+ return;
273
+ }
274
+ this.lastAcquiredHere = false;
275
+ this._featuresNeedsReload = true;
171
276
  _log.debug('interruptionFromOutside');
172
277
  if (this.commands) {
173
278
  this.commands.dispose();
@@ -176,19 +281,20 @@ class Device extends utils_1.TypedEmitter {
176
281
  this.runPromise.reject(constants_1.ERRORS.TypedError('Device_UsedElsewhere'));
177
282
  delete this.runPromise;
178
283
  }
179
- if (this.originalDescriptor.session) {
180
- this.transport.releaseDevice(this.originalDescriptor.session);
284
+ if (this.session) {
285
+ this.transport.releaseDevice(this.session);
181
286
  }
182
287
  }
183
288
  async _runInner(fn, options) {
184
- var _a, _b;
289
+ var _a;
185
290
  if (this.releasePromise) {
186
291
  await this.releasePromise;
187
292
  }
293
+ const { staticSessionId, deriveCardano } = this.getState() || {};
188
294
  if (!this.isUsedHere() ||
189
295
  ((_a = this.commands) === null || _a === void 0 ? void 0 : _a.disposed) ||
190
- !((_b = this.getState()) === null || _b === void 0 ? void 0 : _b.staticSessionId) ||
191
- this.useCardanoDerivation != !!options.useCardanoDerivation) {
296
+ !staticSessionId ||
297
+ (!deriveCardano && options.useCardanoDerivation)) {
192
298
  await this.acquire();
193
299
  try {
194
300
  if (fn) {
@@ -221,9 +327,6 @@ class Device extends utils_1.TypedEmitter {
221
327
  if (options.keepSession) {
222
328
  this.keepTransportSession = true;
223
329
  }
224
- if (this.listeners(events_1.DEVICE.ACQUIRED).length > 0) {
225
- this.emit(events_1.DEVICE.ACQUIRED);
226
- }
227
330
  if (fn) {
228
331
  await fn();
229
332
  }
@@ -253,7 +356,7 @@ class Device extends utils_1.TypedEmitter {
253
356
  setInstance(instance = 0) {
254
357
  if (this.instance !== instance) {
255
358
  if (this.keepTransportSession) {
256
- this.transportSession = null;
359
+ this.lastAcquiredHere = false;
257
360
  this.keepTransportSession = false;
258
361
  }
259
362
  }
@@ -303,19 +406,19 @@ class Device extends utils_1.TypedEmitter {
303
406
  }
304
407
  }
305
408
  async initialize(useCardanoDerivation) {
306
- var _a;
307
409
  let payload;
308
410
  if (this.features) {
309
- const sessionId = (_a = this.getState()) === null || _a === void 0 ? void 0 : _a.sessionId;
310
- payload = {};
311
- payload.derive_cardano = useCardanoDerivation;
312
- this.useCardanoDerivation = useCardanoDerivation;
411
+ const { sessionId, deriveCardano } = this.getState() || {};
412
+ payload = {
413
+ derive_cardano: deriveCardano || useCardanoDerivation,
414
+ };
313
415
  if (sessionId) {
314
416
  payload.session_id = sessionId;
315
417
  }
316
418
  }
317
419
  const { message } = await this.getCommands().typedCall('Initialize', 'Features', payload);
318
420
  this._updateFeatures(message);
421
+ this.setState({ deriveCardano: payload === null || payload === void 0 ? void 0 : payload.derive_cardano });
319
422
  }
320
423
  initStorage(storage) {
321
424
  this.stateStorage = storage;
@@ -347,14 +450,14 @@ class Device extends utils_1.TypedEmitter {
347
450
  async checkFirmwareHash() {
348
451
  var _a;
349
452
  const createFailResult = (error) => ({ success: false, error });
453
+ const baseUrl = DataManager_1.DataManager.getSettings('binFilesBaseUrl');
454
+ const enabled = DataManager_1.DataManager.getSettings('enableFirmwareHashCheck');
455
+ if (!enabled || baseUrl === undefined)
456
+ return createFailResult('check-skipped');
350
457
  const firmwareVersion = this.getVersion();
351
458
  if (firmwareVersion === undefined || !this.features || this.features.bootloader_mode) {
352
459
  return null;
353
460
  }
354
- const baseUrl = DataManager_1.DataManager.getSettings('binFilesBaseUrl');
355
- const isModelOne = this.features.internal_model === types_1.DeviceModelInternal.T1B1;
356
- if (baseUrl === undefined || !isModelOne)
357
- return createFailResult('check-skipped');
358
461
  const checkSupported = this.atLeast(constants_1.FIRMWARE.FW_HASH_SUPPORTED_VERSIONS);
359
462
  if (!checkSupported)
360
463
  return createFailResult('check-unsupported');
@@ -366,6 +469,10 @@ class Device extends utils_1.TypedEmitter {
366
469
  if (binary === null) {
367
470
  return createFailResult('check-unsupported');
368
471
  }
472
+ if (binary.byteLength < 200) {
473
+ _log.warn(`Firmware binary for hash check suspiciously small (< 200 b)`);
474
+ return createFailResult('check-unsupported');
475
+ }
369
476
  const strippedBinary = (0, firmware_1.stripFwHeaders)(binary);
370
477
  const { hash: expectedHash, challenge } = (0, firmware_1.calculateFirmwareHash)(this.features.major_version, strippedBinary, (0, crypto_1.randomBytes)(32));
371
478
  const getFirmwareHashOptional = async () => {
@@ -374,7 +481,7 @@ class Device extends utils_1.TypedEmitter {
374
481
  challenge,
375
482
  });
376
483
  }
377
- catch (e) {
484
+ catch {
378
485
  return null;
379
486
  }
380
487
  };
@@ -468,21 +575,21 @@ class Device extends utils_1.TypedEmitter {
468
575
  feat.patch_version,
469
576
  ];
470
577
  if (!version || !utils_1.versionUtils.isEqual(version, newVersion)) {
471
- this.unavailableCapabilities = (0, deviceFeaturesUtils_1.getUnavailableCapabilities)(feat, (0, coinInfo_1.getAllNetworks)());
472
- this.firmwareStatus = (0, firmwareInfo_1.getFirmwareStatus)(feat);
473
- this.firmwareRelease = (0, firmwareInfo_1.getRelease)(feat);
578
+ this._unavailableCapabilities = (0, deviceFeaturesUtils_1.getUnavailableCapabilities)(feat, (0, coinInfo_1.getAllNetworks)());
579
+ this._firmwareStatus = (0, firmwareInfo_1.getFirmwareStatus)(feat);
580
+ this._firmwareRelease = (0, firmwareInfo_1.getRelease)(feat);
474
581
  this.availableTranslations = (_c = (_b = this.firmwareRelease) === null || _b === void 0 ? void 0 : _b.translations) !== null && _c !== void 0 ? _c : [];
475
582
  }
476
- this.features = feat;
477
- this.featuresNeedsReload = false;
583
+ this._features = feat;
584
+ this._featuresNeedsReload = false;
478
585
  if (feat.fw_vendor === 'Trezor Bitcoin-only') {
479
- this.firmwareType = types_1.FirmwareType.BitcoinOnly;
586
+ this._firmwareType = types_1.FirmwareType.BitcoinOnly;
480
587
  }
481
588
  else if (feat.fw_vendor === 'Trezor') {
482
- this.firmwareType = types_1.FirmwareType.Regular;
589
+ this._firmwareType = types_1.FirmwareType.Regular;
483
590
  }
484
591
  else if (this.getMode() !== 'bootloader') {
485
- this.firmwareType =
592
+ this._firmwareType =
486
593
  feat.capabilities &&
487
594
  feat.capabilities.length > 0 &&
488
595
  !feat.capabilities.includes('Capability_Bitcoin_like')
@@ -504,9 +611,15 @@ class Device extends utils_1.TypedEmitter {
504
611
  isUnacquired() {
505
612
  return this.features === undefined;
506
613
  }
614
+ isUnreadable() {
615
+ return !!this.unreadableError;
616
+ }
507
617
  disconnect() {
618
+ var _a;
508
619
  _log.debug('Disconnect cleanup');
509
- this.transportSession = null;
620
+ (_a = this.sessionDfd) === null || _a === void 0 ? void 0 : _a.reject(new Error());
621
+ this.lastAcquiredHere = false;
622
+ this.emitLifecycle(events_1.DEVICE.DISCONNECT);
510
623
  return this.interruptionFromUser(constants_1.ERRORS.TypedError('Device_Disconnected'));
511
624
  }
512
625
  isBootloader() {
@@ -538,13 +651,13 @@ class Device extends utils_1.TypedEmitter {
538
651
  return utils_1.versionUtils.isNewerOrEqual(version, modelVersion);
539
652
  }
540
653
  isUsed() {
541
- return typeof this.originalDescriptor.session === 'string';
654
+ return typeof this.session === 'string';
542
655
  }
543
656
  isUsedHere() {
544
- return this.isUsed() && this.originalDescriptor.session === this.transportSession;
657
+ return this.isUsed() && this.lastAcquiredHere;
545
658
  }
546
659
  isUsedElsewhere() {
547
- return this.isUsed() && !this.isUsedHere();
660
+ return this.isUsed() && !this.lastAcquiredHere;
548
661
  }
549
662
  isRunning() {
550
663
  return !!this.runPromise;
@@ -555,8 +668,11 @@ class Device extends utils_1.TypedEmitter {
555
668
  waitForFirstRun() {
556
669
  return this.firstRunPromise.promise;
557
670
  }
558
- getDevicePath() {
559
- return this.originalDescriptor.path;
671
+ getLocalSession() {
672
+ return this.lastAcquiredHere ? this.session : null;
673
+ }
674
+ getUniquePath() {
675
+ return this.uniquePath;
560
676
  }
561
677
  isT1() {
562
678
  return this.features ? this.features.major_version === 1 : false;
@@ -578,28 +694,20 @@ class Device extends utils_1.TypedEmitter {
578
694
  }
579
695
  return null;
580
696
  }
581
- updateDescriptor(descriptor) {
582
- this.originalDescriptor = {
583
- session: descriptor.session,
584
- path: descriptor.path,
585
- product: descriptor.product,
586
- type: descriptor.type,
587
- };
588
- }
589
697
  async dispose() {
590
698
  var _a, _b;
591
699
  this.removeAllListeners();
592
- if (this.isUsedHere() && this.transportSession) {
700
+ if (this.session && this.lastAcquiredHere) {
593
701
  try {
594
702
  await ((_a = this.cancelableAction) === null || _a === void 0 ? void 0 : _a.call(this));
595
703
  await ((_b = this.commands) === null || _b === void 0 ? void 0 : _b.cancel());
596
704
  return this.transport.release({
597
- session: this.transportSession,
598
- path: this.originalDescriptor.path,
705
+ session: this.session,
706
+ path: this.transportPath,
599
707
  onClose: true,
600
708
  });
601
709
  }
602
- catch (err) {
710
+ catch {
603
711
  }
604
712
  }
605
713
  }
@@ -614,18 +722,15 @@ class Device extends utils_1.TypedEmitter {
614
722
  }
615
723
  toMessageObject() {
616
724
  var _a;
617
- const { path } = this.originalDescriptor;
618
- const { name } = this;
619
- const base = {
620
- path,
621
- name,
622
- };
725
+ const { name, uniquePath: path } = this;
726
+ const base = { path, name };
623
727
  if (this.unreadableError) {
624
728
  return {
625
729
  ...base,
626
730
  type: 'unreadable',
627
731
  error: this.unreadableError,
628
732
  label: 'Unreadable device',
733
+ transportDescriptorType: this.transportDescriptorType,
629
734
  };
630
735
  }
631
736
  if (this.isUnacquired()) {
@@ -633,12 +738,14 @@ class Device extends utils_1.TypedEmitter {
633
738
  ...base,
634
739
  type: 'unacquired',
635
740
  label: 'Unacquired device',
741
+ name: this.name,
742
+ transportSessionOwner: this.transportSessionOwner,
636
743
  };
637
744
  }
638
745
  const defaultLabel = 'My Trezor';
639
746
  const label = this.features.label === '' || !this.features.label ? defaultLabel : this.features.label;
640
747
  let status = this.isUsedElsewhere() ? 'occupied' : 'available';
641
- if (this.featuresNeedsReload)
748
+ if (this._featuresNeedsReload)
642
749
  status = 'used';
643
750
  return {
644
751
  ...base,
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const crypto_1 = require("crypto");
6
6
  const protobuf_1 = require("@trezor/protobuf");
7
7
  const utils_1 = require("@trezor/utils");
8
+ const schema_utils_1 = require("@trezor/schema-utils");
8
9
  const constants_1 = require("../constants");
9
10
  const events_1 = require("../events");
10
11
  const hdnodeUtils = tslib_1.__importStar(require("../utils/hdnodeUtils"));
@@ -12,7 +13,6 @@ const pathUtils_1 = require("../utils/pathUtils");
12
13
  const accountUtils_1 = require("../utils/accountUtils");
13
14
  const coinInfo_1 = require("../data/coinInfo");
14
15
  const debug_1 = require("../utils/debug");
15
- const schema_utils_1 = require("@trezor/schema-utils");
16
16
  const resolveDescriptorForTaproot_1 = require("./resolveDescriptorForTaproot");
17
17
  const prompts_1 = require("./prompts");
18
18
  const logger = (0, debug_1.initLog)('DeviceCommands');
@@ -26,7 +26,7 @@ const generateEntropy = (len) => {
26
26
  try {
27
27
  return (0, crypto_1.randomBytes)(len);
28
28
  }
29
- catch (err) {
29
+ catch {
30
30
  throw constants_1.ERRORS.TypedError('Runtime', 'generateEntropy: Environment does not support crypto random');
31
31
  }
32
32
  };
@@ -236,10 +236,10 @@ class DeviceCommands {
236
236
  return response;
237
237
  }
238
238
  async _commonCall(type, msg) {
239
- const resp = await this.call(type, msg);
240
239
  if (this.disposed) {
241
240
  throw constants_1.ERRORS.TypedError('Runtime', 'typedCall: DeviceCommands already disposed');
242
241
  }
242
+ const resp = await this.call(type, msg);
243
243
  return this._filterCommonTypes(resp);
244
244
  }
245
245
  _filterCommonTypes(res) {
@@ -361,7 +361,7 @@ class DeviceCommands {
361
361
  await this.device.acquire();
362
362
  await (0, prompts_1.cancelPrompt)(this.device, false);
363
363
  }
364
- catch (err) {
364
+ catch {
365
365
  }
366
366
  }
367
367
  else {