@trezor/connect 9.6.0 → 9.6.1-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 +37 -8
- package/README.md +1 -1
- package/lib/api/blockchainEstimateFee.js +1 -0
- package/lib/api/discoverAccounts.js +10 -2
- package/lib/api/eos/eosSignTx.d.ts +3 -3
- package/lib/api/ethereum/api/ethereumSignMessage.js +1 -1
- package/lib/api/ethereum/api/ethereumSignTypedData.d.ts +1 -1
- package/lib/api/firmware/getBinary.js +2 -2
- package/lib/api/getAddress.d.ts +1 -0
- package/lib/api/getAddress.js +1 -0
- package/lib/api/getCoinInfo.d.ts +3 -3
- package/lib/api/getNonce.d.ts +9 -0
- package/lib/api/getNonce.js +15 -0
- package/lib/api/index.d.ts +1 -0
- package/lib/api/index.js +4 -2
- package/lib/api/nem/nemSignTx.d.ts +1 -1
- package/lib/api/resetDevice.d.ts +2 -3
- package/lib/api/resetDevice.js +47 -49
- package/lib/api/signMessage.js +1 -1
- package/lib/api/signTransaction.js +6 -1
- package/lib/backend/Blockchain.d.ts +1 -0
- package/lib/backend/fees/BitcoinFeeLevels.d.ts +2 -4
- package/lib/backend/fees/BitcoinFeeLevels.js +11 -73
- package/lib/backend/fees/EthereumFeeLevels.d.ts +1 -3
- package/lib/backend/fees/EthereumFeeLevels.js +8 -5
- package/lib/backend/fees/MiscFeeLevels.d.ts +0 -3
- package/lib/backend/fees/MiscFeeLevels.js +2 -2
- package/lib/constants/errors.d.ts +1 -0
- package/lib/constants/errors.js +1 -0
- package/lib/core/AbstractMethod.d.ts +1 -1
- package/lib/core/index.js +43 -53
- package/lib/core/onCallFirmwareUpdate.js +2 -2
- package/lib/data/coinInfo.d.ts +11 -11
- package/lib/data/coinInfo.js +1 -1
- package/lib/data/connectSettings.js +0 -3
- package/lib/data/defaultFeeLevels.d.ts +3 -1
- package/lib/data/defaultFeeLevels.js +22 -12
- package/lib/data/deviceAuthenticityConfig.js +4 -1
- package/lib/data/firmwareInfo.d.ts +1 -0
- package/lib/data/firmwareInfo.js +14 -1
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +20 -21
- package/lib/device/Device.js +78 -123
- package/lib/device/DeviceCurrentSession.d.ts +441 -4027
- package/lib/device/DeviceCurrentSession.js +75 -44
- package/lib/device/DeviceList.d.ts +3 -8
- package/lib/device/DeviceList.js +21 -77
- package/lib/device/TransportManager.d.ts +2 -6
- package/lib/device/TransportManager.js +11 -7
- package/lib/device/checkFirmwareRevision.js +2 -2
- package/lib/device/workflow/index.d.ts +2 -0
- package/lib/device/workflow/index.js +6 -0
- package/lib/device/workflow/validateState.d.ts +3 -0
- package/lib/device/workflow/validateState.js +97 -0
- package/lib/events/device.d.ts +19 -1
- package/lib/events/device.js +2 -0
- package/lib/events/index.d.ts +4 -0
- package/lib/events/ui-request.d.ts +24 -3
- package/lib/events/ui-request.js +3 -0
- package/lib/events/ui-response.d.ts +11 -1
- package/lib/events/ui-response.js +1 -0
- package/lib/factory.js +1 -0
- package/lib/tsconfig.lib.tsbuildinfo +1 -1
- package/lib/types/api/applySettings.d.ts +1 -0
- package/lib/types/api/discoverAccounts.d.ts +17 -4
- package/lib/types/api/discoverAccounts.js +2 -0
- package/lib/types/api/getNonce.d.ts +4 -0
- package/lib/types/api/getNonce.js +3 -0
- package/lib/types/api/index.d.ts +2 -0
- package/lib/types/coinInfo.d.ts +6 -6
- package/lib/types/coinInfo.js +2 -0
- package/lib/types/device.d.ts +3 -4
- package/lib/types/fees.d.ts +1 -1
- package/lib/types/fees.js +1 -1
- package/lib/types/params.d.ts +1 -0
- package/lib/types/settings.d.ts +0 -1
- package/lib/types/workflow.d.ts +8 -0
- package/lib/types/workflow.js +3 -0
- package/lib/utils/formatUtils.d.ts +1 -0
- package/lib/utils/formatUtils.js +9 -1
- package/lib/utils/uiPromiseManager.d.ts +2 -0
- package/package.json +17 -17
- package/lib/data/downloadReleasesMetadata.d.ts +0 -7
- package/lib/data/downloadReleasesMetadata.js +0 -18
- package/lib/data/models.d.ts +0 -8
- package/lib/data/models.js +0 -49
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { EthereumNetworkInfo } from '../../types';
|
|
2
2
|
import { Blockchain } from '../Blockchain';
|
|
3
|
-
import {
|
|
3
|
+
import { MiscFeeLevels } from './MiscFeeLevels';
|
|
4
4
|
export declare class EthereumFeeLevels extends MiscFeeLevels {
|
|
5
5
|
coinInfo: EthereumNetworkInfo;
|
|
6
|
-
blocks: Blocks;
|
|
7
6
|
constructor(coinInfo: EthereumNetworkInfo);
|
|
8
7
|
load(blockchain: Blockchain, request: Parameters<typeof blockchain.estimateFee>[0]): Promise<{
|
|
9
8
|
feePerTx?: string | undefined;
|
|
@@ -11,7 +10,6 @@ export declare class EthereumFeeLevels extends MiscFeeLevels {
|
|
|
11
10
|
baseFeePerGas?: string | undefined;
|
|
12
11
|
maxFeePerGas?: string | undefined;
|
|
13
12
|
maxPriorityFeePerGas?: string | undefined;
|
|
14
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
15
13
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
16
14
|
blocks: number;
|
|
17
15
|
feePerUnit: string;
|
|
@@ -5,7 +5,6 @@ const bigNumber_1 = require("@trezor/utils/lib/bigNumber");
|
|
|
5
5
|
const MiscFeeLevels_1 = require("./MiscFeeLevels");
|
|
6
6
|
class EthereumFeeLevels extends MiscFeeLevels_1.MiscFeeLevels {
|
|
7
7
|
coinInfo;
|
|
8
|
-
blocks = [];
|
|
9
8
|
constructor(coinInfo) {
|
|
10
9
|
super(coinInfo);
|
|
11
10
|
this.coinInfo = coinInfo;
|
|
@@ -19,21 +18,25 @@ class EthereumFeeLevels extends MiscFeeLevels_1.MiscFeeLevels {
|
|
|
19
18
|
const feeInWei = new bigNumber_1.BigNumber(response.feePerUnit).toNumber();
|
|
20
19
|
const feePerUnit = Math.min(maxFeeInWei, Math.max(minFeeInWei, feeInWei)).toString();
|
|
21
20
|
if (eip1559?.baseFeePerGas) {
|
|
21
|
+
const minMaxPriorityFeePerGas = new bigNumber_1.BigNumber(this.coinInfo.minPriorityFee)
|
|
22
|
+
.multipliedBy('1e+9')
|
|
23
|
+
.toNumber();
|
|
22
24
|
const levels = ['low', 'medium', 'high'].map(levelKey => {
|
|
23
25
|
const level = eip1559[levelKey];
|
|
24
26
|
const label = levelKey === 'medium' ? 'normal' : levelKey;
|
|
25
27
|
if (!level?.maxFeePerGas || !level?.maxPriorityFeePerGas) {
|
|
26
28
|
return null;
|
|
27
29
|
}
|
|
30
|
+
const maxFeePerGas = bigNumber_1.BigNumber.max(this.coinInfo.minFee, level.maxFeePerGas, minMaxPriorityFeePerGas).toString();
|
|
31
|
+
const maxPriorityFeePerGas = bigNumber_1.BigNumber.max(minMaxPriorityFeePerGas, bigNumber_1.BigNumber.min(maxFeePerGas, level.maxPriorityFeePerGas)).toString();
|
|
28
32
|
return {
|
|
29
33
|
label,
|
|
30
34
|
feePerUnit,
|
|
31
35
|
feeLimit: response.feeLimit,
|
|
32
|
-
blocks:
|
|
36
|
+
blocks: Math.ceil(Math.max(1, (level?.maxWaitTimeEstimate || 0) / 1000 / this.coinInfo.blockTime)),
|
|
33
37
|
baseFeePerGas: eip1559.baseFeePerGas,
|
|
34
|
-
maxFeePerGas
|
|
35
|
-
maxPriorityFeePerGas
|
|
36
|
-
maxWaitTimeEstimate: level?.maxWaitTimeEstimate,
|
|
38
|
+
maxFeePerGas,
|
|
39
|
+
maxPriorityFeePerGas,
|
|
37
40
|
};
|
|
38
41
|
});
|
|
39
42
|
this.levels = levels.filter(level => level);
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { CoinInfo, FeeLevel } from '../../types';
|
|
2
2
|
import { Blockchain } from '../Blockchain';
|
|
3
|
-
export type Blocks = Array<string | undefined>;
|
|
4
3
|
export declare class MiscFeeLevels {
|
|
5
4
|
coinInfo: CoinInfo;
|
|
6
5
|
levels: FeeLevel[];
|
|
7
|
-
blocks: Blocks;
|
|
8
6
|
wasFetchedSuccessfully: boolean;
|
|
9
7
|
constructor(coinInfo: CoinInfo);
|
|
10
8
|
load(blockchain: Blockchain, request: Parameters<typeof blockchain.estimateFee>[0]): Promise<{
|
|
@@ -13,7 +11,6 @@ export declare class MiscFeeLevels {
|
|
|
13
11
|
baseFeePerGas?: string | undefined;
|
|
14
12
|
maxFeePerGas?: string | undefined;
|
|
15
13
|
maxPriorityFeePerGas?: string | undefined;
|
|
16
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
17
14
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
18
15
|
blocks: number;
|
|
19
16
|
feePerUnit: string;
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MiscFeeLevels = void 0;
|
|
4
4
|
const bigNumber_1 = require("@trezor/utils/lib/bigNumber");
|
|
5
|
+
const cloneObject_1 = require("@trezor/utils/lib/cloneObject");
|
|
5
6
|
class MiscFeeLevels {
|
|
6
7
|
coinInfo;
|
|
7
8
|
levels;
|
|
8
|
-
blocks = [];
|
|
9
9
|
wasFetchedSuccessfully = false;
|
|
10
10
|
constructor(coinInfo) {
|
|
11
11
|
this.coinInfo = coinInfo;
|
|
12
|
-
this.levels = coinInfo.defaultFees;
|
|
12
|
+
this.levels = (0, cloneObject_1.cloneObject)(coinInfo.defaultFees);
|
|
13
13
|
}
|
|
14
14
|
async load(blockchain, request) {
|
|
15
15
|
try {
|
|
@@ -35,6 +35,7 @@ export declare const ERROR_CODES: {
|
|
|
35
35
|
readonly Device_MultipleNotSupported: "Multiple devices are not supported";
|
|
36
36
|
readonly Device_MissingCapability: "Device is missing capability";
|
|
37
37
|
readonly Device_MissingCapabilityBtcOnly: "Device is missing capability (BTC only)";
|
|
38
|
+
readonly Device_ThpPairingTagInvalid: "Pairing tag mismatch";
|
|
38
39
|
readonly Failure_ActionCancelled: "Action cancelled by user";
|
|
39
40
|
readonly Failure_FirmwareError: "Firmware installation failed";
|
|
40
41
|
readonly Failure_UnknownCode: "Unknown error";
|
package/lib/constants/errors.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.ERROR_CODES = {
|
|
|
38
38
|
Device_MultipleNotSupported: 'Multiple devices are not supported',
|
|
39
39
|
Device_MissingCapability: 'Device is missing capability',
|
|
40
40
|
Device_MissingCapabilityBtcOnly: 'Device is missing capability (BTC only)',
|
|
41
|
+
Device_ThpPairingTagInvalid: 'Pairing tag mismatch',
|
|
41
42
|
Failure_ActionCancelled: 'Action cancelled by user',
|
|
42
43
|
Failure_FirmwareError: 'Firmware installation failed',
|
|
43
44
|
Failure_UnknownCode: 'Unknown error',
|
|
@@ -72,7 +72,7 @@ export declare abstract class AbstractMethod<Name extends CallMethodPayload['met
|
|
|
72
72
|
requiredPermissions: MethodPermission[];
|
|
73
73
|
info: string;
|
|
74
74
|
confirmation: {
|
|
75
|
-
view: "no-backup" | "export-xpub" | "export-address" | "export-account-info" | "device-management";
|
|
75
|
+
view: "thp-pairing-start" | "thp-pairing-failed" | "no-backup" | "export-xpub" | "export-address" | "export-account-info" | "device-management";
|
|
76
76
|
label?: string;
|
|
77
77
|
customConfirmButton?: {
|
|
78
78
|
className: string;
|
package/lib/core/index.js
CHANGED
|
@@ -15,6 +15,7 @@ const analyticsInfo_1 = require("../data/analyticsInfo");
|
|
|
15
15
|
const connectSettings_1 = require("../data/connectSettings");
|
|
16
16
|
const DeviceList_1 = require("../device/DeviceList");
|
|
17
17
|
const StateStorage_1 = require("../device/StateStorage");
|
|
18
|
+
const workflows = tslib_1.__importStar(require("../device/workflow"));
|
|
18
19
|
const events_2 = require("../events");
|
|
19
20
|
const debug_1 = require("../utils/debug");
|
|
20
21
|
const interactionTimeout_1 = require("../utils/interactionTimeout");
|
|
@@ -111,23 +112,6 @@ const initDevice = async (context, methodCallDevice) => {
|
|
|
111
112
|
}
|
|
112
113
|
return device;
|
|
113
114
|
};
|
|
114
|
-
const MAX_PIN_TRIES = 3;
|
|
115
|
-
const getInvalidDeviceState = async ({ sendCoreMessage }, device, preauthorized) => {
|
|
116
|
-
for (let i = 0; i < MAX_PIN_TRIES - 1; ++i) {
|
|
117
|
-
try {
|
|
118
|
-
return await device.validateState(preauthorized);
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
if (error.message.includes('PIN invalid')) {
|
|
122
|
-
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PIN, { device: device.toMessageObject() }));
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
throw error;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return device.validateState(preauthorized);
|
|
130
|
-
};
|
|
131
115
|
const inner = async (context, method, device) => {
|
|
132
116
|
const { uiPromises, sendCoreMessage } = context;
|
|
133
117
|
const trustedHost = DataManager_1.DataManager.getSettings('trustedHost');
|
|
@@ -215,40 +199,12 @@ const inner = async (context, method, device) => {
|
|
|
215
199
|
}
|
|
216
200
|
}
|
|
217
201
|
}
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const uiPromise = uiPromises.create(events_2.UI.INVALID_PASSPHRASE_ACTION, device);
|
|
225
|
-
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PASSPHRASE, {
|
|
226
|
-
device: device.toMessageObject(),
|
|
227
|
-
}));
|
|
228
|
-
const uiResp = await uiPromise.promise;
|
|
229
|
-
if (uiResp.payload) {
|
|
230
|
-
device.setState({ sessionId: undefined });
|
|
231
|
-
await device.initialize(method.useCardanoDerivation);
|
|
232
|
-
invalidDeviceState = await getInvalidDeviceState(context, device, method.preauthorized);
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
device.setState({ staticSessionId: invalidDeviceState });
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
else if (invalidDeviceState) {
|
|
241
|
-
throw constants_1.ERRORS.TypedError('Device_InvalidState');
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
catch (error) {
|
|
245
|
-
device.setState({ sessionId: undefined });
|
|
246
|
-
return Promise.reject(error);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (!isDeviceUnlocked && device.features.unlocked) {
|
|
250
|
-
sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.CHANGED, device.toMessageObject()));
|
|
251
|
-
}
|
|
202
|
+
const workflowCtx = {
|
|
203
|
+
device,
|
|
204
|
+
method,
|
|
205
|
+
signal: context.signal,
|
|
206
|
+
};
|
|
207
|
+
await workflows.validateState(workflowCtx);
|
|
252
208
|
if (method.useUi) {
|
|
253
209
|
await waitForPopup(context);
|
|
254
210
|
}
|
|
@@ -533,6 +489,37 @@ const onDevicePassphraseHandler = (device, context) => async ({ callback }) => {
|
|
|
533
489
|
const onEmptyPassphraseHandler = () => ({ callback }) => {
|
|
534
490
|
callback({ success: true, payload: { value: '' } });
|
|
535
491
|
};
|
|
492
|
+
const onThpPairingHandler = (device, context) => async ({ callback, payload }) => {
|
|
493
|
+
const { uiPromises, sendCoreMessage } = context;
|
|
494
|
+
await waitForPopup(context);
|
|
495
|
+
const uiPromise = uiPromises.create(events_2.UI.RECEIVE_THP_PAIRING_TAG, device);
|
|
496
|
+
sendCoreMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_THP_PAIRING, {
|
|
497
|
+
device: device.toMessageObject(),
|
|
498
|
+
...payload,
|
|
499
|
+
}));
|
|
500
|
+
try {
|
|
501
|
+
const uiResp = await uiPromise.promise;
|
|
502
|
+
if (uiResp.payload == null) {
|
|
503
|
+
callback({
|
|
504
|
+
success: false,
|
|
505
|
+
error: new Error(`${events_2.UI.RECEIVE_THP_PAIRING_TAG} missing payload`),
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
callback({ success: true, payload: uiResp.payload });
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
callback({ success: false, error });
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
const onThpCredentialsChangedHandler = (device, context) => (payload) => {
|
|
517
|
+
const { sendCoreMessage } = context;
|
|
518
|
+
sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.THP_CREDENTIALS_CHANGED, {
|
|
519
|
+
device: device.toMessageObject(),
|
|
520
|
+
...payload,
|
|
521
|
+
}));
|
|
522
|
+
};
|
|
536
523
|
const registerDeviceEvents = (context, method) => (device) => {
|
|
537
524
|
device.removeAllListeners();
|
|
538
525
|
device.on(events_2.DEVICE.BUTTON, onDeviceButtonHandler(device, context, method));
|
|
@@ -547,6 +534,8 @@ const registerDeviceEvents = (context, method) => (device) => {
|
|
|
547
534
|
device.on(events_2.DEVICE.FIRMWARE_VERSION_CHANGED, payload => {
|
|
548
535
|
context.sendCoreMessage((0, events_2.createDeviceMessage)(events_2.DEVICE.FIRMWARE_VERSION_CHANGED, payload));
|
|
549
536
|
});
|
|
537
|
+
device.on(events_2.DEVICE.THP_PAIRING, onThpPairingHandler(device, context));
|
|
538
|
+
device.on(events_2.DEVICE.THP_CREDENTIALS_CHANGED, onThpCredentialsChangedHandler(device, context));
|
|
550
539
|
};
|
|
551
540
|
const onPopupClosed = (context, customErrorMessage) => {
|
|
552
541
|
const { uiPromises, popupPromise, deviceList, callMethods, resetWaitForFirstMethod, sendCoreMessage, } = context;
|
|
@@ -656,6 +645,7 @@ class Core extends events_1.default {
|
|
|
656
645
|
}
|
|
657
646
|
getCoreContext() {
|
|
658
647
|
return {
|
|
648
|
+
signal: this.abortController.signal,
|
|
659
649
|
uiPromises: this.uiPromises,
|
|
660
650
|
popupPromise: this.popupPromise,
|
|
661
651
|
interactionTimeout: this.interactionTimeout,
|
|
@@ -709,6 +699,7 @@ class Core extends events_1.default {
|
|
|
709
699
|
case events_2.UI.RECEIVE_PIN:
|
|
710
700
|
case events_2.UI.RECEIVE_PASSPHRASE:
|
|
711
701
|
case events_2.UI.INVALID_PASSPHRASE_ACTION:
|
|
702
|
+
case events_2.UI.RECEIVE_THP_PAIRING_TAG:
|
|
712
703
|
case events_2.UI.RECEIVE_ACCOUNT:
|
|
713
704
|
case events_2.UI.RECEIVE_FEE:
|
|
714
705
|
case events_2.UI.RECEIVE_WORD:
|
|
@@ -785,7 +776,7 @@ class Core extends events_1.default {
|
|
|
785
776
|
if (localFirmwares) {
|
|
786
777
|
DataManager_1.DataManager.setLocalFirmwares(localFirmwares);
|
|
787
778
|
}
|
|
788
|
-
const { debug, priority,
|
|
779
|
+
const { debug, priority, manifest } = DataManager_1.DataManager.getSettings();
|
|
789
780
|
const messages = DataManager_1.DataManager.getProtobufMessages();
|
|
790
781
|
(0, debug_1.enableLog)(debug);
|
|
791
782
|
this._interactionTimeout = new interactionTimeout_1.InteractionTimeout(settings.popup ? settings.interactionTimeout : 0);
|
|
@@ -793,7 +784,6 @@ class Core extends events_1.default {
|
|
|
793
784
|
debug,
|
|
794
785
|
messages,
|
|
795
786
|
priority,
|
|
796
|
-
_sessionsBackgroundUrl,
|
|
797
787
|
manifest,
|
|
798
788
|
});
|
|
799
789
|
initDeviceList(this.getCoreContext());
|
|
@@ -211,13 +211,13 @@ const onCallFirmwareUpdate = async ({ params, context, }) => {
|
|
|
211
211
|
await device.getCommands().typedCall('RebootToBootloader', 'Success', rebootParams);
|
|
212
212
|
}
|
|
213
213
|
else {
|
|
214
|
-
let rebootResponse = await device.getCommands().typedCall('RebootToBootloader', ['
|
|
214
|
+
let rebootResponse = await device.getCommands().typedCall('RebootToBootloader', ['DataChunkRequest', 'Success'], { ...rebootParams, language_data_length: languageBlob?.byteLength });
|
|
215
215
|
log.debug('onCallFirmwareUpdate', 'RebootToBootloader response', rebootResponse.message);
|
|
216
216
|
while (languageBlob && rebootResponse.type !== 'Success') {
|
|
217
217
|
const start = rebootResponse.message.data_offset;
|
|
218
218
|
const end = rebootResponse.message.data_offset + rebootResponse.message.data_length;
|
|
219
219
|
const chunk = languageBlob.slice(start, end);
|
|
220
|
-
rebootResponse = await device.getCommands().typedCall('
|
|
220
|
+
rebootResponse = await device.getCommands().typedCall('DataChunkAck', ['DataChunkRequest', 'Success'], { data_chunk: Buffer.from(chunk).toString('hex') });
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
log.info('onCallFirmwareUpdate', 'waiting for disconnected event after rebootToBootloader...');
|
package/lib/data/coinInfo.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const getBitcoinNetwork: (pathOrName: DerivationPath) => ({
|
|
|
8
8
|
blockTime: number;
|
|
9
9
|
minFee: number;
|
|
10
10
|
maxFee: number;
|
|
11
|
+
minPriorityFee: number;
|
|
11
12
|
name: string;
|
|
12
13
|
shortcut: string;
|
|
13
14
|
slip44: number;
|
|
@@ -28,7 +29,6 @@ export declare const getBitcoinNetwork: (pathOrName: DerivationPath) => ({
|
|
|
28
29
|
baseFeePerGas?: string | undefined;
|
|
29
30
|
maxFeePerGas?: string | undefined;
|
|
30
31
|
maxPriorityFeePerGas?: string | undefined;
|
|
31
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
32
32
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
33
33
|
blocks: number;
|
|
34
34
|
feePerUnit: string;
|
|
@@ -72,6 +72,7 @@ export declare const getEthereumNetwork: (pathOrNetworkSymbol: DerivationPath) =
|
|
|
72
72
|
blockTime: number;
|
|
73
73
|
minFee: number;
|
|
74
74
|
maxFee: number;
|
|
75
|
+
minPriorityFee: number;
|
|
75
76
|
name: string;
|
|
76
77
|
shortcut: string;
|
|
77
78
|
slip44: number;
|
|
@@ -92,7 +93,6 @@ export declare const getEthereumNetwork: (pathOrNetworkSymbol: DerivationPath) =
|
|
|
92
93
|
baseFeePerGas?: string | undefined;
|
|
93
94
|
maxFeePerGas?: string | undefined;
|
|
94
95
|
maxPriorityFeePerGas?: string | undefined;
|
|
95
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
96
96
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
97
97
|
blocks: number;
|
|
98
98
|
feePerUnit: string;
|
|
@@ -111,6 +111,7 @@ export declare const getMiscNetwork: (pathOrName: DerivationPath) => ({
|
|
|
111
111
|
blockTime: number;
|
|
112
112
|
minFee: number;
|
|
113
113
|
maxFee: number;
|
|
114
|
+
minPriorityFee: number;
|
|
114
115
|
name: string;
|
|
115
116
|
shortcut: string;
|
|
116
117
|
slip44: number;
|
|
@@ -131,7 +132,6 @@ export declare const getMiscNetwork: (pathOrName: DerivationPath) => ({
|
|
|
131
132
|
baseFeePerGas?: string | undefined;
|
|
132
133
|
maxFeePerGas?: string | undefined;
|
|
133
134
|
maxPriorityFeePerGas?: string | undefined;
|
|
134
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
135
135
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
136
136
|
blocks: number;
|
|
137
137
|
feePerUnit: string;
|
|
@@ -174,6 +174,7 @@ export declare const fixCoinInfoNetwork: (ci: BitcoinNetworkInfo, path: number[]
|
|
|
174
174
|
blockTime: number;
|
|
175
175
|
minFee: number;
|
|
176
176
|
maxFee: number;
|
|
177
|
+
minPriorityFee: number;
|
|
177
178
|
name: string;
|
|
178
179
|
shortcut: string;
|
|
179
180
|
slip44: number;
|
|
@@ -194,7 +195,6 @@ export declare const fixCoinInfoNetwork: (ci: BitcoinNetworkInfo, path: number[]
|
|
|
194
195
|
baseFeePerGas?: string | undefined;
|
|
195
196
|
maxFeePerGas?: string | undefined;
|
|
196
197
|
maxPriorityFeePerGas?: string | undefined;
|
|
197
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
198
198
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
199
199
|
blocks: number;
|
|
200
200
|
feePerUnit: string;
|
|
@@ -238,6 +238,7 @@ export declare const getCoinInfoByHash: (hash: string, networkInfo: any) => {
|
|
|
238
238
|
blockTime: number;
|
|
239
239
|
minFee: number;
|
|
240
240
|
maxFee: number;
|
|
241
|
+
minPriorityFee: number;
|
|
241
242
|
name: string;
|
|
242
243
|
shortcut: string;
|
|
243
244
|
slip44: number;
|
|
@@ -258,7 +259,6 @@ export declare const getCoinInfoByHash: (hash: string, networkInfo: any) => {
|
|
|
258
259
|
baseFeePerGas?: string | undefined;
|
|
259
260
|
maxFeePerGas?: string | undefined;
|
|
260
261
|
maxPriorityFeePerGas?: string | undefined;
|
|
261
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
262
262
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
263
263
|
blocks: number;
|
|
264
264
|
feePerUnit: string;
|
|
@@ -302,6 +302,7 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
302
302
|
blockTime: number;
|
|
303
303
|
minFee: number;
|
|
304
304
|
maxFee: number;
|
|
305
|
+
minPriorityFee: number;
|
|
305
306
|
name: string;
|
|
306
307
|
shortcut: string;
|
|
307
308
|
slip44: number;
|
|
@@ -322,7 +323,6 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
322
323
|
baseFeePerGas?: string | undefined;
|
|
323
324
|
maxFeePerGas?: string | undefined;
|
|
324
325
|
maxPriorityFeePerGas?: string | undefined;
|
|
325
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
326
326
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
327
327
|
blocks: number;
|
|
328
328
|
feePerUnit: string;
|
|
@@ -365,6 +365,7 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
365
365
|
blockTime: number;
|
|
366
366
|
minFee: number;
|
|
367
367
|
maxFee: number;
|
|
368
|
+
minPriorityFee: number;
|
|
368
369
|
name: string;
|
|
369
370
|
shortcut: string;
|
|
370
371
|
slip44: number;
|
|
@@ -385,7 +386,6 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
385
386
|
baseFeePerGas?: string | undefined;
|
|
386
387
|
maxFeePerGas?: string | undefined;
|
|
387
388
|
maxPriorityFeePerGas?: string | undefined;
|
|
388
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
389
389
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
390
390
|
blocks: number;
|
|
391
391
|
feePerUnit: string;
|
|
@@ -403,6 +403,7 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
403
403
|
blockTime: number;
|
|
404
404
|
minFee: number;
|
|
405
405
|
maxFee: number;
|
|
406
|
+
minPriorityFee: number;
|
|
406
407
|
name: string;
|
|
407
408
|
shortcut: string;
|
|
408
409
|
slip44: number;
|
|
@@ -423,7 +424,6 @@ export declare const getCoinInfo: (currency: string) => ({
|
|
|
423
424
|
baseFeePerGas?: string | undefined;
|
|
424
425
|
maxFeePerGas?: string | undefined;
|
|
425
426
|
maxPriorityFeePerGas?: string | undefined;
|
|
426
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
427
427
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
428
428
|
blocks: number;
|
|
429
429
|
feePerUnit: string;
|
|
@@ -451,6 +451,7 @@ export declare const getAllNetworks: () => (({
|
|
|
451
451
|
blockTime: number;
|
|
452
452
|
minFee: number;
|
|
453
453
|
maxFee: number;
|
|
454
|
+
minPriorityFee: number;
|
|
454
455
|
name: string;
|
|
455
456
|
shortcut: string;
|
|
456
457
|
slip44: number;
|
|
@@ -471,7 +472,6 @@ export declare const getAllNetworks: () => (({
|
|
|
471
472
|
baseFeePerGas?: string | undefined;
|
|
472
473
|
maxFeePerGas?: string | undefined;
|
|
473
474
|
maxPriorityFeePerGas?: string | undefined;
|
|
474
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
475
475
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
476
476
|
blocks: number;
|
|
477
477
|
feePerUnit: string;
|
|
@@ -514,6 +514,7 @@ export declare const getAllNetworks: () => (({
|
|
|
514
514
|
blockTime: number;
|
|
515
515
|
minFee: number;
|
|
516
516
|
maxFee: number;
|
|
517
|
+
minPriorityFee: number;
|
|
517
518
|
name: string;
|
|
518
519
|
shortcut: string;
|
|
519
520
|
slip44: number;
|
|
@@ -534,7 +535,6 @@ export declare const getAllNetworks: () => (({
|
|
|
534
535
|
baseFeePerGas?: string | undefined;
|
|
535
536
|
maxFeePerGas?: string | undefined;
|
|
536
537
|
maxPriorityFeePerGas?: string | undefined;
|
|
537
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
538
538
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
539
539
|
blocks: number;
|
|
540
540
|
feePerUnit: string;
|
|
@@ -552,6 +552,7 @@ export declare const getAllNetworks: () => (({
|
|
|
552
552
|
blockTime: number;
|
|
553
553
|
minFee: number;
|
|
554
554
|
maxFee: number;
|
|
555
|
+
minPriorityFee: number;
|
|
555
556
|
name: string;
|
|
556
557
|
shortcut: string;
|
|
557
558
|
slip44: number;
|
|
@@ -572,7 +573,6 @@ export declare const getAllNetworks: () => (({
|
|
|
572
573
|
baseFeePerGas?: string | undefined;
|
|
573
574
|
maxFeePerGas?: string | undefined;
|
|
574
575
|
maxPriorityFeePerGas?: string | undefined;
|
|
575
|
-
maxWaitTimeEstimate?: number | undefined;
|
|
576
576
|
label: "normal" | "custom" | "high" | "economy" | "low";
|
|
577
577
|
blocks: number;
|
|
578
578
|
feePerUnit: string;
|
package/lib/data/coinInfo.js
CHANGED
|
@@ -187,7 +187,7 @@ const parseEthereumNetworksJson = (json) => {
|
|
|
187
187
|
const network = json[key];
|
|
188
188
|
ethereumNetworks.push({
|
|
189
189
|
...exports.ethereumNetworkInfoBase,
|
|
190
|
-
...(0, defaultFeeLevels_1.getEthereumFeeLevels)(network
|
|
190
|
+
...(0, defaultFeeLevels_1.getEthereumFeeLevels)(network),
|
|
191
191
|
blockchainLink: network.blockchain_link,
|
|
192
192
|
chainId: network.chain_id,
|
|
193
193
|
label: network.label,
|
|
@@ -137,9 +137,6 @@ const parseConnectSettings = (input = {}) => {
|
|
|
137
137
|
if (typeof input._extendWebextensionLifetime === 'boolean') {
|
|
138
138
|
settings._extendWebextensionLifetime = input._extendWebextensionLifetime;
|
|
139
139
|
}
|
|
140
|
-
if (typeof input._sessionsBackgroundUrl === 'string' || input._sessionsBackgroundUrl === null) {
|
|
141
|
-
settings._sessionsBackgroundUrl = input._sessionsBackgroundUrl;
|
|
142
|
-
}
|
|
143
140
|
if (typeof input.binFilesBaseUrl === 'string') {
|
|
144
141
|
settings.binFilesBaseUrl = input.binFilesBaseUrl;
|
|
145
142
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FeeInfo, FeeLevel } from '../types';
|
|
2
|
+
export declare const DEFAULT_BITCOIN_LONGTERM_FEE_RATE = "1";
|
|
2
3
|
interface CoinsJsonData {
|
|
3
4
|
shortcut: string;
|
|
4
5
|
blocktime_seconds: number;
|
|
@@ -6,12 +7,13 @@ interface CoinsJsonData {
|
|
|
6
7
|
maxfee_kb: number;
|
|
7
8
|
minfee_kb: number;
|
|
8
9
|
dust_limit: number;
|
|
10
|
+
chain: string;
|
|
9
11
|
}
|
|
10
12
|
export type FeeInfoWithLevels = FeeInfo & {
|
|
11
13
|
defaultFees: FeeLevel[];
|
|
12
14
|
};
|
|
13
15
|
export declare const getBitcoinFeeLevels: (coin: CoinsJsonData) => FeeInfoWithLevels;
|
|
14
|
-
export declare const getEthereumFeeLevels: (
|
|
16
|
+
export declare const getEthereumFeeLevels: (network: CoinsJsonData) => FeeInfoWithLevels;
|
|
15
17
|
export declare const getMiscFeeLevels: (data: CoinsJsonData) => FeeInfoWithLevels;
|
|
16
18
|
export {};
|
|
17
19
|
//# sourceMappingURL=defaultFeeLevels.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMiscFeeLevels = exports.getEthereumFeeLevels = exports.getBitcoinFeeLevels = void 0;
|
|
3
|
+
exports.getMiscFeeLevels = exports.getEthereumFeeLevels = exports.getBitcoinFeeLevels = exports.DEFAULT_BITCOIN_LONGTERM_FEE_RATE = void 0;
|
|
4
4
|
const utils_1 = require("@trezor/utils");
|
|
5
5
|
const BLOCKS_FOR_FEE_LEVEL = {
|
|
6
6
|
btc: {
|
|
@@ -10,21 +10,24 @@ const BLOCKS_FOR_FEE_LEVEL = {
|
|
|
10
10
|
low: 36,
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
|
+
const DEFAULT_BLOCK_FOR_FEE_LEVEL = 1;
|
|
13
14
|
const getDefaultBlocksForFeeLevel = (shortcut, label) => BLOCKS_FOR_FEE_LEVEL[shortcut] && BLOCKS_FOR_FEE_LEVEL[shortcut][label]
|
|
14
15
|
? BLOCKS_FOR_FEE_LEVEL[shortcut][label]
|
|
15
|
-
:
|
|
16
|
+
: DEFAULT_BLOCK_FOR_FEE_LEVEL;
|
|
17
|
+
exports.DEFAULT_BITCOIN_LONGTERM_FEE_RATE = '1';
|
|
16
18
|
const EVM_GAS_PRICE_PER_CHAIN_IN_GWEI = {
|
|
17
|
-
eth: { min: 1, max: 10000, defaultGas:
|
|
18
|
-
pol: { min: 1, max: 10000000, defaultGas: 200 },
|
|
19
|
-
bsc: { min: 1, max: 100000, defaultGas:
|
|
20
|
-
base: { min: 0.0000001, max: 1000, defaultGas: 0.01 },
|
|
21
|
-
arb: { min: 0.001, max: 1000, defaultGas: 0.01 },
|
|
22
|
-
op: { min: 0.000000001, max: 1000, defaultGas: 0.01 },
|
|
19
|
+
eth: { min: 0.1, max: 10000, defaultGas: 10, minPriorityFee: 0 },
|
|
20
|
+
pol: { min: 0.1, max: 10000000, defaultGas: 200, minPriorityFee: 30 },
|
|
21
|
+
bsc: { min: 0.1, max: 100000, defaultGas: 1, minPriorityFee: 0 },
|
|
22
|
+
base: { min: 0.0000001, max: 1000, defaultGas: 0.01, minPriorityFee: 0 },
|
|
23
|
+
arb: { min: 0.001, max: 1000, defaultGas: 0.01, minPriorityFee: 0 },
|
|
24
|
+
op: { min: 0.000000001, max: 1000, defaultGas: 0.01, minPriorityFee: 0 },
|
|
23
25
|
};
|
|
24
26
|
const getEvmChainGweiGasPrice = (chain) => EVM_GAS_PRICE_PER_CHAIN_IN_GWEI[chain] ?? {
|
|
25
27
|
min: 0.000000001,
|
|
26
28
|
max: 10000,
|
|
27
|
-
defaultGas:
|
|
29
|
+
defaultGas: 1,
|
|
30
|
+
minPriorityFee: 0,
|
|
28
31
|
};
|
|
29
32
|
const getBitcoinFeeLevels = (coin) => {
|
|
30
33
|
const defaultFees = coin.default_fee_b;
|
|
@@ -45,14 +48,15 @@ const getBitcoinFeeLevels = (coin) => {
|
|
|
45
48
|
dustLimit: coin.dust_limit,
|
|
46
49
|
maxFee: Math.round(coin.maxfee_kb / 1000),
|
|
47
50
|
minFee: Math.round(coin.minfee_kb / 1000),
|
|
51
|
+
minPriorityFee: -1,
|
|
48
52
|
defaultFees: levels,
|
|
49
53
|
};
|
|
50
54
|
};
|
|
51
55
|
exports.getBitcoinFeeLevels = getBitcoinFeeLevels;
|
|
52
|
-
const getEthereumFeeLevels = (
|
|
53
|
-
const { min, max, defaultGas } = getEvmChainGweiGasPrice(chain);
|
|
56
|
+
const getEthereumFeeLevels = (network) => {
|
|
57
|
+
const { min, max, defaultGas, minPriorityFee } = getEvmChainGweiGasPrice(network.chain);
|
|
54
58
|
return {
|
|
55
|
-
blockTime:
|
|
59
|
+
blockTime: Math.max(0.1, Math.round(network.blocktime_seconds)),
|
|
56
60
|
defaultFees: [
|
|
57
61
|
{
|
|
58
62
|
label: 'normal',
|
|
@@ -63,6 +67,7 @@ const getEthereumFeeLevels = (chain) => {
|
|
|
63
67
|
],
|
|
64
68
|
minFee: min,
|
|
65
69
|
maxFee: max,
|
|
70
|
+
minPriorityFee,
|
|
66
71
|
dustLimit: -1,
|
|
67
72
|
};
|
|
68
73
|
};
|
|
@@ -72,6 +77,7 @@ const RIPPLE_FEE_INFO = {
|
|
|
72
77
|
defaultFees: [{ label: 'normal', feePerUnit: '12', blocks: -1 }],
|
|
73
78
|
minFee: 10,
|
|
74
79
|
maxFee: 10000,
|
|
80
|
+
minPriorityFee: -1,
|
|
75
81
|
dustLimit: -1,
|
|
76
82
|
};
|
|
77
83
|
const CARDANO_FEE_INFO = {
|
|
@@ -79,6 +85,7 @@ const CARDANO_FEE_INFO = {
|
|
|
79
85
|
defaultFees: [{ label: 'normal', feePerUnit: '44', blocks: -1 }],
|
|
80
86
|
minFee: 44,
|
|
81
87
|
maxFee: 16384 * 44 + 155381,
|
|
88
|
+
minPriorityFee: -1,
|
|
82
89
|
dustLimit: -1,
|
|
83
90
|
};
|
|
84
91
|
const SOLANA_FEE_INFO = {
|
|
@@ -94,6 +101,7 @@ const SOLANA_FEE_INFO = {
|
|
|
94
101
|
],
|
|
95
102
|
minFee: 5000,
|
|
96
103
|
maxFee: 1000000000,
|
|
104
|
+
minPriorityFee: -1,
|
|
97
105
|
dustLimit: -1,
|
|
98
106
|
};
|
|
99
107
|
const STELLAR_FEE_INFO = {
|
|
@@ -101,6 +109,7 @@ const STELLAR_FEE_INFO = {
|
|
|
101
109
|
defaultFees: [{ label: 'normal', feePerUnit: '100', blocks: -1 }],
|
|
102
110
|
minFee: 100,
|
|
103
111
|
maxFee: 10000000,
|
|
112
|
+
minPriorityFee: -1,
|
|
104
113
|
dustLimit: -1,
|
|
105
114
|
};
|
|
106
115
|
const MISC_FEE_LEVELS = {
|
|
@@ -120,6 +129,7 @@ const getMiscFeeLevels = (data) => {
|
|
|
120
129
|
minFee: -1,
|
|
121
130
|
maxFee: -1,
|
|
122
131
|
defaultFees: [{ label: 'normal', feePerUnit: '-1', blocks: -1 }],
|
|
132
|
+
minPriorityFee: -1,
|
|
123
133
|
dustLimit: -1,
|
|
124
134
|
});
|
|
125
135
|
};
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.deviceAuthenticityConfig = void 0;
|
|
4
4
|
exports.deviceAuthenticityConfig = {
|
|
5
5
|
version: 1,
|
|
6
|
-
timestamp: '2025-
|
|
6
|
+
timestamp: '2025-05-25T12:00:00.000Z',
|
|
7
7
|
T2B1: {
|
|
8
8
|
rootPubKeys: [
|
|
9
9
|
'04ca97480ac0d7b1e6efafe518cd433cec2bf8ab9822d76eafd34363b55d63e60380bff20acc75cde03cffcb50ab6f8ce70c878e37ebc58ff7cca0a83b16b15fa5',
|
|
@@ -143,6 +143,9 @@ exports.deviceAuthenticityConfig = {
|
|
|
143
143
|
'045f5f8c0f6665149630f001871e0f5baec0633d3452da2f6c0b5a6585429525e47704eb79b2dfb8a628e429016a8f426ead61e8623be69d242553c4d67725c4f0',
|
|
144
144
|
'0459a992145ffbe5f18123380427208dc940fc946648530e516328e3b511a1fc8e920287e51aa1bbae5d015587164acabe52b04d4d48cab2d8b0415b651ffb372f',
|
|
145
145
|
'040925ae014e1fc43bdaadb1a2596f69bb5ea6bb42e8c295600940607788b2673d89eba89a0a3a2c8e46a66356f45e462f5bd84fc0254dae37c2543a837701587e',
|
|
146
|
+
'040bdbc1617f8949463c2c113df382303ade8d4e55cdff60cd424ce19e983772a7dc606c42e99f2d1dfc8fbc93e1bddb3aa112761380e12161846c25d2a0a069a9',
|
|
147
|
+
'044540af92c1a645fb36f360f6a2a685e979480fd2afe70f465199c64020779dd5c8ab2129dbca29ea893dc6b2b0af732ad09bb61d881f43bbcf4b91e91b90a592',
|
|
148
|
+
'04f7dea866ad77fe63b6c2114e7f9efdac21501de1a9fc43ee6574397353d950cb3f7cd77e19a2bf13adc6ee39ee758720b66f3802053281dedba07735bf56b7a0',
|
|
146
149
|
],
|
|
147
150
|
debug: {
|
|
148
151
|
rootPubKeys: [
|
|
@@ -2,6 +2,7 @@ import { DeviceModelInternal, FirmwareRelease, VersionArray } from '@trezor/devi
|
|
|
2
2
|
import type { Features, ReleaseInfo } from '../types';
|
|
3
3
|
export declare const parseFirmwareReleases: (json: any, deviceModel: DeviceModelInternal) => void;
|
|
4
4
|
export declare const getReleases: (deviceModel: DeviceModelInternal) => FirmwareRelease[];
|
|
5
|
+
export declare const getOnlineReleases: (internalModel: DeviceModelInternal) => Promise<FirmwareRelease[]>;
|
|
5
6
|
export interface GetInfoProps {
|
|
6
7
|
features: Features;
|
|
7
8
|
releases: FirmwareRelease[];
|