@trezor/connect 9.6.3-beta.2 → 9.6.4-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 +16 -9
- package/README.md +1 -1
- package/lib/api/applyFlags.d.ts +1 -1
- package/lib/api/applyFlags.js +2 -2
- package/lib/api/applySettings.d.ts +1 -1
- package/lib/api/authenticateDevice.js +4 -0
- package/lib/api/authorizeCoinjoin.d.ts +1 -1
- package/lib/api/backupDevice.d.ts +1 -1
- package/lib/api/backupDevice.js +2 -2
- package/lib/api/bitcoin/TransactionComposer.d.ts +1 -1
- package/lib/api/bitcoin/inputs.d.ts +1 -1
- package/lib/api/bitcoin/transactionBytes.d.ts +2 -2
- package/lib/api/bleUnpair.js +1 -1
- package/lib/api/cancelCoinjoinAuthorization.d.ts +1 -1
- package/lib/api/cardano/api/cardanoSignTransaction.d.ts +2 -2
- package/lib/api/cardano/cardanoInputs.js +2 -2
- package/lib/api/changePin.d.ts +1 -1
- package/lib/api/changePin.js +2 -2
- package/lib/api/changeWipeCode.d.ts +1 -1
- package/lib/api/cipherKeyValue.d.ts +1 -1
- package/lib/api/eos/api/eosGetPublicKey.d.ts +1 -1
- package/lib/api/eos/api/eosSignTransaction.d.ts +1 -1
- package/lib/api/eos/eosSignTx.d.ts +20 -20
- package/lib/api/ethereum/api/ethereumGetPublicKey.d.ts +5 -5
- package/lib/api/ethereum/api/ethereumSignMessage.d.ts +1 -2
- package/lib/api/ethereum/api/ethereumVerifyMessage.d.ts +1 -1
- package/lib/api/evoluGetNode.d.ts +1 -1
- package/lib/api/evoluGetNode.js +2 -2
- package/lib/api/firmware/calculateFirmwareHash.d.ts +9 -2
- package/lib/api/firmware/calculateFirmwareHash.js +11 -1
- package/lib/api/firmware/verifyAuthenticityProof.d.ts +3 -1
- package/lib/api/firmware/verifyAuthenticityProof.js +10 -15
- package/lib/api/getCoinInfo.d.ts +34 -34
- package/lib/api/getFeatures.d.ts +1 -0
- package/lib/api/getFirmwareHash.d.ts +1 -1
- package/lib/api/getFirmwareHash.js +2 -2
- package/lib/api/getNonce.d.ts +1 -1
- package/lib/api/getOwnershipId.d.ts +1 -1
- package/lib/api/getOwnershipId.js +2 -2
- package/lib/api/getOwnershipProof.d.ts +1 -1
- package/lib/api/getOwnershipProof.js +2 -2
- package/lib/api/getPublicKey.d.ts +5 -5
- package/lib/api/loadDevice.d.ts +1 -1
- package/lib/api/loadDevice.js +2 -2
- package/lib/api/nem/api/nemSignTransaction.d.ts +1 -1
- package/lib/api/nem/nemSignTx.d.ts +9 -9
- package/lib/api/recoveryDevice.d.ts +1 -1
- package/lib/api/requestLogin.d.ts +1 -1
- package/lib/api/ripple/api/rippleSignTransaction.d.ts +1 -1
- package/lib/api/setBrightness.d.ts +1 -1
- package/lib/api/setBrightness.js +2 -2
- package/lib/api/setBusy.d.ts +1 -1
- package/lib/api/setBusy.js +2 -2
- package/lib/api/showDeviceTutorial.d.ts +1 -1
- package/lib/api/signMessage.d.ts +1 -1
- package/lib/api/solana/api/solanaComposeTransaction.d.ts +6 -0
- package/lib/api/solana/api/solanaComposeTransaction.js +9 -0
- package/lib/api/solana/api/solanaSignTransaction.js +4 -4
- package/lib/api/tezos/api/tezosGetPublicKey.d.ts +1 -1
- package/lib/api/tezos/api/tezosSignTransaction.d.ts +1 -1
- package/lib/api/tezos/tezosSignTx.d.ts +17 -17
- package/lib/api/unlockPath.d.ts +1 -1
- package/lib/core/AbstractMethod.d.ts +4 -1
- package/lib/core/index.js +8 -1
- package/lib/core/onCallFirmwareUpdate.js +42 -51
- package/lib/data/coinInfo.d.ts +94 -93
- package/lib/data/config.js +9 -1
- package/lib/data/defaultFeeLevels.d.ts +1 -1
- package/lib/data/defaultFeeLevels.js +1 -1
- package/lib/data/deviceAuthenticityBlacklist.d.ts +3 -0
- package/lib/data/deviceAuthenticityBlacklist.js +11 -0
- package/lib/data/deviceAuthenticityBlacklistConfig.d.ts +11 -0
- package/lib/data/deviceAuthenticityBlacklistConfig.js +15 -0
- package/lib/data/deviceAuthenticityConfig.js +4 -140
- package/lib/data/deviceAuthenticityConfigTypes.d.ts +0 -9
- package/lib/data/deviceAuthenticityConfigTypes.js +3 -5
- package/lib/data/firmwareInfo.d.ts +12 -7
- package/lib/data/firmwareInfo.js +58 -15
- package/lib/data/transportInfo.d.ts +11 -1
- package/lib/data/udevInfo.d.ts +9 -1
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +20 -10
- package/lib/device/Device.js +95 -23
- package/lib/device/DeviceCommands.d.ts +4 -4
- package/lib/device/DeviceCurrentSession.d.ts +242 -242
- package/lib/device/DeviceCurrentSession.js +1 -1
- package/lib/device/DeviceList.d.ts +7 -4
- package/lib/device/DeviceList.js +14 -4
- package/lib/device/StateStorage.d.ts +1 -1
- package/lib/device/checkFirmwareRevision.d.ts +1 -1
- package/lib/device/checkFirmwareRevision.js +2 -2
- package/lib/device/thp/handshake.d.ts +1 -1
- package/lib/device/thp/handshake.js +14 -3
- package/lib/device/thp/index.d.ts +1 -1
- package/lib/device/thp/index.js +29 -4
- package/lib/device/thp/pairing.js +1 -3
- package/lib/device/thp/session.js +1 -1
- package/lib/device/workflow/checkFirmwareHash.js +6 -1
- package/lib/device/workflow/handshake.js +3 -7
- package/lib/device/workflow/trezorPushNotification.d.ts +3 -0
- package/lib/device/workflow/trezorPushNotification.js +76 -0
- package/lib/device/workflow/validateState.js +3 -0
- package/lib/events/call.d.ts +1 -1
- package/lib/events/device.d.ts +11 -3
- package/lib/events/device.js +5 -1
- package/lib/events/popup.d.ts +1 -1
- package/lib/events/transport.d.ts +3 -21
- package/lib/events/ui-request.d.ts +15 -8
- package/lib/tsconfig.lib.tsbuildinfo +1 -1
- package/lib/types/api/applyFlags.d.ts +1 -1
- package/lib/types/api/applySettings.d.ts +1 -0
- package/lib/types/api/authenticateDevice.d.ts +9 -10
- package/lib/types/api/authenticateDevice.js +2 -0
- package/lib/types/api/backupDevice.d.ts +1 -1
- package/lib/types/api/bitcoin/index.d.ts +1 -1
- package/lib/types/api/bleUnpair.d.ts +1 -1
- package/lib/types/api/cancelCoinjoinAuthorization.d.ts +1 -1
- package/lib/types/api/cardanoComposeTransaction.d.ts +2 -2
- package/lib/types/api/cardanoComposeTransaction.js +2 -2
- package/lib/types/api/changePin.d.ts +1 -1
- package/lib/types/api/changeWipeCode.d.ts +1 -1
- package/lib/types/api/composeTransaction.d.ts +1 -1
- package/lib/types/api/discoverAccounts.d.ts +1 -1
- package/lib/types/api/discoverAccounts.js +1 -1
- package/lib/types/api/eosSignTransaction.d.ts +1 -1
- package/lib/types/api/ethereum/index.d.ts +8 -8
- package/lib/types/api/ethereumSignMessage.d.ts +1 -1
- package/lib/types/api/ethereumSignTypedData.d.ts +1 -1
- package/lib/types/api/ethereumVerifyMessage.d.ts +1 -1
- package/lib/types/api/getAccountInfo.d.ts +1 -1
- package/lib/types/api/getAddress.d.ts +6 -6
- package/lib/types/api/getFirmwareHash.d.ts +1 -1
- package/lib/types/api/nemGetAddress.d.ts +1 -1
- package/lib/types/api/nemSignTransaction.d.ts +1 -1
- package/lib/types/api/recoveryDevice.d.ts +2 -2
- package/lib/types/api/setBusy.d.ts +1 -1
- package/lib/types/api/setProxy.d.ts +1 -1
- package/lib/types/api/showDeviceTutorial.d.ts +1 -1
- package/lib/types/api/signMessage.d.ts +1 -1
- package/lib/types/api/solana/index.d.ts +26 -3
- package/lib/types/api/solana/index.js +19 -3
- package/lib/types/api/tezosSignTransaction.d.ts +1 -1
- package/lib/types/api/thpRemoveCredentials.d.ts +1 -1
- package/lib/types/api/unlockPath.d.ts +1 -1
- package/lib/types/api/verifyMessage.d.ts +1 -1
- package/lib/types/api/wipeDevice.d.ts +1 -1
- package/lib/types/device.d.ts +9 -4
- package/lib/types/device.js +5 -3
- package/lib/types/firmware.d.ts +1 -0
- package/lib/types/settings.d.ts +2 -2
- package/lib/types/workflow.d.ts +4 -0
- package/lib/utils/assetUtils.d.ts +6 -4
- package/lib/utils/assetUtils.js +13 -2
- package/lib/utils/assets-browser.d.ts +0 -4
- package/lib/utils/assets-browser.js +3 -11
- package/lib/utils/assets.native.js +1 -1
- package/lib/utils/deviceFeaturesUtils.d.ts +1 -1
- package/lib/utils/firmwareUtils.d.ts +7 -4
- package/lib/utils/firmwareUtils.js +21 -14
- package/lib/utils/pathUtils.d.ts +3 -2
- package/lib/utils/uiPromiseManager.d.ts +9 -9
- package/package.json +16 -15
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TRANSPORT } from '@trezor/transport';
|
|
2
|
-
import type { TransportApiType } from '@trezor/transport/lib/transports/abstract';
|
|
3
2
|
import { TypedEmitter } from '@trezor/utils';
|
|
4
|
-
import { DEVICE, TransportError, TransportInfo } from '../events';
|
|
3
|
+
import { DEVICE, DecodedTrezorPushNotification, TransportError, TransportInfo } from '../events';
|
|
5
4
|
import { Device } from './Device';
|
|
6
5
|
import { ConnectSettings, DeviceUniquePath, StaticSessionId } from '../types';
|
|
7
6
|
interface DeviceListEvents {
|
|
@@ -9,6 +8,9 @@ interface DeviceListEvents {
|
|
|
9
8
|
[TRANSPORT.ERROR]: TransportError;
|
|
10
9
|
[DEVICE.CONNECT]: Device;
|
|
11
10
|
[DEVICE.CONNECT_UNACQUIRED]: Device;
|
|
11
|
+
[DEVICE.TREZOR_PUSH_NOTIFICATION]: DecodedTrezorPushNotification & {
|
|
12
|
+
device: Device;
|
|
13
|
+
};
|
|
12
14
|
[DEVICE.DISCONNECT]: Device;
|
|
13
15
|
[DEVICE.CHANGED]: Device;
|
|
14
16
|
}
|
|
@@ -39,8 +41,8 @@ export declare class DeviceList extends TypedEmitter<DeviceListEvents> implement
|
|
|
39
41
|
isConnected(): this is DeviceList;
|
|
40
42
|
pendingConnection(): Promise<void> | undefined;
|
|
41
43
|
getActiveTransports(): {
|
|
42
|
-
apiType:
|
|
43
|
-
type: "BridgeTransport" | "NodeUsbTransport" | "WebUsbTransport" | "UdpTransport" | "NativeUsbTransport" | "BluetoothTransport";
|
|
44
|
+
apiType: "usb" | "bluetooth" | "udp";
|
|
45
|
+
type: "BridgeTransport" | "NodeUsbTransport" | "WebUsbTransport" | "UdpTransport" | "NativeUsbTransport" | "BluetoothTransport" | "NativeBluetoothTransport";
|
|
44
46
|
version: string;
|
|
45
47
|
outdated: boolean;
|
|
46
48
|
}[];
|
|
@@ -51,6 +53,7 @@ export declare class DeviceList extends TypedEmitter<DeviceListEvents> implement
|
|
|
51
53
|
private initializeTransport;
|
|
52
54
|
private waitForDevices;
|
|
53
55
|
getDeviceCount(): number;
|
|
56
|
+
getPrioritizedDevices(): Device[];
|
|
54
57
|
getAllDevices(): readonly Device[];
|
|
55
58
|
getOnlyDevice(): Device | undefined;
|
|
56
59
|
getDeviceByPath(path: DeviceUniquePath): Device | undefined;
|
package/lib/device/DeviceList.js
CHANGED
|
@@ -81,7 +81,7 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
81
81
|
}
|
|
82
82
|
async onDeviceConnected(descriptor, transport) {
|
|
83
83
|
const id = (this.deviceCounter++).toString(16).slice(-8);
|
|
84
|
-
const device = new Device_1.Device({ id: (0, types_1.
|
|
84
|
+
const device = new Device_1.Device({ id: (0, types_1.asDeviceUniquePath)(id), transport, descriptor });
|
|
85
85
|
const penalty = this.authPenaltyManager.get();
|
|
86
86
|
const stillConnected = await this.handshakeLock(() => (0, utils_1.resolveAfter)(penalty && penalty + 501).then(() => device.handshake()));
|
|
87
87
|
if (!stillConnected) {
|
|
@@ -91,6 +91,12 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
91
91
|
device.lifecycle.on(events_1.DEVICE.CONNECT, () => this.emit(events_1.DEVICE.CONNECT, device));
|
|
92
92
|
device.lifecycle.on(events_1.DEVICE.CHANGED, () => this.emit(events_1.DEVICE.CHANGED, device));
|
|
93
93
|
device.lifecycle.on(events_1.DEVICE.CONNECT_UNACQUIRED, () => this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device));
|
|
94
|
+
device.lifecycle.on(events_1.DEVICE.TREZOR_PUSH_NOTIFICATION, payload => {
|
|
95
|
+
this.emit(events_1.DEVICE.TREZOR_PUSH_NOTIFICATION, {
|
|
96
|
+
device,
|
|
97
|
+
...payload,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
94
100
|
device.lifecycle.on(events_1.DEVICE.DISCONNECT, () => {
|
|
95
101
|
device.lifecycle.removeAllListeners();
|
|
96
102
|
this.authPenaltyManager.remove(device);
|
|
@@ -153,18 +159,22 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
153
159
|
getDeviceCount() {
|
|
154
160
|
return this.devices.length;
|
|
155
161
|
}
|
|
162
|
+
getPrioritizedDevices() {
|
|
163
|
+
return [...this.devices].sort((a, b) => (a.descriptor.apiType === 'bluetooth' ? 1 : 0) -
|
|
164
|
+
(b.descriptor.apiType === 'bluetooth' ? 1 : 0));
|
|
165
|
+
}
|
|
156
166
|
getAllDevices() {
|
|
157
|
-
return this.
|
|
167
|
+
return this.getPrioritizedDevices();
|
|
158
168
|
}
|
|
159
169
|
getOnlyDevice() {
|
|
160
170
|
return this.devices.length === 1 ? this.devices[0] : undefined;
|
|
161
171
|
}
|
|
162
172
|
getDeviceByPath(path) {
|
|
163
|
-
return this.
|
|
173
|
+
return this.getPrioritizedDevices().find(d => d.getUniquePath() === path);
|
|
164
174
|
}
|
|
165
175
|
getDeviceByStaticState(state) {
|
|
166
176
|
const deviceId = state.split('@')[1].split(':')[0];
|
|
167
|
-
return this.
|
|
177
|
+
return this.getPrioritizedDevices().find(d => d.features?.device_id === deviceId);
|
|
168
178
|
}
|
|
169
179
|
async dispose() {
|
|
170
180
|
this.removeAllListeners();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FirmwareType, VersionArray } from '@trezor/device-utils';
|
|
2
|
-
import { PROTO } from '
|
|
2
|
+
import { MessagesSchema as PROTO } from '@trezor/protobuf';
|
|
3
3
|
import { FirmwareRevisionCheckResult } from '../types/device';
|
|
4
4
|
export type CheckFirmwareRevisionParams = {
|
|
5
5
|
firmwareVersion: VersionArray;
|
|
@@ -4,8 +4,8 @@ exports.checkFirmwareRevision = void 0;
|
|
|
4
4
|
const utils_1 = require("@trezor/utils");
|
|
5
5
|
const calculateRevisionForDevice_1 = require("./calculateRevisionForDevice");
|
|
6
6
|
const firmwareInfo_1 = require("../data/firmwareInfo");
|
|
7
|
-
const
|
|
8
|
-
const isNotFoundError = (e) => e instanceof
|
|
7
|
+
const assetUtils_1 = require("../utils/assetUtils");
|
|
8
|
+
const isNotFoundError = (e) => e instanceof assetUtils_1.HttpRequestError && e.response.status === 404;
|
|
9
9
|
const isNodeJSOfflineError = (e) => ['FetchError', 'AbortError'].includes(e.name);
|
|
10
10
|
const isReactNativeOfflineError = (e) => e.name === 'TypeError' && e.message.includes('Network request failed');
|
|
11
11
|
const isAbortControllerTimeout = (e) => e.name === 'AbortError' ||
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Device } from '../Device';
|
|
2
2
|
export declare const createThpChannel: (device: Device) => Promise<void>;
|
|
3
|
-
export declare const thpHandshake: (device: Device) => Promise<void>;
|
|
3
|
+
export declare const thpHandshake: (device: Device, unlockPin?: boolean) => Promise<void>;
|
|
4
4
|
//# sourceMappingURL=handshake.d.ts.map
|
|
@@ -38,7 +38,7 @@ const createThpChannel = async (device) => {
|
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
exports.createThpChannel = createThpChannel;
|
|
41
|
-
const thpHandshake = async (device) => {
|
|
41
|
+
const thpHandshake = async (device, unlockPin = false) => {
|
|
42
42
|
const thpState = device.getThpState();
|
|
43
43
|
if (!thpState?.handshakeCredentials) {
|
|
44
44
|
throw constants_1.ERRORS.TypedError('Device_ThpStateMissing');
|
|
@@ -49,9 +49,11 @@ const thpHandshake = async (device) => {
|
|
|
49
49
|
: (0, crypto_1.randomBytes)(32);
|
|
50
50
|
const hostStaticKeys = protocol_1.thp.getCurve25519KeyPair(staticKey);
|
|
51
51
|
const knownCredentials = (settings?.knownCredentials || []).sort(cre => cre.autoconnect ? -1 : 1);
|
|
52
|
+
const tryToUnlock = unlockPin ? 1 : 0;
|
|
52
53
|
const hostEphemeralKeys = protocol_1.thp.getCurve25519KeyPair((0, crypto_1.randomBytes)(32));
|
|
53
54
|
const handshakeInit = await (0, thpCall_1.thpCall)(device, 'ThpHandshakeInitRequest', {
|
|
54
55
|
key: hostEphemeralKeys.publicKey,
|
|
56
|
+
tryToUnlock,
|
|
55
57
|
});
|
|
56
58
|
const { trezorEncryptedStaticPubkey } = handshakeInit.message;
|
|
57
59
|
const handshakeCredentials = protocol_1.thp.handleHandshakeInit({
|
|
@@ -60,6 +62,7 @@ const thpHandshake = async (device) => {
|
|
|
60
62
|
hostStaticKeys,
|
|
61
63
|
hostEphemeralKeys,
|
|
62
64
|
knownCredentials,
|
|
65
|
+
tryToUnlock,
|
|
63
66
|
protobufEncoder: (name, data) => (0, protobuf_1.encodeMessage)(device.transport.getMessages(), name, data),
|
|
64
67
|
});
|
|
65
68
|
const { hostKey, trezorKey, hostEncryptedStaticPubkey } = handshakeCredentials;
|
|
@@ -77,9 +80,17 @@ const thpHandshake = async (device) => {
|
|
|
77
80
|
hostPubkey: hostEncryptedStaticPubkey,
|
|
78
81
|
encryptedPayload: handshakeCredentials.encryptedPayload,
|
|
79
82
|
});
|
|
80
|
-
|
|
83
|
+
if (!handshakeCompletion.message.state && handshakeCredentials.credentials) {
|
|
84
|
+
thpState.removePairingCredential(handshakeCredentials.credentials);
|
|
85
|
+
const { credential } = handshakeCredentials.credentials;
|
|
86
|
+
const index = settings?.knownCredentials?.findIndex(c => c.credential === credential) ?? -1;
|
|
87
|
+
if (index >= 0) {
|
|
88
|
+
settings?.knownCredentials?.splice(index, 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
thpState.setIsPaired(handshakeCompletion.message.state !== 0);
|
|
81
92
|
thpState.setPhase('pairing');
|
|
82
|
-
if (thpState.
|
|
93
|
+
if (thpState.isAutoconnectPaired || handshakeCompletion.message.state === 2) {
|
|
83
94
|
await (0, thpCall_1.thpCall)(device, 'ThpEndRequest', {});
|
|
84
95
|
thpState.setPhase('paired');
|
|
85
96
|
}
|
|
@@ -2,5 +2,5 @@ import type { Device } from '../Device';
|
|
|
2
2
|
export { abortThpWorkflow } from './thpCall';
|
|
3
3
|
export { getThpCredentials } from './pairing';
|
|
4
4
|
export { createThpSession } from './session';
|
|
5
|
-
export declare const getThpChannel: (device: Device, withInteraction?: boolean) => Promise<
|
|
5
|
+
export declare const getThpChannel: (device: Device, withInteraction?: boolean) => Promise<"pin-locked" | "thp-locked" | undefined>;
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/device/thp/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getThpChannel = exports.createThpSession = exports.getThpCredentials = exports.abortThpWorkflow = void 0;
|
|
4
|
+
const device_1 = require("../../events/device");
|
|
4
5
|
const handshake_1 = require("./handshake");
|
|
5
6
|
const pairing_1 = require("./pairing");
|
|
6
7
|
var thpCall_1 = require("./thpCall");
|
|
@@ -11,17 +12,41 @@ var session_1 = require("./session");
|
|
|
11
12
|
Object.defineProperty(exports, "createThpSession", { enumerable: true, get: function () { return session_1.createThpSession; } });
|
|
12
13
|
const getThpChannel = async (device, withInteraction) => {
|
|
13
14
|
const thpState = device.getThpState();
|
|
15
|
+
if (!thpState)
|
|
16
|
+
return;
|
|
14
17
|
try {
|
|
15
|
-
if (thpState
|
|
18
|
+
if (thpState.phase === 'handshake') {
|
|
16
19
|
await (0, handshake_1.createThpChannel)(device);
|
|
17
|
-
|
|
20
|
+
try {
|
|
21
|
+
await (0, handshake_1.thpHandshake)(device);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const isPinLocked = error.code === 'ThpDeviceLocked';
|
|
25
|
+
const isTransportBusy = error.message === 'ThpTransportBusy';
|
|
26
|
+
if (!isPinLocked && !isTransportBusy)
|
|
27
|
+
throw error;
|
|
28
|
+
thpState.resetState();
|
|
29
|
+
if (isPinLocked && !withInteraction)
|
|
30
|
+
return 'pin-locked';
|
|
31
|
+
if (isPinLocked) {
|
|
32
|
+
device.emit(device_1.DEVICE.BUTTON, {
|
|
33
|
+
device,
|
|
34
|
+
payload: { code: 'ButtonRequest_PinEntry' },
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
await (0, handshake_1.createThpChannel)(device);
|
|
38
|
+
await (0, handshake_1.thpHandshake)(device, isPinLocked);
|
|
39
|
+
}
|
|
18
40
|
}
|
|
19
|
-
if (thpState
|
|
41
|
+
if (thpState.phase === 'pairing' && withInteraction) {
|
|
20
42
|
await (0, pairing_1.thpPairing)(device);
|
|
21
43
|
}
|
|
44
|
+
if (thpState.phase !== 'paired') {
|
|
45
|
+
return 'thp-locked';
|
|
46
|
+
}
|
|
22
47
|
}
|
|
23
48
|
catch (error) {
|
|
24
|
-
thpState
|
|
49
|
+
thpState.resetState();
|
|
25
50
|
throw error;
|
|
26
51
|
}
|
|
27
52
|
};
|
|
@@ -83,9 +83,7 @@ const processThpPairingResponse = (device, payload) => {
|
|
|
83
83
|
const waitForPairingCancel = (device) => {
|
|
84
84
|
const readAbort = new AbortController();
|
|
85
85
|
device.getThpState()?.setExpectedResponses([0x04]);
|
|
86
|
-
const readCancel = device.getCurrentSession().receive({
|
|
87
|
-
signal: readAbort.signal,
|
|
88
|
-
});
|
|
86
|
+
const readCancel = device.getCurrentSession().receive({ signal: readAbort.signal });
|
|
89
87
|
return {
|
|
90
88
|
readAbort,
|
|
91
89
|
readCancel,
|
|
@@ -4,7 +4,7 @@ exports.createThpSession = void 0;
|
|
|
4
4
|
const thpCall_1 = require("./thpCall");
|
|
5
5
|
const createThpSession = async (device, deriveCardano) => {
|
|
6
6
|
let passphrase;
|
|
7
|
-
if (
|
|
7
|
+
if (device.features.passphrase_protection === false) {
|
|
8
8
|
passphrase = { passphrase: '' };
|
|
9
9
|
}
|
|
10
10
|
else {
|
|
@@ -51,7 +51,12 @@ const checkFirmwareHash = async ({ device, logger, }) => {
|
|
|
51
51
|
return createFailResult('check-unsupported');
|
|
52
52
|
}
|
|
53
53
|
const strippedBinary = (0, firmware_1.stripFwHeaders)(firmwareBinary.binary);
|
|
54
|
-
const { hash: expectedHash, challenge } = (0, firmware_1.calculateFirmwareHash)(
|
|
54
|
+
const { hash: expectedHash, challenge } = (0, firmware_1.calculateFirmwareHash)({
|
|
55
|
+
internal_model: device.features.internal_model,
|
|
56
|
+
firmwareVersion,
|
|
57
|
+
fw: strippedBinary,
|
|
58
|
+
key: (0, crypto_1.randomBytes)(32),
|
|
59
|
+
});
|
|
55
60
|
try {
|
|
56
61
|
const ts = performance.now();
|
|
57
62
|
const deviceResponse = await device
|
|
@@ -13,10 +13,9 @@ const handshakeCancel = async ({ device, logger, signal }) => {
|
|
|
13
13
|
if (device.features || device.getThpState()?.properties) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
+
const timeout = device.possibleT1 ? CANCEL_TIMEOUT : undefined;
|
|
16
17
|
logger?.debug('handshake Cancel start');
|
|
17
|
-
const send = await device
|
|
18
|
-
.getCurrentSession()
|
|
19
|
-
.send('Cancel', {}, { signal, timeout: CANCEL_TIMEOUT });
|
|
18
|
+
const send = await device.getCurrentSession().send('Cancel', {}, { signal, timeout });
|
|
20
19
|
if (!send.success) {
|
|
21
20
|
logger?.debug(`handshake Cancel send error ${send.error}`);
|
|
22
21
|
return;
|
|
@@ -24,10 +23,7 @@ const handshakeCancel = async ({ device, logger, signal }) => {
|
|
|
24
23
|
logger?.debug('handshake Cancel sent');
|
|
25
24
|
for (let attempt = 0; attempt < ATTEMPTS_LIMIT; ++attempt) {
|
|
26
25
|
logger?.debug(`handshake Cancel read attempt ${attempt}`);
|
|
27
|
-
const result = await device.getCurrentSession().receive({
|
|
28
|
-
signal,
|
|
29
|
-
timeout: CANCEL_TIMEOUT,
|
|
30
|
-
});
|
|
26
|
+
const result = await device.getCurrentSession().receive({ signal, timeout });
|
|
31
27
|
if (!result.success && result.error.message === transport_1.TRANSPORT_ERROR.ABORTED_BY_TIMEOUT) {
|
|
32
28
|
if (isLegacyBridge(device.transport)) {
|
|
33
29
|
await (0, utils_1.resolveAfter)(501);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.trezorPushNotificationHandler = void 0;
|
|
4
|
+
const protocol_1 = require("@trezor/protocol");
|
|
5
|
+
const utils_1 = require("@trezor/utils");
|
|
6
|
+
const device_1 = require("../../events/device");
|
|
7
|
+
const thp_1 = require("../thp");
|
|
8
|
+
const setupDeviceMode = async (device, mode) => {
|
|
9
|
+
if (mode === protocol_1.TrezorPushNotificationMode.BootloaderMode && !device.features) {
|
|
10
|
+
device.setBusy('rebooting');
|
|
11
|
+
await device.acquire();
|
|
12
|
+
await device.getFeatures();
|
|
13
|
+
await device.release();
|
|
14
|
+
}
|
|
15
|
+
if (mode === protocol_1.TrezorPushNotificationMode.NormalMode &&
|
|
16
|
+
(!device.features || !device.getThpState())) {
|
|
17
|
+
device.setBusy('rebooting');
|
|
18
|
+
await device.setupThp();
|
|
19
|
+
await device.acquire();
|
|
20
|
+
await (0, utils_1.resolveAfter)(1000);
|
|
21
|
+
await (0, thp_1.getThpChannel)(device, false);
|
|
22
|
+
if (device.getThpState()?.phase === 'paired') {
|
|
23
|
+
await device.getFeatures();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
device.setBusy('thp-locked');
|
|
27
|
+
device.lifecycle.emit(device_1.DEVICE.CHANGED);
|
|
28
|
+
}
|
|
29
|
+
await device.release();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const trezorPushNotificationHandler = async ({ device, message }) => {
|
|
33
|
+
const decoded = protocol_1.tpn.decode(message);
|
|
34
|
+
device.lifecycle.emit(device_1.DEVICE.TREZOR_PUSH_NOTIFICATION, decoded);
|
|
35
|
+
const { type, mode } = decoded;
|
|
36
|
+
const modeChanged = (mode === protocol_1.TrezorPushNotificationMode.BootloaderMode &&
|
|
37
|
+
(device.getThpState()?.properties ||
|
|
38
|
+
(device.features && !device.features.bootloader_mode))) ||
|
|
39
|
+
(mode === protocol_1.TrezorPushNotificationMode.NormalMode && device.features?.bootloader_mode);
|
|
40
|
+
if (modeChanged) {
|
|
41
|
+
device.reset();
|
|
42
|
+
device.setBusy(mode === protocol_1.TrezorPushNotificationMode.BootloaderMode ? 'bootloader-locked' : 'rebooting');
|
|
43
|
+
device.lifecycle.emit(device_1.DEVICE.CHANGED);
|
|
44
|
+
}
|
|
45
|
+
switch (type) {
|
|
46
|
+
case protocol_1.TrezorPushNotificationType.SETTING_CHANGE:
|
|
47
|
+
case protocol_1.TrezorPushNotificationType.PIN_CHANGE:
|
|
48
|
+
if (!device.isUsed()) {
|
|
49
|
+
await device.acquire();
|
|
50
|
+
await device.getFeatures();
|
|
51
|
+
await device.release();
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case protocol_1.TrezorPushNotificationType.LOCK:
|
|
55
|
+
device.setBusy(mode === protocol_1.TrezorPushNotificationMode.BootloaderMode
|
|
56
|
+
? 'bootloader-locked'
|
|
57
|
+
: 'hard-locked');
|
|
58
|
+
device.lifecycle.emit(device_1.DEVICE.CHANGED);
|
|
59
|
+
break;
|
|
60
|
+
case protocol_1.TrezorPushNotificationType.UNLOCK:
|
|
61
|
+
await setupDeviceMode(device, decoded.mode);
|
|
62
|
+
break;
|
|
63
|
+
case protocol_1.TrezorPushNotificationType.SOFTLOCK:
|
|
64
|
+
device.setBusy('pin-locked');
|
|
65
|
+
device.lifecycle.emit(device_1.DEVICE.CHANGED);
|
|
66
|
+
break;
|
|
67
|
+
case protocol_1.TrezorPushNotificationType.SOFTUNLOCK:
|
|
68
|
+
device.setBusy(device.features ? undefined : 'thp-locked');
|
|
69
|
+
device.lifecycle.emit(device_1.DEVICE.CHANGED);
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.trezorPushNotificationHandler = trezorPushNotificationHandler;
|
|
76
|
+
//# sourceMappingURL=trezorPushNotification.js.map
|
|
@@ -78,6 +78,9 @@ const getInvalidThpDeviceState = async (context) => {
|
|
|
78
78
|
thpState?.setSessionId(Buffer.alloc(1));
|
|
79
79
|
return undefined;
|
|
80
80
|
}
|
|
81
|
+
if (e.code === 'Failure_PinCancelled') {
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
if (!uniqueState || (!currentState?.deriveCardano && method.useCardanoDerivation)) {
|
package/lib/events/call.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IFRAME } from './iframe';
|
|
2
|
-
import { Device } from '../device/Device';
|
|
2
|
+
import type { Device } from '../device/Device';
|
|
3
3
|
import type { TrezorConnect } from '../types/api';
|
|
4
4
|
import type { CommonParams, DeviceIdentity } from '../types/params';
|
|
5
5
|
type UnwrappedResponse<Response> = Response extends Promise<infer R> ? R extends {
|
package/lib/events/device.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { VersionArray } from '@trezor/device-utils';
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
2
|
+
import { MessagesSchema as PROTO } from '@trezor/protobuf';
|
|
3
|
+
import type { DecodedTrezorPushNotification, ThpCredentials, ThpPairingMethod } from '@trezor/protocol';
|
|
4
4
|
import type { Device } from '../types/device';
|
|
5
5
|
import type { MessageFactoryFn } from '../types/utils';
|
|
6
|
+
export { type DecodedTrezorPushNotification, TrezorPushNotificationMode, TrezorPushNotificationType, } from '@trezor/protocol/lib/protocol-tpn';
|
|
6
7
|
export declare const DEVICE_EVENT = "DEVICE_EVENT";
|
|
7
8
|
export declare const DEVICE: {
|
|
8
9
|
readonly CONNECT: "device-connect";
|
|
@@ -10,6 +11,7 @@ export declare const DEVICE: {
|
|
|
10
11
|
readonly DISCONNECT: "device-disconnect";
|
|
11
12
|
readonly CHANGED: "device-changed";
|
|
12
13
|
readonly FIRMWARE_VERSION_CHANGED: "device-firmware_version_changed";
|
|
14
|
+
readonly TREZOR_PUSH_NOTIFICATION: "device-trezor_push_notification";
|
|
13
15
|
readonly THP_CREDENTIALS_CHANGED: "device-thp_credentials_changed";
|
|
14
16
|
readonly BUTTON: "button";
|
|
15
17
|
readonly PIN: "pin";
|
|
@@ -50,10 +52,16 @@ export interface DeviceThpCredentialsChanged {
|
|
|
50
52
|
device: Device;
|
|
51
53
|
};
|
|
52
54
|
}
|
|
55
|
+
export interface DeviceTrezorPushNotification {
|
|
56
|
+
type: typeof DEVICE.TREZOR_PUSH_NOTIFICATION;
|
|
57
|
+
payload: DecodedTrezorPushNotification & {
|
|
58
|
+
device: Device;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
53
61
|
export type DeviceEvent = {
|
|
54
62
|
type: typeof DEVICE.CONNECT | typeof DEVICE.CONNECT_UNACQUIRED | typeof DEVICE.CHANGED | typeof DEVICE.DISCONNECT;
|
|
55
63
|
payload: Device;
|
|
56
|
-
} | DeviceButtonRequest | DeviceThpCredentialsChanged | DeviceVersionChanged;
|
|
64
|
+
} | DeviceButtonRequest | DeviceThpCredentialsChanged | DeviceVersionChanged | DeviceTrezorPushNotification;
|
|
57
65
|
export type DeviceEventMessage = DeviceEvent & {
|
|
58
66
|
event: typeof DEVICE_EVENT;
|
|
59
67
|
};
|
package/lib/events/device.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createDeviceMessage = exports.DEVICE = exports.DEVICE_EVENT = void 0;
|
|
3
|
+
exports.createDeviceMessage = exports.DEVICE = exports.DEVICE_EVENT = exports.TrezorPushNotificationType = exports.TrezorPushNotificationMode = void 0;
|
|
4
|
+
var protocol_tpn_1 = require("@trezor/protocol/lib/protocol-tpn");
|
|
5
|
+
Object.defineProperty(exports, "TrezorPushNotificationMode", { enumerable: true, get: function () { return protocol_tpn_1.TrezorPushNotificationMode; } });
|
|
6
|
+
Object.defineProperty(exports, "TrezorPushNotificationType", { enumerable: true, get: function () { return protocol_tpn_1.TrezorPushNotificationType; } });
|
|
4
7
|
exports.DEVICE_EVENT = 'DEVICE_EVENT';
|
|
5
8
|
exports.DEVICE = {
|
|
6
9
|
CONNECT: 'device-connect',
|
|
@@ -8,6 +11,7 @@ exports.DEVICE = {
|
|
|
8
11
|
DISCONNECT: 'device-disconnect',
|
|
9
12
|
CHANGED: 'device-changed',
|
|
10
13
|
FIRMWARE_VERSION_CHANGED: 'device-firmware_version_changed',
|
|
14
|
+
TREZOR_PUSH_NOTIFICATION: 'device-trezor_push_notification',
|
|
11
15
|
THP_CREDENTIALS_CHANGED: 'device-thp_credentials_changed',
|
|
12
16
|
BUTTON: 'button',
|
|
13
17
|
PIN: 'pin',
|
package/lib/events/popup.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TransportInfo } from './transport';
|
|
2
2
|
import { UI_EVENT } from './ui-request';
|
|
3
|
-
import type { ConnectSettings, SystemInfo } from '../types';
|
|
3
|
+
import type { ConnectSettings, SystemInfo } from '../types/settings';
|
|
4
4
|
import type { MessageFactoryFn } from '../types/utils';
|
|
5
5
|
export declare const POPUP: {
|
|
6
6
|
readonly BOOTSTRAP: "popup-bootstrap";
|
|
@@ -1,29 +1,11 @@
|
|
|
1
1
|
import type { Transport } from '@trezor/transport';
|
|
2
2
|
import { TRANSPORT } from '@trezor/transport/lib/constants';
|
|
3
|
-
import {
|
|
3
|
+
import { BridgeInfo } from '../data/transportInfo';
|
|
4
|
+
import { UdevInfo } from '../data/udevInfo';
|
|
5
|
+
import { ConnectSettings } from '../types/settings';
|
|
4
6
|
import type { MessageFactoryFn } from '../types/utils';
|
|
5
7
|
export { TRANSPORT } from '@trezor/transport/lib/constants';
|
|
6
8
|
export declare const TRANSPORT_EVENT = "TRANSPORT_EVENT";
|
|
7
|
-
export interface BridgeInfo {
|
|
8
|
-
version: number[];
|
|
9
|
-
packages: {
|
|
10
|
-
name: string;
|
|
11
|
-
platform: string[];
|
|
12
|
-
url: string;
|
|
13
|
-
signature?: string;
|
|
14
|
-
preferred?: boolean;
|
|
15
|
-
}[];
|
|
16
|
-
changelog: string;
|
|
17
|
-
}
|
|
18
|
-
export interface UdevInfo {
|
|
19
|
-
packages: {
|
|
20
|
-
name: string;
|
|
21
|
-
platform: string[];
|
|
22
|
-
url: string;
|
|
23
|
-
signature?: string;
|
|
24
|
-
preferred?: boolean;
|
|
25
|
-
}[];
|
|
26
|
-
}
|
|
27
9
|
export interface TransportInfo {
|
|
28
10
|
apiType: Transport['apiType'];
|
|
29
11
|
type: Transport['name'];
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { EventTypeDeviceSelected } from '@trezor/connect-analytics';
|
|
2
|
-
import { DeviceModelInternal } from '@trezor/device-utils';
|
|
3
|
-
import
|
|
4
|
-
import type { BinaryInfo, BitcoinNetworkInfo, CoinInfo, Device, FirmwareType, SelectFeeLevel } from '../types';
|
|
2
|
+
import { DeviceModelInternal, FirmwareRelease, FirmwareType, VersionArray } from '@trezor/device-utils';
|
|
3
|
+
import { MessagesSchema as PROTO } from '@trezor/protobuf';
|
|
5
4
|
import type { DeviceButtonRequest, DeviceThpPairingPayload } from './device';
|
|
6
|
-
import { MethodPermission } from '../core/AbstractMethod';
|
|
5
|
+
import type { MethodPermission } from '../core/AbstractMethod';
|
|
7
6
|
import type { DiscoveryAccount, DiscoveryAccountType } from '../types/account';
|
|
7
|
+
import type { BitcoinNetworkInfo, CoinInfo } from '../types/coinInfo';
|
|
8
|
+
import type { Device } from '../types/device';
|
|
9
|
+
import type { SelectFeeLevel } from '../types/fees';
|
|
8
10
|
import type { MessageFactoryFn } from '../types/utils';
|
|
9
11
|
export declare const UI_EVENT = "UI_EVENT";
|
|
10
12
|
export declare const UI_REQUEST: {
|
|
@@ -176,12 +178,17 @@ export interface UiRequestSelectDevice {
|
|
|
176
178
|
webusb: boolean;
|
|
177
179
|
};
|
|
178
180
|
}
|
|
181
|
+
export type FirmwareStoreEvent = {
|
|
182
|
+
binary: ArrayBuffer;
|
|
183
|
+
binaryVersion: VersionArray;
|
|
184
|
+
internalModel: DeviceModelInternal;
|
|
185
|
+
release: FirmwareRelease | undefined;
|
|
186
|
+
firmwareType?: FirmwareType;
|
|
187
|
+
releaseVersion?: number[];
|
|
188
|
+
};
|
|
179
189
|
export interface UiRequestFirmwareDownloaded {
|
|
180
190
|
type: typeof UI_REQUEST.FIRMWARE_DOWNLOADED;
|
|
181
|
-
payload:
|
|
182
|
-
internalModel?: DeviceModelInternal;
|
|
183
|
-
firmwareType?: FirmwareType;
|
|
184
|
-
};
|
|
191
|
+
payload: FirmwareStoreEvent;
|
|
185
192
|
}
|
|
186
193
|
export interface UiRequestUnexpectedDeviceMode {
|
|
187
194
|
type: typeof UI_REQUEST.BOOTLOADER | typeof UI_REQUEST.NOT_IN_BOOTLOADER | typeof UI_REQUEST.INITIALIZE | typeof UI_REQUEST.SEEDLESS | typeof UI_REQUEST.DEVICE_NEEDS_BACKUP;
|