@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.
- package/CHANGELOG.md +54 -9
- package/README.md +1 -1
- package/lib/api/bitcoin/inputs.js +1 -1
- package/lib/api/cardano/cardanoInputs.d.ts +7 -7
- package/lib/api/cardano/cardanoOutputs.d.ts +22 -22
- package/lib/api/cardano/cardanoTokenBundle.d.ts +5 -5
- package/lib/api/ethereum/api/ethereumSignTypedData.d.ts +56 -56
- package/lib/api/ethereum/ethereumDefinitions.d.ts +20 -20
- package/lib/backend/Blockchain.js +10 -3
- package/lib/constants/nem.d.ts +3 -3
- package/lib/core/index.js +25 -14
- package/lib/data/connectSettings.js +3 -0
- package/lib/data/deviceAuthenticityConfigTypes.d.ts +23 -23
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +17 -13
- package/lib/device/Device.js +22 -16
- package/lib/device/DeviceCommands.d.ts +40 -10
- package/lib/device/DeviceCommands.js +25 -90
- package/lib/device/DeviceList.d.ts +5 -2
- package/lib/device/DeviceList.js +35 -11
- package/lib/device/prompts.d.ts +15 -0
- package/lib/device/prompts.js +63 -0
- package/lib/events/call.d.ts +4 -2
- package/lib/events/call.js +8 -1
- package/lib/events/core.js +1 -0
- package/lib/events/ui-response.d.ts +3 -3
- package/lib/index.js +2 -2
- package/lib/types/api/applySettings.d.ts +13 -13
- package/lib/types/api/authenticateDevice.d.ts +24 -24
- package/lib/types/api/authorizeCoinjoin.d.ts +9 -9
- package/lib/types/api/binance/index.d.ts +142 -142
- package/lib/types/api/bitcoin/index.d.ts +10 -10
- package/lib/types/api/cancelCoinjoinAuthorization.d.ts +1 -1
- package/lib/types/api/cardano/index.d.ts +507 -507
- package/lib/types/api/changeLanguage.d.ts +6 -6
- package/lib/types/api/cipherKeyValue.d.ts +7 -7
- package/lib/types/api/eos/index.d.ts +525 -525
- package/lib/types/api/ethereum/index.d.ts +100 -100
- package/lib/types/api/firmwareUpdate.d.ts +5 -5
- package/lib/types/api/getAccountDescriptor.d.ts +4 -4
- package/lib/types/api/getAddress.d.ts +32 -32
- package/lib/types/api/getOwnershipId.d.ts +24 -24
- package/lib/types/api/getOwnershipProof.d.ts +28 -28
- package/lib/types/api/getPublicKey.d.ts +23 -23
- package/lib/types/api/nem/index.d.ts +611 -611
- package/lib/types/api/nemGetAddress.d.ts +6 -6
- package/lib/types/api/pushTransaction.d.ts +3 -3
- package/lib/types/api/recoveryDevice.d.ts +9 -9
- package/lib/types/api/requestLogin.d.ts +25 -25
- package/lib/types/api/ripple/index.d.ts +21 -21
- package/lib/types/api/solana/index.d.ts +23 -23
- package/lib/types/api/stellar/index.d.ts +581 -581
- package/lib/types/api/tezos/index.d.ts +120 -120
- package/lib/types/api/unlockPath.d.ts +2 -2
- package/lib/types/coinInfo.d.ts +224 -224
- package/lib/types/fees.d.ts +19 -19
- package/lib/types/firmware.d.ts +1 -1
- package/lib/types/params.d.ts +24 -20
- package/lib/types/settings.d.ts +4 -0
- 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
|
|
4
|
-
T2B1: import("@sinclair/typebox
|
|
5
|
-
rootPubKeys: import("@sinclair/typebox
|
|
6
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
9
|
-
rootPubKeys: import("@sinclair/typebox
|
|
10
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
14
|
-
rootPubKeys: import("@sinclair/typebox
|
|
15
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
18
|
-
rootPubKeys: import("@sinclair/typebox
|
|
19
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
23
|
-
rootPubKeys: import("@sinclair/typebox
|
|
24
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
27
|
-
rootPubKeys: import("@sinclair/typebox
|
|
28
|
-
caPubKeys: import("@sinclair/typebox
|
|
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
|
|
33
|
-
T2T1: import("@sinclair/typebox
|
|
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
|
|
36
|
-
timestamp: import("@sinclair/typebox
|
|
35
|
+
version: import("@sinclair/typebox").TNumber;
|
|
36
|
+
timestamp: import("@sinclair/typebox").TString;
|
|
37
37
|
}>]>;
|
|
38
38
|
//# sourceMappingURL=deviceAuthenticityConfigTypes.d.ts.map
|
package/lib/data/version.d.ts
CHANGED
package/lib/data/version.js
CHANGED
|
@@ -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.
|
|
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
|
package/lib/device/Device.d.ts
CHANGED
|
@@ -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
|
|
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,
|
|
21
|
-
[DEVICE.WORD]: (device: Device,
|
|
22
|
-
[DEVICE.PASSPHRASE]: (device: Device, callback:
|
|
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
|
-
|
|
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
|
|
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():
|
|
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
|
package/lib/device/Device.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
534
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
}),
|
|
282
|
+
}), error => Promise.reject(error));
|
|
283
283
|
}
|
|
284
284
|
if (res.type === 'PassphraseRequest') {
|
|
285
|
-
return this.
|
|
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
|
-
},
|
|
291
|
-
throw err || e;
|
|
292
|
-
}));
|
|
289
|
+
}, error => Promise.reject(error));
|
|
293
290
|
}
|
|
294
291
|
if (res.type === 'WordRequest') {
|
|
295
|
-
return this.
|
|
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
|
|
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
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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;
|
package/lib/device/DeviceList.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
132
|
-
device
|
|
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
|
-
|
|
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
|
}
|