@trezor/connect 9.4.1 → 9.4.2-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.
package/CHANGELOG.md CHANGED
@@ -1,15 +1,34 @@
1
- | Package | Stable | Canary |
2
- | :------------------------------: | :----: | :----: |
3
- | npm @trezor/connect | 9.4.1 | - |
4
- | npm @trezor/connect-web | 9.4.1 | - |
5
- | npm @trezor/connect-webextension | 9.4.1 | - |
1
+ | Package | Stable | Canary |
2
+ | :------------------------------: | :----: | :----------: |
3
+ | npm @trezor/connect | 9.4.1 | 9.4.2-beta.1 |
4
+ | npm @trezor/connect-web | 9.4.1 | 9.4.2-beta.1 |
5
+ | npm @trezor/connect-webextension | 9.4.1 | 9.4.2-beta.1 |
6
6
 
7
- | Deployment | Stable | Canary |
8
- | :----------------: | :----: | :----: |
9
- | connect.trezor.io/ | 9.4.1 | - |
7
+ | Deployment | Stable | Canary |
8
+ | :----------------: | :----: | :----------: |
9
+ | connect.trezor.io/ | 9.4.1 | 9.4.2-beta.1 |
10
10
 
11
11
  Use the persistent link [connect.trezor.io/9](https://connect.trezor.io/9/) to access the latest stable version of Connect Explorer.
12
12
 
13
+ ## 9.4.2-beta.1
14
+
15
+ ### Features
16
+
17
+ - feat(connect): return device info with method response (a378def)
18
+ - docs(connect-explorer): flowchart for auto core mode (9501d3d)
19
+ - docs(connect-explorer): diagram and explanation for core in popup (3bbb032)
20
+
21
+ ### Fixes
22
+
23
+ - Fixing an issue with typescript not being able to resolve @sinclair/typebox and USB types correctly ((98d6437))
24
+ - Fixing regression that made it impossible to acquire (steal) device session over webusb (5cf83b4)
25
+ - Couple of other fixes and improvements of device handling:
26
+
27
+ - fix(connect): pending transport event fix (231899f)
28
+ - fix(connect): DeviceList create devices sequentially (b4a915b)
29
+
30
+ - fix(connect-explorer): icons on index page (fef3791)
31
+
13
32
  ## 9.4.1
14
33
 
15
34
  Automatic retry for no transport issue: If the transport (bridge) is initially not available, the automatic retry feature allows the user to continue after starting the transport, without having to restart the entire flow.
@@ -28,7 +47,7 @@ NodeBridge new version compatibility fix: Resolved an issue where NodeBridge ver
28
47
  - docs(connect-explorer): step by step tutorial to build connect webextension (9d5ba70)
29
48
  - docs(connect-explorer): add more ways to test getAccountInfo (62101d6)
30
49
 
31
- ### Fixes:
50
+ ### Fixes
32
51
 
33
52
  - New NodeBridge version not parsed correctly - ignore semver labels in version utils (6501704)
34
53
  - fw releases value for custom device model (265028d)
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @trezor/connect
2
2
 
3
- API version 9.4.1
3
+ API version 9.4.2-beta.1
4
4
 
5
5
  [![Build Status](https://github.com/trezor/trezor-suite/actions/workflows/test-connect.yml/badge.svg)](https://github.com/trezor/trezor-suite/actions/workflows/test-connect.yml)
6
6
  [![NPM](https://img.shields.io/npm/v/@trezor/connect.svg)](https://www.npmjs.org/package/@trezor/connect)
@@ -36,7 +36,7 @@ exports.validateTrezorInputs = validateTrezorInputs;
36
36
  const enhanceTrezorInputs = (inputs, rawTxs) => {
37
37
  inputs.forEach(input => {
38
38
  if (!input.amount) {
39
- console.warn('TrezorConnect.singTransaction deprecation: missing input amount.');
39
+ console.warn('TrezorConnect.signTransaction deprecation: missing input amount.');
40
40
  const refTx = rawTxs.find(t => t.getId() === input.prev_hash);
41
41
  if (refTx && refTx.outs[input.prev_index]) {
42
42
  input.amount = refTx.outs[input.prev_index].value;
package/lib/core/index.js CHANGED
@@ -250,7 +250,7 @@ const inner = async (context, method, device) => {
250
250
  }
251
251
  try {
252
252
  const response = await method.run();
253
- return (0, events_2.createResponseMessage)(method.responseID, true, response);
253
+ return (0, events_2.createResponseMessage)(method.responseID, true, response, device);
254
254
  }
255
255
  catch (error) {
256
256
  return Promise.reject(error);
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "9.4.1";
1
+ export declare const VERSION = "9.4.2-beta.1";
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.1';
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
@@ -84,7 +84,7 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
84
84
  message: string;
85
85
  }>;
86
86
  private _uploadTranslationData;
87
- _updateFeatures(feat: Features): void;
87
+ private _updateFeatures;
88
88
  isUnacquired(): boolean;
89
89
  disconnect(): void;
90
90
  isBootloader(): boolean;
@@ -99,7 +99,7 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
99
99
  isRunning(): boolean;
100
100
  isLoaded(): boolean;
101
101
  waitForFirstRun(): Promise<boolean>;
102
- getDevicePath(): `${number}`;
102
+ getDevicePath(): import("@trezor/transport/lib/types").PathPublic;
103
103
  isT1(): boolean;
104
104
  hasUnexpectedMode(allow: string[], require: string[]): "ui-device_bootloader_mode" | "ui-device_not_in_bootloader_mode" | "ui-device_not_initialized" | "ui-device_seedless" | null;
105
105
  updateDescriptor(descriptor: Descriptor): void;
@@ -161,7 +161,9 @@ class Device extends utils_1.TypedEmitter {
161
161
  this.runPromise.reject(constants_1.ERRORS.TypedError('Device_UsedElsewhere'));
162
162
  delete this.runPromise;
163
163
  }
164
- this.transport.releaseDevice(this.originalDescriptor.path);
164
+ if (this.originalDescriptor.session) {
165
+ this.transport.releaseDevice(this.originalDescriptor.session);
166
+ }
165
167
  }
166
168
  async _runInner(fn, options) {
167
169
  var _a, _b;
@@ -34,6 +34,7 @@ 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?;
@@ -44,6 +45,8 @@ export declare class DeviceList extends TypedEmitter<DeviceListEvents> implement
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;
@@ -46,6 +46,7 @@ class DeviceList extends utils_1.TypedEmitter {
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
51
  const abortController = new AbortController();
51
52
  this.authPenaltyManager = createAuthPenaltyManager(priority);
@@ -104,6 +105,7 @@ class DeviceList extends utils_1.TypedEmitter {
104
105
  this.creatingDevicesDescriptors[path] = descriptor;
105
106
  switch (category.type) {
106
107
  case 'disconnected':
108
+ this.removeFromCreateDevicesQueue(path);
107
109
  if (!device)
108
110
  break;
109
111
  device.disconnect();
@@ -111,6 +113,9 @@ class DeviceList extends utils_1.TypedEmitter {
111
113
  this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
112
114
  break;
113
115
  case 'connected':
116
+ if (!(await this.waitForCreateDevicesQueue(path))) {
117
+ break;
118
+ }
114
119
  const penalty = this.authPenaltyManager.get();
115
120
  if (penalty) {
116
121
  await (0, promiseUtils_1.resolveAfter)(501 + penalty, null).promise;
@@ -123,14 +128,18 @@ class DeviceList extends utils_1.TypedEmitter {
123
128
  this.devices[path] = device;
124
129
  this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
125
130
  }
131
+ this.removeFromCreateDevicesQueue(path);
126
132
  break;
127
133
  case 'acquired':
128
- if (!device)
129
- break;
130
134
  if (category.subtype === 'elsewhere') {
131
- device.featuresNeedsReload = true;
132
- device.interruptionFromOutside();
135
+ this.removeFromCreateDevicesQueue(path);
136
+ if (device) {
137
+ device.featuresNeedsReload = true;
138
+ device.interruptionFromOutside();
139
+ }
133
140
  }
141
+ if (!device)
142
+ break;
134
143
  _log.debug('Event', events_1.DEVICE.CHANGED, device.toMessageObject());
135
144
  this.emit(events_1.DEVICE.CHANGED, device.toMessageObject());
136
145
  _log.debug('Event', events_1.DEVICE.ACQUIRED, device.toMessageObject());
@@ -159,6 +168,20 @@ class DeviceList extends utils_1.TypedEmitter {
159
168
  device === null || device === void 0 ? void 0 : device.updateDescriptor(descriptor);
160
169
  });
161
170
  }
171
+ async waitForCreateDevicesQueue(path) {
172
+ const dfd = (0, utils_1.createDeferred)(path);
173
+ const prevQueue = this.createDevicesQueue.slice();
174
+ this.createDevicesQueue.push(dfd);
175
+ await (0, utils_1.promiseAllSequence)(prevQueue.map(pr => () => pr.promise));
176
+ return this.createDevicesQueue.includes(dfd);
177
+ }
178
+ removeFromCreateDevicesQueue(path) {
179
+ const index = this.createDevicesQueue.findIndex(dfd => dfd.id === path);
180
+ if (index >= 0) {
181
+ const [dfd] = this.createDevicesQueue.splice(index, 1);
182
+ dfd.resolve();
183
+ }
184
+ }
162
185
  init(initParams = {}) {
163
186
  if (!this.initPromise) {
164
187
  _log.debug('Initializing transports');
@@ -210,12 +233,12 @@ class DeviceList extends utils_1.TypedEmitter {
210
233
  throw new Error(enumerateResult.error);
211
234
  }
212
235
  const descriptors = enumerateResult.payload;
236
+ const waitForDevicesPromise = initParams.pendingTransportEvent && descriptors.length
237
+ ? this.waitForDevices(descriptors.length, 10000)
238
+ : Promise.resolve();
213
239
  transport.handleDescriptorsChange(descriptors);
214
240
  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
- }
241
+ await waitForDevicesPromise;
219
242
  return transport;
220
243
  }
221
244
  waitForDevices(deviceCount, autoResolveMs) {
@@ -294,6 +317,8 @@ class DeviceList extends utils_1.TypedEmitter {
294
317
  devices.forEach(device => {
295
318
  this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
296
319
  });
320
+ this.createDevicesQueue.forEach(dfd => dfd.resolve());
321
+ this.createDevicesQueue = [];
297
322
  await Promise.all(devices.map(device => device.dispose()));
298
323
  transport === null || transport === void 0 ? void 0 : transport.stop();
299
324
  }
@@ -1,6 +1,7 @@
1
1
  import type { IFRAME } from './iframe';
2
2
  import type { TrezorConnect } from '../types/api';
3
- import type { CommonParams } from '../types/params';
3
+ import type { CommonParams, DeviceIdentity } from '../types/params';
4
+ import { Device } from '../device/Device';
4
5
  type UnwrappedResponse<T> = T extends Promise<infer R> ? (R extends {
5
6
  success: true;
6
7
  payload: infer P;
@@ -35,7 +36,8 @@ export interface MethodResponseMessage {
35
36
  id: number;
36
37
  success: boolean;
37
38
  payload: CallMethodResponse<keyof CallApi>;
39
+ device?: DeviceIdentity;
38
40
  }
39
- export declare const createResponseMessage: (id: number, success: boolean, payload: any) => MethodResponseMessage;
41
+ export declare const createResponseMessage: (id: number, success: boolean, payload: any, device?: Device) => MethodResponseMessage;
40
42
  export {};
41
43
  //# sourceMappingURL=call.d.ts.map
@@ -3,12 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createResponseMessage = exports.RESPONSE_EVENT = void 0;
4
4
  const errors_1 = require("../constants/errors");
5
5
  exports.RESPONSE_EVENT = 'RESPONSE_EVENT';
6
- const createResponseMessage = (id, success, payload) => ({
6
+ const createResponseMessage = (id, success, payload, device) => ({
7
7
  event: exports.RESPONSE_EVENT,
8
8
  type: exports.RESPONSE_EVENT,
9
9
  id,
10
10
  success,
11
11
  payload: success ? payload : (0, errors_1.serializeError)(payload),
12
+ device: device
13
+ ? {
14
+ path: device === null || device === void 0 ? void 0 : device.originalDescriptor.path,
15
+ state: device === null || device === void 0 ? void 0 : device.getState(),
16
+ instance: device === null || device === void 0 ? void 0 : device.instance,
17
+ }
18
+ : undefined,
12
19
  });
13
20
  exports.createResponseMessage = createResponseMessage;
14
21
  //# sourceMappingURL=call.js.map
@@ -7,6 +7,7 @@ const parseMessage = (messageData) => {
7
7
  event: messageData.event,
8
8
  type: messageData.type,
9
9
  payload: messageData.payload,
10
+ device: messageData.device,
10
11
  };
11
12
  if (typeof messageData.id === 'number') {
12
13
  message.id = messageData.id;
package/lib/index.js CHANGED
@@ -38,8 +38,8 @@ const onCoreEvent = (message) => {
38
38
  _log.debug('handleMessage', message);
39
39
  switch (event) {
40
40
  case events_2.RESPONSE_EVENT: {
41
- const { id = 0, success } = message;
42
- const resolved = messagePromises.resolve(id, { id, success, payload });
41
+ const { id = 0, success, device } = message;
42
+ const resolved = messagePromises.resolve(id, { id, success, payload, device });
43
43
  if (!resolved)
44
44
  _log.warn(`Unknown message id ${id}`);
45
45
  break;
@@ -1,11 +1,12 @@
1
1
  import { TSchema, Static } from '@trezor/schema-utils';
2
2
  import { DeviceState } from './device';
3
+ export interface DeviceIdentity {
4
+ path?: string;
5
+ state?: string | DeviceState;
6
+ instance?: number;
7
+ }
3
8
  export interface CommonParams {
4
- device?: {
5
- path?: string;
6
- state?: string | DeviceState;
7
- instance?: number;
8
- };
9
+ device?: DeviceIdentity;
9
10
  useEmptyPassphrase?: boolean;
10
11
  useEventListener?: boolean;
11
12
  allowSeedlessDevice?: boolean;
@@ -40,7 +41,10 @@ export interface Success<T> {
40
41
  success: true;
41
42
  payload: T;
42
43
  }
43
- export type Response<T> = Promise<Success<T> | Unsuccessful>;
44
+ export interface SuccessWithDevice<T> extends Success<T> {
45
+ device?: DeviceIdentity;
46
+ }
47
+ export type Response<T> = Promise<SuccessWithDevice<T> | Unsuccessful>;
44
48
  export type DerivationPath = string | number[];
45
49
  export declare const DerivationPath: import("@sinclair/typebox/build/esm/index.mjs").TUnion<[import("@sinclair/typebox/build/esm/index.mjs").TString, import("@sinclair/typebox/build/esm/index.mjs").TArray<import("@sinclair/typebox/build/esm/index.mjs").TNumber>]>;
46
50
  type ProtoWithExtendedAddressN<T, A, R> = Omit<Extract<T, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trezor/connect",
3
- "version": "9.4.1",
3
+ "version": "9.4.2-beta.1",
4
4
  "author": "Trezor <info@trezor.io>",
5
5
  "homepage": "https://github.com/trezor/trezor-suite/tree/develop/packages/connect",
6
6
  "description": "High-level javascript interface for Trezor hardware wallet.",
@@ -76,11 +76,11 @@
76
76
  "@trezor/blockchain-link": "2.3.1",
77
77
  "@trezor/blockchain-link-types": "1.2.1",
78
78
  "@trezor/connect-analytics": "1.2.1",
79
- "@trezor/connect-common": "0.2.1",
80
- "@trezor/protobuf": "1.2.1",
79
+ "@trezor/connect-common": "0.2.2-beta.1",
80
+ "@trezor/protobuf": "1.2.2-beta.1",
81
81
  "@trezor/protocol": "1.2.1",
82
82
  "@trezor/schema-utils": "1.2.1",
83
- "@trezor/transport": "1.3.1",
83
+ "@trezor/transport": "1.3.2-beta.1",
84
84
  "@trezor/utils": "9.2.1",
85
85
  "@trezor/utxo-lib": "2.2.1",
86
86
  "blakejs": "^1.2.1",