@trezor/connect 9.5.0-beta.1 → 9.5.1-beta.1

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 (48) hide show
  1. package/CHANGELOG.md +66 -62
  2. package/README.md +1 -1
  3. package/lib/api/bitcoin/BitcoinFees.d.ts +25 -0
  4. package/lib/api/bitcoin/{Fees.js → BitcoinFees.js} +8 -29
  5. package/lib/api/bitcoin/TransactionComposer.d.ts +2 -2
  6. package/lib/api/bitcoin/TransactionComposer.js +5 -5
  7. package/lib/api/bitcoin/index.d.ts +1 -1
  8. package/lib/api/bitcoin/index.js +1 -1
  9. package/lib/api/blockchainEstimateFee.js +15 -4
  10. package/lib/api/{bitcoin/Fees.d.ts → common/MiscFees.d.ts} +10 -11
  11. package/lib/api/common/MiscFees.js +46 -0
  12. package/lib/api/common/paramsValidator.js +1 -1
  13. package/lib/api/ethereum/EthereumFees.d.ts +24 -0
  14. package/lib/api/ethereum/EthereumFees.js +71 -0
  15. package/lib/api/ethereum/api/ethereumSignTypedData.d.ts +6 -0
  16. package/lib/api/ethereum/ethereumDefinitions.js +1 -3
  17. package/lib/api/getCoinInfo.d.ts +18 -0
  18. package/lib/api/solana/api/solanaComposeTransaction.d.ts +1 -2
  19. package/lib/api/solana/api/solanaComposeTransaction.js +2 -5
  20. package/lib/api/unlockPath.d.ts +1 -1
  21. package/lib/backend/Blockchain.d.ts +1 -0
  22. package/lib/core/AbstractMethod.js +1 -1
  23. package/lib/data/coinInfo.d.ts +66 -0
  24. package/lib/data/connectSettings.js +6 -1
  25. package/lib/data/defaultFeeLevels.js +1 -1
  26. package/lib/data/version.d.ts +1 -1
  27. package/lib/data/version.js +1 -1
  28. package/lib/device/Device.d.ts +3 -5
  29. package/lib/device/Device.js +25 -20
  30. package/lib/device/DeviceList.d.ts +6 -13
  31. package/lib/device/DeviceList.js +44 -174
  32. package/lib/device/TransportList.d.ts +9 -0
  33. package/lib/device/TransportList.js +50 -0
  34. package/lib/device/TransportManager.d.ts +34 -0
  35. package/lib/device/TransportManager.js +149 -0
  36. package/lib/device/checkFirmwareRevision.js +9 -5
  37. package/lib/types/api/solana/index.d.ts +1 -2
  38. package/lib/types/api/solana/index.js +1 -2
  39. package/lib/types/coinInfo.d.ts +36 -0
  40. package/lib/types/device.d.ts +6 -0
  41. package/lib/types/fees.d.ts +13 -0
  42. package/lib/types/fees.js +13 -1
  43. package/lib/types/settings.d.ts +3 -1
  44. package/lib/types/utils.d.ts +0 -1
  45. package/lib/types/utils.js +0 -3
  46. package/lib/utils/assets-browser.d.ts +4 -0
  47. package/lib/utils/assets-browser.js +11 -2
  48. package/package.json +16 -16
@@ -6,9 +6,9 @@ const utils_1 = require("@trezor/utils");
6
6
  const constants_1 = require("../constants");
7
7
  const events_1 = require("../events");
8
8
  const Device_1 = require("./Device");
9
- const transportInfo_1 = require("../data/transportInfo");
10
9
  const types_1 = require("../types");
11
- const utils_2 = require("../types/utils");
10
+ const TransportList_1 = require("./TransportList");
11
+ const TransportManager_1 = require("./TransportManager");
12
12
  const debug_1 = require("../utils/debug");
13
13
  const createAuthPenaltyManager = (priority) => {
14
14
  const penalizedDevices = {};
@@ -67,100 +67,42 @@ const assertDeviceListConnected = deviceList => {
67
67
  };
68
68
  exports.assertDeviceListConnected = assertDeviceListConnected;
69
69
  class DeviceList extends utils_1.TypedEmitter {
70
- transport = {};
70
+ transportManagers = {};
71
71
  transports = [];
72
72
  devices = createDeviceCollection();
73
73
  deviceCounter = Date.now();
74
74
  handshakeLock;
75
75
  authPenaltyManager;
76
- transportCommonArgs;
76
+ updateTransports;
77
+ getConnectedTransports() {
78
+ return Object.values(this.transportManagers)
79
+ .map(manager => manager.get())
80
+ .filter(utils_1.isNotUndefined);
81
+ }
77
82
  isConnected() {
78
- return !!Object.keys(this.transport).length;
83
+ return !!this.getConnectedTransports().length;
79
84
  }
80
85
  pendingConnection() {
81
- const pending = Object.values(this.locks)
82
- .map(({ promise }) => promise)
86
+ const pending = Object.values(this.transportManagers)
87
+ .map(manager => manager.pending())
83
88
  .filter(utils_1.isNotUndefined);
84
89
  if (pending.length)
85
90
  return Promise.all(pending).then(() => { });
86
91
  }
87
92
  getActiveTransports() {
88
- return Object.values(this.transport).map(getTransportInfo);
89
- }
90
- locks = {};
91
- async transportLock(apiType, abortMessage, action) {
92
- const lock = this.locks[apiType] ?? (this.locks[apiType] = { sequence: 0 });
93
- lock.abortMessage = abortMessage;
94
- const sequence = ++lock.sequence;
95
- while (lock.promise) {
96
- lock.abort?.abort(new Error(abortMessage));
97
- await lock.promise.catch(() => { });
98
- }
99
- if (sequence !== lock.sequence)
100
- return Promise.reject(new Error(lock.abortMessage));
101
- lock.abort = new AbortController();
102
- lock.promise = action(lock.abort.signal).finally(() => {
103
- delete lock.abort;
104
- delete lock.promise;
105
- });
106
- return lock.promise;
93
+ return this.getConnectedTransports().map(getTransportInfo);
107
94
  }
108
- scheduledUpgradeChecks = {};
109
95
  constructor({ messages, priority, debug, _sessionsBackgroundUrl, manifest, }) {
110
96
  super();
111
97
  const transportLogger = (0, debug_1.initLog)('@trezor/transport', debug);
112
98
  this.handshakeLock = (0, utils_1.getSynchronize)();
113
99
  this.authPenaltyManager = createAuthPenaltyManager(priority);
114
- this.transportCommonArgs = {
100
+ this.updateTransports = (0, TransportList_1.createTransportList)({
115
101
  messages,
116
102
  logger: transportLogger,
117
103
  sessionsBackgroundUrl: _sessionsBackgroundUrl,
118
104
  id: manifest?.appUrl || 'unknown app',
119
- };
120
- }
121
- tryGetTransport(name) {
122
- return this.transports.find(t => t.name === name);
123
- }
124
- getOrCreateTransport(transportType) {
125
- const { transportCommonArgs } = this;
126
- if (typeof transportType === 'string') {
127
- const existing = this.tryGetTransport(transportType);
128
- if (existing)
129
- return existing;
130
- switch (transportType) {
131
- case 'WebUsbTransport':
132
- return new transport_1.WebUsbTransport(transportCommonArgs);
133
- case 'NodeUsbTransport':
134
- return new transport_1.NodeUsbTransport(transportCommonArgs);
135
- case 'BridgeTransport':
136
- return new transport_1.BridgeTransport({
137
- latestVersion: (0, transportInfo_1.getBridgeInfo)().version.join('.'),
138
- ...transportCommonArgs,
139
- });
140
- case 'UdpTransport':
141
- return new transport_1.UdpTransport(transportCommonArgs);
142
- }
143
- }
144
- else if (typeof transportType === 'function' && 'prototype' in transportType) {
145
- const transportInstance = new transportType(transportCommonArgs);
146
- if ((0, transport_1.isTransportInstance)(transportInstance)) {
147
- return this.tryGetTransport(transportInstance.name) ?? transportInstance;
148
- }
149
- }
150
- else if ((0, transport_1.isTransportInstance)(transportType)) {
151
- if (this.tryGetTransport(transportType.name)) {
152
- return transportType;
153
- }
154
- if (!transportType.getMessage()) {
155
- transportType.updateMessages(transportCommonArgs.messages);
156
- }
157
- return transportType;
158
- }
159
- throw constants_1.ERRORS.TypedError('Runtime', `DeviceList.init: transports[] of unexpected type: ${transportType}`);
160
- }
161
- createTransports(transports) {
162
- const transportTypes = transports?.length ? transports : ['BridgeTransport'];
163
- return transportTypes.map(this.getOrCreateTransport.bind(this));
105
+ });
164
106
  }
165
107
  onDeviceConnected(descriptor, transport) {
166
108
  const id = (this.deviceCounter++).toString(16).slice(-8);
@@ -190,103 +132,41 @@ class DeviceList extends utils_1.TypedEmitter {
190
132
  const device = this.devices.get(descriptor.path, transport);
191
133
  device?.usedElsewhere();
192
134
  }
193
- async init(initParams = {}) {
194
- this.transports = this.createTransports(initParams.transports);
135
+ getOrCreateTransportManager(apiType) {
136
+ if (!this.transportManagers[apiType]) {
137
+ const manager = new TransportManager_1.TransportManager({
138
+ startTransport: this.startTransport.bind(this),
139
+ stopTransport: this.stopTransport.bind(this),
140
+ });
141
+ manager.on(transport_1.TRANSPORT.START, transport => this.emit(transport_1.TRANSPORT.START, getTransportInfo(transport)));
142
+ manager.on(transport_1.TRANSPORT.ERROR, error => this.emit(transport_1.TRANSPORT.ERROR, { apiType, error }));
143
+ this.transportManagers[apiType] = manager;
144
+ }
145
+ return this.transportManagers[apiType];
146
+ }
147
+ async init({ transports, transportReconnect, pendingTransportEvent } = {}) {
148
+ this.transports = this.updateTransports(this.transports, transports);
195
149
  const promises = this.transports
196
150
  .map(t => t.apiType)
197
- .concat((0, utils_2.typedObjectKeys)(this.transport))
198
- .concat((0, utils_2.typedObjectKeys)(this.locks))
151
+ .concat((0, utils_1.typedObjectKeys)(this.transportManagers))
199
152
  .filter(utils_1.arrayDistinct)
200
- .map(apiType => this.transportLock(apiType, 'New init', signal => this.createInitPromise(apiType, initParams, signal)));
153
+ .map(apiType => this.getOrCreateTransportManager(apiType).init({
154
+ transports: this.transports.filter(t => t.apiType === apiType),
155
+ transportReconnect,
156
+ pendingTransportEvent,
157
+ }));
201
158
  await Promise.all(promises);
202
159
  }
203
- async createInitPromise(apiType, initParams, abortSignal) {
160
+ async startTransport(transport, pendingTransportEvent, signal) {
204
161
  try {
205
- const transports = this.transports.filter(t => t.apiType === apiType);
206
- const transport = transports.length
207
- ? await this.selectTransport(transports, abortSignal)
208
- : undefined;
209
- const oldTransport = this.transport[apiType];
210
- if (oldTransport !== transport) {
211
- if (oldTransport) {
212
- delete this.transport[apiType];
213
- await this.stopTransport(oldTransport);
214
- if (!transport) {
215
- this.emit(transport_1.TRANSPORT.ERROR, { apiType, error: 'Transport disabled' });
216
- }
217
- }
218
- if (transport) {
219
- try {
220
- await this.initializeTransport(transport, initParams, abortSignal);
221
- }
222
- catch (error) {
223
- await this.stopTransport(transport);
224
- throw error;
225
- }
226
- transport.on(transport_1.TRANSPORT.ERROR, error => {
227
- this.emit(transport_1.TRANSPORT.ERROR, { apiType, error });
228
- this.transportLock(apiType, 'Transport error', async (signal) => {
229
- delete this.transport[apiType];
230
- await this.stopTransport(transport);
231
- if (initParams.transportReconnect) {
232
- await this.createReconnectDelay(signal);
233
- await this.createInitPromise(apiType, initParams, signal);
234
- }
235
- }).catch(() => { });
236
- });
237
- this.transport[apiType] = transport;
238
- this.emit(transport_1.TRANSPORT.START, getTransportInfo(transport));
239
- }
240
- }
241
- if (transport && transport !== transports[0]) {
242
- this.scheduleUpgradeCheck(apiType, initParams);
243
- }
162
+ await this.initializeTransport(transport, pendingTransportEvent, signal);
244
163
  }
245
- catch (error) {
246
- this.emit(transport_1.TRANSPORT.ERROR, { apiType, error: error?.message });
247
- if (initParams.transportReconnect && !abortSignal.aborted) {
248
- this.transportLock(apiType, 'Reconnecting', async (signal) => {
249
- await this.createReconnectDelay(signal);
250
- await this.createInitPromise(apiType, initParams, signal);
251
- }).catch(() => { });
252
- }
164
+ catch (err) {
165
+ await this.stopTransport(transport);
166
+ throw err;
253
167
  }
254
168
  }
255
- createReconnectDelay(signal) {
256
- return (0, utils_1.resolveAfter)(1000, signal);
257
- }
258
- scheduleUpgradeCheck(apiType, initParams) {
259
- clearTimeout(this.scheduledUpgradeChecks[apiType]);
260
- this.scheduledUpgradeChecks[apiType] = setTimeout(async () => {
261
- const transport = this.transport[apiType];
262
- const transports = this.transports.filter(t => t.apiType === apiType);
263
- if (!transport || transport === transports[0])
264
- return;
265
- for (const t of transports) {
266
- if (t === transport)
267
- break;
268
- if (await t.ping()) {
269
- this.transportLock(apiType, 'Upgrading', signal => this.createInitPromise(apiType, initParams, signal)).catch(() => { });
270
- return;
271
- }
272
- }
273
- this.scheduleUpgradeCheck(apiType, initParams);
274
- }, 1000);
275
- }
276
- async selectTransport([transport, ...rest], signal) {
277
- if (signal.aborted)
278
- throw new Error(signal.reason);
279
- if (transport === this.transport[transport.apiType])
280
- return transport;
281
- const result = await transport.init({ signal });
282
- if (result.success)
283
- return transport;
284
- else if (rest.length)
285
- return this.selectTransport(rest, signal);
286
- else
287
- throw new Error(result.error);
288
- }
289
- async initializeTransport(transport, initParams, signal) {
169
+ async initializeTransport(transport, pendingTransportEvent, signal) {
290
170
  transport.on(transport_1.TRANSPORT.DEVICE_CONNECTED, d => this.onDeviceConnected(d, transport));
291
171
  transport.on(transport_1.TRANSPORT.DEVICE_DISCONNECTED, d => this.onDeviceDisconnected(d, transport));
292
172
  transport.on(transport_1.TRANSPORT.DEVICE_SESSION_CHANGED, d => this.onDeviceSessionChanged(d, transport));
@@ -296,7 +176,7 @@ class DeviceList extends utils_1.TypedEmitter {
296
176
  throw new Error(enumerateResult.error);
297
177
  }
298
178
  const descriptors = enumerateResult.payload;
299
- const waitForDevicesPromise = initParams.pendingTransportEvent && descriptors.length
179
+ const waitForDevicesPromise = pendingTransportEvent && descriptors.length
300
180
  ? this.waitForDevices(transport, descriptors, signal)
301
181
  : Promise.resolve();
302
182
  transport.handleDescriptorsChange(descriptors);
@@ -348,20 +228,10 @@ class DeviceList extends utils_1.TypedEmitter {
348
228
  }
349
229
  async dispose() {
350
230
  this.removeAllListeners();
351
- const promises = (0, utils_2.typedObjectKeys)(this.transport)
352
- .concat((0, utils_2.typedObjectKeys)(this.locks))
353
- .filter(utils_1.arrayDistinct)
354
- .map(apiType => this.transportLock(apiType, 'Disposing', async () => {
355
- const transport = this.transport[apiType];
356
- if (transport) {
357
- delete this.transport[apiType];
358
- await this.stopTransport(transport);
359
- }
360
- }));
231
+ const promises = Object.values(this.transportManagers).map(manager => manager.dispose());
361
232
  await Promise.all(promises);
362
233
  }
363
234
  async stopTransport(transport) {
364
- clearTimeout(this.scheduledUpgradeChecks[transport.apiType]);
365
235
  const devices = this.devices.clear(transport);
366
236
  devices.forEach(device => {
367
237
  this.emit(events_1.DEVICE.DISCONNECT, device);
@@ -373,7 +243,7 @@ class DeviceList extends utils_1.TypedEmitter {
373
243
  transport?.stop();
374
244
  }
375
245
  async enumerate() {
376
- const promises = Object.values(this.transport).map(async (transport) => {
246
+ const promises = this.getConnectedTransports().map(async (transport) => {
377
247
  const res = await transport.enumerate();
378
248
  if (!res.success) {
379
249
  return;
@@ -0,0 +1,9 @@
1
+ import { BridgeTransport, NodeUsbTransport, Transport, UdpTransport } from '@trezor/transport';
2
+ import type { AbstractTransportParams } from '@trezor/transport/lib/transports/abstract';
3
+ import { ConnectSettingsTransport } from '../types';
4
+ type Params = AbstractTransportParams & {
5
+ sessionsBackgroundUrl?: string | null;
6
+ };
7
+ export declare const createTransportList: (params: Params) => (existing: Transport[], transports?: ConnectSettingsTransport[]) => (Transport | NodeUsbTransport | BridgeTransport | UdpTransport)[];
8
+ export {};
9
+ //# sourceMappingURL=TransportList.d.ts.map
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTransportList = void 0;
4
+ const transport_1 = require("@trezor/transport");
5
+ const constants_1 = require("../constants");
6
+ const transportInfo_1 = require("../data/transportInfo");
7
+ const tryGetTransport = (transports, name) => transports.find(t => t.name === name);
8
+ const getOrCreateTransport = (transports, transportType, params) => {
9
+ if (typeof transportType === 'string') {
10
+ const existing = tryGetTransport(transports, transportType);
11
+ if (existing)
12
+ return existing;
13
+ switch (transportType) {
14
+ case 'WebUsbTransport':
15
+ return new transport_1.WebUsbTransport(params);
16
+ case 'NodeUsbTransport':
17
+ return new transport_1.NodeUsbTransport(params);
18
+ case 'BridgeTransport':
19
+ return new transport_1.BridgeTransport({
20
+ latestVersion: (0, transportInfo_1.getBridgeInfo)().version.join('.'),
21
+ ...params,
22
+ });
23
+ case 'UdpTransport':
24
+ return new transport_1.UdpTransport(params);
25
+ }
26
+ }
27
+ else if (typeof transportType === 'function' && 'prototype' in transportType) {
28
+ const transportInstance = new transportType(params);
29
+ if ((0, transport_1.isTransportInstance)(transportInstance)) {
30
+ return tryGetTransport(transports, transportInstance.name) ?? transportInstance;
31
+ }
32
+ }
33
+ else if ((0, transport_1.isTransportInstance)(transportType)) {
34
+ if (tryGetTransport(transports, transportType.name)) {
35
+ return transportType;
36
+ }
37
+ if (!transportType.getMessage()) {
38
+ transportType.updateMessages(params.messages);
39
+ }
40
+ return transportType;
41
+ }
42
+ throw constants_1.ERRORS.TypedError('Runtime', `DeviceList.init: transports[] of unexpected type: ${transportType}`);
43
+ };
44
+ const createTransports = (existing, transports = [], params) => {
45
+ const transportTypes = transports?.length ? transports : ['BridgeTransport'];
46
+ return transportTypes.map(type => getOrCreateTransport(existing, type, params));
47
+ };
48
+ const createTransportList = (params) => (existing, transports) => createTransports(existing, transports, params);
49
+ exports.createTransportList = createTransportList;
50
+ //# sourceMappingURL=TransportList.js.map
@@ -0,0 +1,34 @@
1
+ import { TRANSPORT, Transport } from '@trezor/transport';
2
+ import { TypedEmitter } from '@trezor/utils';
3
+ type TransportManagerEvents = {
4
+ [TRANSPORT.START]: Transport;
5
+ [TRANSPORT.ERROR]: string;
6
+ };
7
+ type TransportManagerParams = {
8
+ startTransport: (transport: Transport, pendingTransportEvent: boolean, signal: AbortSignal) => Promise<void>;
9
+ stopTransport: (transport: Transport) => Promise<void>;
10
+ };
11
+ type InitParams = {
12
+ transports: Transport[];
13
+ transportReconnect?: boolean;
14
+ pendingTransportEvent?: boolean;
15
+ };
16
+ export declare class TransportManager extends TypedEmitter<TransportManagerEvents> {
17
+ private lock;
18
+ private transports;
19
+ private activeTransport?;
20
+ private transportReconnect;
21
+ private upgradeTimeout?;
22
+ private readonly startTransport;
23
+ private readonly stopTransport;
24
+ constructor({ startTransport, stopTransport }: TransportManagerParams);
25
+ pending(): Promise<void> | undefined;
26
+ get(): Transport | undefined;
27
+ init({ transports, transportReconnect, pendingTransportEvent }: InitParams): Promise<void>;
28
+ dispose(): Promise<void>;
29
+ private selectTransport;
30
+ private scheduleUpgradeCheck;
31
+ private createInitPromise;
32
+ }
33
+ export {};
34
+ //# sourceMappingURL=TransportManager.d.ts.map
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransportManager = void 0;
4
+ const transport_1 = require("@trezor/transport");
5
+ const utils_1 = require("@trezor/utils");
6
+ const createOverrideLock = () => {
7
+ let promise;
8
+ let sequence = 0;
9
+ let abort;
10
+ let message;
11
+ const override = async (abortMessage, action) => {
12
+ message = abortMessage;
13
+ const seq = ++sequence;
14
+ while (promise) {
15
+ abort?.abort(new Error(abortMessage));
16
+ await promise.catch(() => { });
17
+ }
18
+ if (seq !== sequence)
19
+ return Promise.reject(new Error(message));
20
+ abort = new AbortController();
21
+ promise = action(abort.signal).finally(() => {
22
+ abort = undefined;
23
+ promise = undefined;
24
+ });
25
+ return promise;
26
+ };
27
+ const getPending = () => promise;
28
+ return { override, getPending };
29
+ };
30
+ class TransportManager extends utils_1.TypedEmitter {
31
+ lock = createOverrideLock();
32
+ transports = [];
33
+ activeTransport;
34
+ transportReconnect = false;
35
+ upgradeTimeout;
36
+ startTransport;
37
+ stopTransport;
38
+ constructor({ startTransport, stopTransport }) {
39
+ super();
40
+ this.startTransport = startTransport;
41
+ this.stopTransport = stopTransport;
42
+ }
43
+ pending() {
44
+ return this.lock.getPending();
45
+ }
46
+ get() {
47
+ return this.activeTransport;
48
+ }
49
+ init({ transports, transportReconnect = false, pendingTransportEvent = false }) {
50
+ this.transports = transports;
51
+ this.transportReconnect = transportReconnect;
52
+ return this.lock.override('New init', signal => this.createInitPromise(pendingTransportEvent, signal));
53
+ }
54
+ dispose() {
55
+ this.removeAllListeners();
56
+ return this.lock.override('Disposing', async () => {
57
+ const { activeTransport } = this;
58
+ if (activeTransport) {
59
+ clearTimeout(this.upgradeTimeout);
60
+ delete this.activeTransport;
61
+ await this.stopTransport(activeTransport);
62
+ }
63
+ });
64
+ }
65
+ async selectTransport([transport, ...rest], signal) {
66
+ if (signal.aborted)
67
+ throw new Error(signal.reason);
68
+ if (transport === this.activeTransport)
69
+ return transport;
70
+ const result = await transport.init({ signal });
71
+ if (result.success)
72
+ return transport;
73
+ else if (rest.length)
74
+ return this.selectTransport(rest, signal);
75
+ else
76
+ throw new Error(result.error);
77
+ }
78
+ scheduleUpgradeCheck(pendingTransportEvent) {
79
+ clearTimeout(this.upgradeTimeout);
80
+ this.upgradeTimeout = setTimeout(async () => {
81
+ if (!this.activeTransport || this.activeTransport === this.transports[0])
82
+ return;
83
+ for (const t of this.transports) {
84
+ if (t === this.activeTransport)
85
+ break;
86
+ if (await t.ping()) {
87
+ this.lock
88
+ .override('Upgrading', signal => this.createInitPromise(pendingTransportEvent, signal))
89
+ .catch(() => { });
90
+ return;
91
+ }
92
+ }
93
+ this.scheduleUpgradeCheck(pendingTransportEvent);
94
+ }, 1000);
95
+ }
96
+ async createInitPromise(pendingTransportEvent, abortSignal) {
97
+ try {
98
+ const { transports, activeTransport } = this;
99
+ const transport = transports.length
100
+ ? await this.selectTransport(transports, abortSignal)
101
+ : undefined;
102
+ if (activeTransport !== transport) {
103
+ if (activeTransport) {
104
+ clearTimeout(this.upgradeTimeout);
105
+ delete this.activeTransport;
106
+ await this.stopTransport(activeTransport);
107
+ }
108
+ if (transport) {
109
+ await this.startTransport(transport, pendingTransportEvent, abortSignal);
110
+ transport.on(transport_1.TRANSPORT.ERROR, error => {
111
+ this.emit(transport_1.TRANSPORT.ERROR, error);
112
+ clearTimeout(this.upgradeTimeout);
113
+ this.lock
114
+ .override('Transport error', async (signal) => {
115
+ delete this.activeTransport;
116
+ await this.stopTransport(transport);
117
+ if (this.transportReconnect) {
118
+ await (0, utils_1.resolveAfter)(1000, signal);
119
+ await this.createInitPromise(pendingTransportEvent, signal);
120
+ }
121
+ })
122
+ .catch(() => { });
123
+ });
124
+ this.activeTransport = transport;
125
+ this.emit(transport_1.TRANSPORT.START, transport);
126
+ }
127
+ else {
128
+ this.emit(transport_1.TRANSPORT.ERROR, 'Transport disabled');
129
+ }
130
+ }
131
+ if (transport && transport !== transports[0]) {
132
+ this.scheduleUpgradeCheck(pendingTransportEvent);
133
+ }
134
+ }
135
+ catch (error) {
136
+ this.emit(transport_1.TRANSPORT.ERROR, error?.message);
137
+ if (this.transportReconnect && !abortSignal.aborted) {
138
+ this.lock
139
+ .override('Reconnecting', async (signal) => {
140
+ await (0, utils_1.resolveAfter)(1000, signal);
141
+ await this.createInitPromise(pendingTransportEvent, signal);
142
+ })
143
+ .catch(() => { });
144
+ }
145
+ }
146
+ }
147
+ }
148
+ exports.TransportManager = TransportManager;
149
+ //# sourceMappingURL=TransportManager.js.map
@@ -4,12 +4,14 @@ exports.checkFirmwareRevision = void 0;
4
4
  const versionUtils_1 = require("@trezor/utils/lib/versionUtils");
5
5
  const downloadReleasesMetadata_1 = require("../data/downloadReleasesMetadata");
6
6
  const calculateRevisionForDevice_1 = require("./calculateRevisionForDevice");
7
- const isNodeJSNetworkError = (e) => ['FetchError', 'AbortError'].includes(e.name);
8
- const isReactNativeNetworkError = (e) => e.name === 'TypeError' && e.message.includes('Network request failed');
9
- const isNetworkError = (e) => {
7
+ const assets_browser_1 = require("../utils/assets-browser");
8
+ const isNotFoundError = (e) => e instanceof assets_browser_1.HttpRequestError && e.response.status === 404;
9
+ const isNodeJSOfflineError = (e) => ['FetchError', 'AbortError'].includes(e.name);
10
+ const isReactNativeOfflineError = (e) => e.name === 'TypeError' && e.message.includes('Network request failed');
11
+ const isOfflineError = (e) => {
10
12
  if (!(e instanceof Error))
11
13
  return false;
12
- return isNodeJSNetworkError(e) || isReactNativeNetworkError(e);
14
+ return isNodeJSOfflineError(e) || isReactNativeOfflineError(e);
13
15
  };
14
16
  const getOnlineReleaseMetadata = async ({ firmwareVersion, internalModel, }) => {
15
17
  const onlineReleases = await (0, downloadReleasesMetadata_1.downloadReleasesMetadata)({ internal_model: internalModel });
@@ -49,7 +51,9 @@ const checkFirmwareRevision = async ({ firmwareVersion, internalModel, deviceRev
49
51
  return { success: true };
50
52
  }
51
53
  catch (e) {
52
- return isNetworkError(e)
54
+ if (isNotFoundError(e))
55
+ return failFirmwareRevisionCheck('firmware-version-unknown');
56
+ return isOfflineError(e)
53
57
  ? failFirmwareRevisionCheck('cannot-perform-check-offline')
54
58
  : failFirmwareRevisionCheck('other-error');
55
59
  }
@@ -71,8 +71,7 @@ export type SolanaComposedTransaction = Static<typeof SolanaComposedTransaction>
71
71
  export declare const SolanaComposedTransaction: import("@trezor/schema-utils").TObject<{
72
72
  serializedTx: import("@trezor/schema-utils").TString;
73
73
  additionalInfo: import("@trezor/schema-utils").TObject<{
74
- isCreatingAccount: import("@trezor/schema-utils").TBoolean;
75
- newTokenAccountProgramName: import("@trezor/schema-utils").TOptional<import("@trezor/schema-utils").TUnion<[import("@trezor/schema-utils").TLiteral<"spl-token">, import("@trezor/schema-utils").TLiteral<"spl-token-2022">]>>;
74
+ newAccountProgramName: import("@trezor/schema-utils").TOptional<import("@trezor/schema-utils").TUnion<[import("@trezor/schema-utils").TLiteral<"spl-token">, import("@trezor/schema-utils").TLiteral<"spl-token-2022">]>>;
76
75
  tokenAccountInfo: import("@trezor/schema-utils").TOptional<import("@trezor/schema-utils").TObject<{
77
76
  baseAddress: import("@trezor/schema-utils").TString;
78
77
  tokenProgram: import("@trezor/schema-utils").TString;
@@ -51,8 +51,7 @@ exports.SolanaComposeTransaction = schema_utils_1.Type.Object({
51
51
  exports.SolanaComposedTransaction = schema_utils_1.Type.Object({
52
52
  serializedTx: schema_utils_1.Type.String(),
53
53
  additionalInfo: schema_utils_1.Type.Object({
54
- isCreatingAccount: schema_utils_1.Type.Boolean(),
55
- newTokenAccountProgramName: schema_utils_1.Type.Optional(exports.SolanaProgramName),
54
+ newAccountProgramName: schema_utils_1.Type.Optional(exports.SolanaProgramName),
56
55
  tokenAccountInfo: schema_utils_1.Type.Optional(exports.SolanaTxTokenAccountInfo),
57
56
  }),
58
57
  });