@trezor/connect 9.1.3 → 9.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +3 -1
  3. package/lib/api/authenticateDevice.d.ts +7 -0
  4. package/lib/api/authenticateDevice.js +51 -0
  5. package/lib/api/bitcoin/TransactionComposer.js +1 -9
  6. package/lib/api/bitcoin/inputs.d.ts +2 -2
  7. package/lib/api/bitcoin/outputs.d.ts +2 -2
  8. package/lib/api/cardanoGetPublicKey.d.ts +6 -2
  9. package/lib/api/cardanoGetPublicKey.js +7 -1
  10. package/lib/api/checkFirmwareAuthenticity.js +9 -8
  11. package/lib/api/common/paramsValidator.js +46 -52
  12. package/lib/api/eos/eosSignTx.js +1 -1
  13. package/lib/api/ethereum/ethereumDefinitions.js +3 -2
  14. package/lib/api/firmware/getBinary.js +1 -1
  15. package/lib/api/firmware/verifyAuthenticityProof.d.ts +14 -0
  16. package/lib/api/firmware/verifyAuthenticityProof.js +103 -0
  17. package/lib/api/firmware/x509certificate.d.ts +73 -0
  18. package/lib/api/firmware/x509certificate.js +203 -0
  19. package/lib/api/firmwareUpdate.js +4 -4
  20. package/lib/api/getAccountInfo.d.ts +1 -1
  21. package/lib/api/getAccountInfo.js +6 -6
  22. package/lib/api/getFirmwareHash.js +1 -4
  23. package/lib/api/getPublicKey.d.ts +2 -1
  24. package/lib/api/getPublicKey.js +7 -1
  25. package/lib/api/index.d.ts +1 -0
  26. package/lib/api/index.js +4 -2
  27. package/lib/api/rebootToBootloader.js +1 -4
  28. package/lib/api/signTransaction.js +1 -1
  29. package/lib/core/AbstractMethod.d.ts +5 -4
  30. package/lib/core/AbstractMethod.js +13 -11
  31. package/lib/core/index.d.ts +3 -2
  32. package/lib/core/index.js +23 -12
  33. package/lib/core/method.d.ts +1 -1
  34. package/lib/data/DataManager.d.ts +53 -7
  35. package/lib/data/DataManager.js +4 -2
  36. package/lib/data/coinInfo.d.ts +5 -5
  37. package/lib/data/coinInfo.js +1 -1
  38. package/lib/data/config.d.ts +52 -6
  39. package/lib/data/config.js +39 -28
  40. package/lib/data/connectSettings.js +3 -0
  41. package/lib/data/deviceAuthenticityConfig.d.ts +15 -0
  42. package/lib/data/deviceAuthenticityConfig.js +26 -0
  43. package/lib/data/firmwareInfo.d.ts +3 -2
  44. package/lib/data/firmwareInfo.js +19 -11
  45. package/lib/data/models.d.ts +21 -0
  46. package/lib/data/models.js +24 -0
  47. package/lib/data/version.d.ts +1 -1
  48. package/lib/data/version.js +1 -1
  49. package/lib/device/Device.d.ts +5 -3
  50. package/lib/device/Device.js +37 -22
  51. package/lib/device/DeviceCommands.js +4 -4
  52. package/lib/device/DeviceList.d.ts +2 -1
  53. package/lib/device/DeviceList.js +10 -3
  54. package/lib/events/iframe.d.ts +7 -1
  55. package/lib/events/iframe.js +1 -0
  56. package/lib/events/ui-promise.d.ts +10 -2
  57. package/lib/factory.js +1 -0
  58. package/lib/types/api/authenticateDevice.d.ts +21 -0
  59. package/lib/types/api/authenticateDevice.js +3 -0
  60. package/lib/types/api/authorizeCoinjoin.d.ts +2 -2
  61. package/lib/types/api/binance/index.d.ts +2 -1
  62. package/lib/types/api/bitcoin/index.d.ts +6 -5
  63. package/lib/types/api/cardano/index.d.ts +12 -12
  64. package/lib/types/api/cipherKeyValue.d.ts +2 -2
  65. package/lib/types/api/eos/index.d.ts +3 -2
  66. package/lib/types/api/ethereum/index.d.ts +5 -4
  67. package/lib/types/api/getAccountInfo.d.ts +1 -0
  68. package/lib/types/api/getOwnershipId.d.ts +2 -2
  69. package/lib/types/api/getOwnershipProof.d.ts +2 -2
  70. package/lib/types/api/index.d.ts +2 -0
  71. package/lib/types/api/nem/index.d.ts +2 -1
  72. package/lib/types/api/ripple/index.d.ts +2 -1
  73. package/lib/types/api/stellar/index.d.ts +2 -1
  74. package/lib/types/api/tezos/index.d.ts +3 -2
  75. package/lib/types/api/unlockPath.d.ts +2 -2
  76. package/lib/types/coinInfo.d.ts +3 -2
  77. package/lib/types/device.d.ts +6 -0
  78. package/lib/types/firmware.d.ts +8 -4
  79. package/lib/types/index.d.ts +1 -0
  80. package/lib/types/params.d.ts +14 -2
  81. package/lib/utils/assetUtils.js +6 -4
  82. package/lib/utils/debug.d.ts +9 -3
  83. package/lib/utils/debug.js +50 -17
  84. package/lib/utils/deviceFeaturesUtils.js +7 -7
  85. package/lib/utils/pathUtils.d.ts +3 -3
  86. package/package.json +14 -13
  87. package/lib/utils/deferred.d.ts +0 -18
  88. package/lib/utils/deferred.js +0 -66
  89. package/lib/utils/versionUtils.d.ts +0 -8
  90. package/lib/utils/versionUtils.js +0 -75
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseCertificate = exports.parseName = void 0;
4
+ const derToAsn1 = (byteArray) => {
5
+ let position = 0;
6
+ function getTag() {
7
+ let tag = byteArray[0] & 0x1f;
8
+ position += 1;
9
+ if (tag === 0x1f) {
10
+ tag = 0;
11
+ while (byteArray[position] >= 0x80) {
12
+ tag = tag * 128 + byteArray[position] - 0x80;
13
+ position += 1;
14
+ }
15
+ tag = tag * 128 + byteArray[position] - 0x80;
16
+ position += 1;
17
+ }
18
+ return tag;
19
+ }
20
+ function getLength() {
21
+ let length = 0;
22
+ if (byteArray[position] < 0x80) {
23
+ length = byteArray[position];
24
+ position += 1;
25
+ }
26
+ else {
27
+ const numberOfDigits = byteArray[position] & 0x7f;
28
+ position += 1;
29
+ length = 0;
30
+ for (let i = 0; i < numberOfDigits; i++) {
31
+ length = length * 256 + byteArray[position];
32
+ position += 1;
33
+ }
34
+ }
35
+ return length;
36
+ }
37
+ const cls = (byteArray[0] & 0xc0) / 64;
38
+ const structured = (byteArray[0] & 0x20) === 0x20;
39
+ const tag = getTag();
40
+ let length = getLength();
41
+ let byteLength;
42
+ let contents;
43
+ if (length === 0x80) {
44
+ length = 0;
45
+ while (byteArray[position + length] !== 0 || byteArray[position + length + 1] !== 0) {
46
+ length += 1;
47
+ }
48
+ byteLength = position + length + 2;
49
+ contents = byteArray.subarray(position, position + length);
50
+ }
51
+ else {
52
+ byteLength = position + length;
53
+ contents = byteArray.subarray(position, byteLength);
54
+ }
55
+ const raw = byteArray.subarray(0, byteLength);
56
+ return {
57
+ cls,
58
+ tag,
59
+ structured,
60
+ byteLength,
61
+ contents,
62
+ raw,
63
+ };
64
+ };
65
+ const derToAsn1List = (byteArray) => {
66
+ const result = [];
67
+ let nextPosition = 0;
68
+ while (nextPosition < byteArray.length) {
69
+ const nextPiece = derToAsn1(byteArray.subarray(nextPosition));
70
+ result.push(nextPiece);
71
+ nextPosition += nextPiece.byteLength;
72
+ }
73
+ return result;
74
+ };
75
+ const derBitStringValue = (byteArray) => ({
76
+ unusedBits: byteArray[0],
77
+ bytes: byteArray.subarray(1),
78
+ });
79
+ const parseSignatureValue = (asn1) => {
80
+ if (asn1.cls !== 0 || asn1.tag !== 3 || asn1.structured) {
81
+ throw new Error('Bad signature value. Not a BIT STRING.');
82
+ }
83
+ return {
84
+ asn1,
85
+ bits: derBitStringValue(asn1.contents),
86
+ };
87
+ };
88
+ const derObjectIdentifierValue = (byteArray) => {
89
+ let oid = `${Math.floor(byteArray[0] / 40)}.${byteArray[0] % 40}`;
90
+ let position = 1;
91
+ while (position < byteArray.length) {
92
+ let nextInteger = 0;
93
+ while (byteArray[position] >= 0x80) {
94
+ nextInteger = nextInteger * 0x80 + (byteArray[position] & 0x7f);
95
+ position += 1;
96
+ }
97
+ nextInteger = nextInteger * 0x80 + byteArray[position];
98
+ position += 1;
99
+ oid += `.${nextInteger}`;
100
+ }
101
+ return oid;
102
+ };
103
+ const parseAlgorithmIdentifier = (asn1) => {
104
+ if (asn1.cls !== 0 || asn1.tag !== 16 || !asn1.structured) {
105
+ throw new Error('Bad algorithm identifier. Not a SEQUENCE.');
106
+ }
107
+ const pieces = derToAsn1List(asn1.contents);
108
+ if (pieces.length > 2) {
109
+ throw new Error('Bad algorithm identifier. Contains too many child objects.');
110
+ }
111
+ const encodedAlgorithm = pieces[0];
112
+ if (encodedAlgorithm.cls !== 0 || encodedAlgorithm.tag !== 6 || encodedAlgorithm.structured) {
113
+ throw new Error('Bad algorithm identifier. Does not begin with an OBJECT IDENTIFIER.');
114
+ }
115
+ const algorithm = derObjectIdentifierValue(encodedAlgorithm.contents);
116
+ return {
117
+ asn1,
118
+ algorithm,
119
+ parameters: pieces.length === 2 ? { asn1: pieces[1] } : null,
120
+ };
121
+ };
122
+ const parseName = (asn1) => derToAsn1List(asn1.contents).map(item => {
123
+ const attrSet = derToAsn1(item.contents);
124
+ return parseAlgorithmIdentifier(attrSet);
125
+ });
126
+ exports.parseName = parseName;
127
+ const parseSubjectPublicKeyInfo = (asn1) => {
128
+ if (asn1.cls !== 0 || asn1.tag !== 16 || !asn1.structured) {
129
+ throw new Error('Bad SPKI. Not a SEQUENCE.');
130
+ }
131
+ const pieces = derToAsn1List(asn1.contents);
132
+ if (pieces.length !== 2) {
133
+ throw new Error('Bad SubjectPublicKeyInfo. Wrong number of child objects.');
134
+ }
135
+ return {
136
+ asn1,
137
+ algorithm: parseAlgorithmIdentifier(pieces[0]),
138
+ bits: derBitStringValue(pieces[1].contents),
139
+ };
140
+ };
141
+ const parseUtcTime = (time) => {
142
+ let offset = 4;
143
+ let yearOffset = 0;
144
+ if (time.tag === 23) {
145
+ offset = 2;
146
+ yearOffset = 2000;
147
+ }
148
+ const utc = Buffer.from(time.contents).toString();
149
+ const year = yearOffset + Number(utc.substring(0, offset));
150
+ const month = Number(utc.substring(offset, offset + 2)) - 1;
151
+ const day = Number(utc.substring(offset + 2, offset + 4));
152
+ const hour = Number(utc.substring(offset + 4, offset + 6));
153
+ const minute = Number(utc.substring(offset + 6, offset + 8));
154
+ const date = new Date();
155
+ date.setUTCFullYear(year, month, day);
156
+ date.setUTCHours(hour, minute, 0);
157
+ return date;
158
+ };
159
+ const parseValidity = (asn1) => {
160
+ const [from, to] = derToAsn1List(asn1.contents);
161
+ return {
162
+ from: parseUtcTime(from),
163
+ to: parseUtcTime(to),
164
+ };
165
+ };
166
+ const parseTBSCertificate = (asn1) => {
167
+ if (asn1.cls !== 0 || asn1.tag !== 16 || !asn1.structured) {
168
+ throw new Error("This can't be a TBSCertificate. Wrong data type.");
169
+ }
170
+ const pieces = derToAsn1List(asn1.contents);
171
+ if (pieces.length < 7) {
172
+ throw new Error('Bad TBS Certificate. There are fewer than the seven required children.');
173
+ }
174
+ return {
175
+ asn1,
176
+ version: pieces[0],
177
+ serialNumber: pieces[1],
178
+ signature: parseAlgorithmIdentifier(pieces[2]),
179
+ issuer: pieces[3],
180
+ validity: parseValidity(pieces[4]),
181
+ subject: (0, exports.parseName)(pieces[5]),
182
+ subjectPublicKeyInfo: parseSubjectPublicKeyInfo(pieces[6]),
183
+ extensions: pieces[7],
184
+ };
185
+ };
186
+ const parseCertificate = (byteArray) => {
187
+ const asn1 = derToAsn1(byteArray);
188
+ if (asn1.cls !== 0 || asn1.tag !== 16 || !asn1.structured) {
189
+ throw new Error("This can't be an X.509 certificate. Wrong data type.");
190
+ }
191
+ const pieces = derToAsn1List(asn1.contents);
192
+ if (pieces.length !== 3) {
193
+ throw new Error('Certificate contains more than the three specified children.');
194
+ }
195
+ return {
196
+ asn1,
197
+ tbsCertificate: parseTBSCertificate(pieces[0]),
198
+ signatureAlgorithm: parseAlgorithmIdentifier(pieces[1]),
199
+ signatureValue: parseSignatureValue(pieces[2]),
200
+ };
201
+ };
202
+ exports.parseCertificate = parseCertificate;
203
+ //# sourceMappingURL=x509certificate.js.map
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const randombytes_1 = tslib_1.__importDefault(require("randombytes"));
3
+ const crypto_1 = require("crypto");
5
4
  const AbstractMethod_1 = require("../core/AbstractMethod");
6
5
  const constants_1 = require("../constants");
7
6
  const events_1 = require("../events");
@@ -54,6 +53,7 @@ class FirmwareUpdate extends AbstractMethod_1.AbstractMethod {
54
53
  return uiResp.payload;
55
54
  }
56
55
  async run() {
56
+ var _a;
57
57
  const { device, params } = this;
58
58
  let binary;
59
59
  try {
@@ -63,7 +63,7 @@ class FirmwareUpdate extends AbstractMethod_1.AbstractMethod {
63
63
  else {
64
64
  binary = await (0, firmware_1.getBinary)({
65
65
  features: device.features,
66
- releases: (0, firmwareInfo_1.getReleases)(device.features.major_version),
66
+ releases: (0, firmwareInfo_1.getReleases)((_a = device.features) === null || _a === void 0 ? void 0 : _a.internal_model),
67
67
  version: params.version,
68
68
  btcOnly: params.btcOnly,
69
69
  baseUrl: params.baseUrl,
@@ -76,7 +76,7 @@ class FirmwareUpdate extends AbstractMethod_1.AbstractMethod {
76
76
  }
77
77
  const stripped = (0, firmware_1.stripFwHeaders)(binary);
78
78
  await (0, firmware_1.uploadFirmware)(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, { payload: (0, firmware_1.shouldStripFwHeaders)(device.features) ? stripped : binary });
79
- return (0, firmware_1.calculateFirmwareHash)(device.features.major_version, stripped, (0, randombytes_1.default)(32));
79
+ return (0, firmware_1.calculateFirmwareHash)(device.features.major_version, stripped, (0, crypto_1.randomBytes)(32));
80
80
  }
81
81
  }
82
82
  exports.default = FirmwareUpdate;
@@ -13,7 +13,7 @@ export default class GetAccountInfo extends AbstractMethod<'getAccountInfo', Req
13
13
  init(): void;
14
14
  get info(): string;
15
15
  confirmation(): Promise<boolean>;
16
- noBackupConfirmation(): Promise<boolean>;
16
+ noBackupConfirmation(allowSuppression?: boolean): Promise<boolean>;
17
17
  checkFirmwareRange(isUsingPopup: boolean): Promise<"ui-device_firmware_old" | "ui-device_firmware_unsupported" | "ui-device_firmware_not_compatible" | "ui-device_firmware_not_installed" | undefined>;
18
18
  run(): Promise<AccountInfo | (AccountInfo | null)[] | {
19
19
  utxo: AccountUtxo[] | undefined;
@@ -41,6 +41,7 @@ class GetAccountInfo extends AbstractMethod_1.AbstractMethod {
41
41
  { name: 'marker', type: 'object' },
42
42
  { name: 'defaultAccountType', type: 'string' },
43
43
  { name: 'derivationType', type: 'number' },
44
+ { name: 'suppressBackupWarning', type: 'boolean' },
44
45
  ]);
45
46
  const coinInfo = (0, coinInfo_1.getCoinInfo)(batch.coin);
46
47
  if (!coinInfo) {
@@ -119,7 +120,10 @@ class GetAccountInfo extends AbstractMethod_1.AbstractMethod {
119
120
  const uiResp = await uiPromise.promise;
120
121
  return uiResp.payload;
121
122
  }
122
- async noBackupConfirmation() {
123
+ async noBackupConfirmation(allowSuppression) {
124
+ if (allowSuppression && this.params.every(batch => batch.suppressBackupWarning)) {
125
+ return true;
126
+ }
123
127
  await this.getPopupPromise().promise;
124
128
  const uiPromise = this.createUiPromise(events_1.UI.RECEIVE_CONFIRMATION);
125
129
  this.postMessage((0, events_1.createUiMessage)(events_1.UI.REQUEST_CONFIRMATION, {
@@ -132,13 +136,9 @@ class GetAccountInfo extends AbstractMethod_1.AbstractMethod {
132
136
  if (isUsingPopup || this.params.length === 1) {
133
137
  return super.checkFirmwareRange(isUsingPopup);
134
138
  }
135
- const defaultRange = {
136
- 1: { min: '1.0.0', max: '0' },
137
- 2: { min: '2.0.0', max: '0' },
138
- };
139
139
  const invalid = [];
140
140
  for (let i = 0; i < this.params.length; i++) {
141
- this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, this.params[i].coinInfo, defaultRange);
141
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, this.params[i].coinInfo, AbstractMethod_1.DEFAULT_FIRMWARE_RANGE);
142
142
  const exception = await super.checkFirmwareRange(false);
143
143
  if (exception) {
144
144
  invalid.push({
@@ -11,10 +11,7 @@ class GetFirmwareHash extends AbstractMethod_1.AbstractMethod {
11
11
  this.allowDeviceMode = [events_1.UI.INITIALIZE];
12
12
  const { payload } = this;
13
13
  (0, paramsValidator_1.validateParams)(payload, [{ name: 'challenge', type: 'string' }]);
14
- this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, {
15
- 1: { min: '1.11.1', max: '0' },
16
- 2: { min: '2.5.1', max: '0' },
17
- });
14
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, this.firmwareRange);
18
15
  this.params = {
19
16
  challenge: payload.challenge,
20
17
  };
@@ -3,6 +3,7 @@ import type { BitcoinNetworkInfo } from '../types';
3
3
  import type { PROTO } from '../constants';
4
4
  type Params = PROTO.GetPublicKey & {
5
5
  coinInfo?: BitcoinNetworkInfo;
6
+ suppressBackupWarning?: boolean;
6
7
  unlockPath?: PROTO.UnlockPath;
7
8
  };
8
9
  export default class GetPublicKey extends AbstractMethod<'getPublicKey', Params[]> {
@@ -11,7 +12,7 @@ export default class GetPublicKey extends AbstractMethod<'getPublicKey', Params[
11
12
  init(): void;
12
13
  get info(): string;
13
14
  confirmation(): Promise<boolean>;
14
- noBackupConfirmation(): Promise<boolean>;
15
+ noBackupConfirmation(allowSuppression?: boolean): Promise<boolean>;
15
16
  run(): Promise<import("../types/api/getPublicKey").HDNodeResponse | import("../types/api/getPublicKey").HDNodeResponse[]>;
16
17
  }
17
18
  export {};
@@ -24,6 +24,7 @@ class GetPublicKey extends AbstractMethod_1.AbstractMethod {
24
24
  { name: 'ignoreXpubMagic', type: 'boolean' },
25
25
  { name: 'ecdsaCurveName', type: 'boolean' },
26
26
  { name: 'unlockPath', type: 'object' },
27
+ { name: 'suppressBackupWarning', type: 'boolean' },
27
28
  ]);
28
29
  if (batch.unlockPath) {
29
30
  (0, paramsValidator_1.validateParams)(batch.unlockPath, [
@@ -54,6 +55,7 @@ class GetPublicKey extends AbstractMethod_1.AbstractMethod {
54
55
  ecdsa_curve_name: batch.ecdsaCurveName,
55
56
  coinInfo,
56
57
  unlockPath: batch.unlockPath,
58
+ suppress_backup_warning: batch.suppressBackupWarning,
57
59
  };
58
60
  });
59
61
  }
@@ -80,7 +82,11 @@ class GetPublicKey extends AbstractMethod_1.AbstractMethod {
80
82
  this.confirmed = uiResp.payload;
81
83
  return this.confirmed;
82
84
  }
83
- async noBackupConfirmation() {
85
+ async noBackupConfirmation(allowSuppression) {
86
+ if (allowSuppression &&
87
+ this.params.every(batch => batch.suppressBackupWarning || !batch.show_display)) {
88
+ return true;
89
+ }
84
90
  await this.getPopupPromise().promise;
85
91
  const uiPromise = this.createUiPromise(events_1.UI.RECEIVE_CONFIRMATION);
86
92
  this.postMessage((0, events_1.createUiMessage)(events_1.UI.REQUEST_CONFIRMATION, {
@@ -1,5 +1,6 @@
1
1
  export { default as applyFlags } from './applyFlags';
2
2
  export { default as applySettings } from './applySettings';
3
+ export { default as authenticateDevice } from './authenticateDevice';
3
4
  export { default as authorizeCoinjoin } from './authorizeCoinjoin';
4
5
  export { default as cancelCoinjoinAuthorization } from './cancelCoinjoinAuthorization';
5
6
  export { default as showDeviceTutorial } from './showDeviceTutorial';
package/lib/api/index.js CHANGED
@@ -3,12 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.rebootToBootloader = exports.pushTransaction = exports.nemSignTransaction = exports.nemGetAddress = exports.getSettings = exports.getPublicKey = exports.getOwnershipProof = exports.getOwnershipId = exports.getFirmwareHash = exports.getFeatures = exports.getDeviceState = exports.getCoinInfo = exports.getAddress = exports.getAccountInfo = exports.firmwareUpdate = exports.ethereumVerifyMessage = exports.ethereumSignTypedData = exports.ethereumSignTransaction = exports.ethereumSignMessage = exports.ethereumGetPublicKey = exports.ethereumGetAddress = exports.eosSignTransaction = exports.eosGetPublicKey = exports.composeTransaction = exports.cipherKeyValue = exports.changePin = exports.cardanoSignTransaction = exports.cardanoGetPublicKey = exports.cardanoGetNativeScriptHash = exports.cardanoGetAddress = exports.blockchainUnsubscribeFiatRates = exports.blockchainUnsubscribe = exports.blockchainSubscribeFiatRates = exports.blockchainSubscribe = exports.blockchainSetCustomBackend = exports.blockchainGetTransactions = exports.blockchainGetFiatRatesForTimestamps = exports.blockchainGetCurrentFiatRates = exports.blockchainGetAccountBalanceHistory = exports.blockchainEstimateFee = exports.blockchainDisconnect = exports.binanceSignTransaction = exports.binanceGetPublicKey = exports.binanceGetAddress = exports.backupDevice = exports.showDeviceTutorial = exports.cancelCoinjoinAuthorization = exports.authorizeCoinjoin = exports.applySettings = exports.applyFlags = void 0;
7
- exports.checkFirmwareAuthenticity = exports.wipeDevice = exports.verifyMessage = exports.unlockPath = exports.tezosSignTransaction = exports.tezosGetPublicKey = exports.tezosGetAddress = exports.stellarSignTransaction = exports.stellarGetAddress = exports.signTransaction = exports.signMessage = exports.setProxy = exports.setBusy = exports.rippleSignTransaction = exports.rippleGetAddress = exports.resetDevice = exports.requestLogin = exports.recoveryDevice = void 0;
6
+ exports.pushTransaction = exports.nemSignTransaction = exports.nemGetAddress = exports.getSettings = exports.getPublicKey = exports.getOwnershipProof = exports.getOwnershipId = exports.getFirmwareHash = exports.getFeatures = exports.getDeviceState = exports.getCoinInfo = exports.getAddress = exports.getAccountInfo = exports.firmwareUpdate = exports.ethereumVerifyMessage = exports.ethereumSignTypedData = exports.ethereumSignTransaction = exports.ethereumSignMessage = exports.ethereumGetPublicKey = exports.ethereumGetAddress = exports.eosSignTransaction = exports.eosGetPublicKey = exports.composeTransaction = exports.cipherKeyValue = exports.changePin = exports.cardanoSignTransaction = exports.cardanoGetPublicKey = exports.cardanoGetNativeScriptHash = exports.cardanoGetAddress = exports.blockchainUnsubscribeFiatRates = exports.blockchainUnsubscribe = exports.blockchainSubscribeFiatRates = exports.blockchainSubscribe = exports.blockchainSetCustomBackend = exports.blockchainGetTransactions = exports.blockchainGetFiatRatesForTimestamps = exports.blockchainGetCurrentFiatRates = exports.blockchainGetAccountBalanceHistory = exports.blockchainEstimateFee = exports.blockchainDisconnect = exports.binanceSignTransaction = exports.binanceGetPublicKey = exports.binanceGetAddress = exports.backupDevice = exports.showDeviceTutorial = exports.cancelCoinjoinAuthorization = exports.authorizeCoinjoin = exports.authenticateDevice = exports.applySettings = exports.applyFlags = void 0;
7
+ exports.checkFirmwareAuthenticity = exports.wipeDevice = exports.verifyMessage = exports.unlockPath = exports.tezosSignTransaction = exports.tezosGetPublicKey = exports.tezosGetAddress = exports.stellarSignTransaction = exports.stellarGetAddress = exports.signTransaction = exports.signMessage = exports.setProxy = exports.setBusy = exports.rippleSignTransaction = exports.rippleGetAddress = exports.resetDevice = exports.requestLogin = exports.recoveryDevice = exports.rebootToBootloader = void 0;
8
8
  var applyFlags_1 = require("./applyFlags");
9
9
  Object.defineProperty(exports, "applyFlags", { enumerable: true, get: function () { return __importDefault(applyFlags_1).default; } });
10
10
  var applySettings_1 = require("./applySettings");
11
11
  Object.defineProperty(exports, "applySettings", { enumerable: true, get: function () { return __importDefault(applySettings_1).default; } });
12
+ var authenticateDevice_1 = require("./authenticateDevice");
13
+ Object.defineProperty(exports, "authenticateDevice", { enumerable: true, get: function () { return __importDefault(authenticateDevice_1).default; } });
12
14
  var authorizeCoinjoin_1 = require("./authorizeCoinjoin");
13
15
  Object.defineProperty(exports, "authorizeCoinjoin", { enumerable: true, get: function () { return __importDefault(authorizeCoinjoin_1).default; } });
14
16
  var cancelCoinjoinAuthorization_1 = require("./cancelCoinjoinAuthorization");
@@ -10,10 +10,7 @@ class RebootToBootloader extends AbstractMethod_1.AbstractMethod {
10
10
  this.keepSession = false;
11
11
  this.requiredPermissions = ['management'];
12
12
  this.useDeviceState = false;
13
- this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, {
14
- 1: { min: '1.10.0', max: '0' },
15
- 2: { min: '2.6.0', max: '0' },
16
- });
13
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, this.firmwareRange);
17
14
  }
18
15
  get info() {
19
16
  return 'Reboot to bootloader';
@@ -70,7 +70,7 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
70
70
  }
71
71
  this.params = {
72
72
  inputs,
73
- outputs: payload.outputs,
73
+ outputs,
74
74
  paymentRequests: payload.paymentRequests || [],
75
75
  refTxs,
76
76
  addresses: payload.account ? payload.account.addresses : undefined,
@@ -1,6 +1,6 @@
1
+ import { Deferred } from '@trezor/utils';
1
2
  import { NETWORK } from '../constants';
2
- import { CallMethodPayload, CallMethodResponse, UiRequestButtonData, UiPromise, UiPromiseResponse, PostMessage } from '../events';
3
- import { Deferred } from '../utils/deferred';
3
+ import { CallMethodPayload, CallMethodResponse, UiRequestButtonData, UiPromiseCreator, PostMessage } from '../events';
4
4
  import type { Device } from '../device/Device';
5
5
  import type { FirmwareRange } from '../types';
6
6
  export type Payload<M> = Extract<CallMethodPayload, {
@@ -9,6 +9,7 @@ export type Payload<M> = Extract<CallMethodPayload, {
9
9
  override?: boolean;
10
10
  };
11
11
  export type MethodReturnType<M extends CallMethodPayload['method']> = CallMethodResponse<M>;
12
+ export declare const DEFAULT_FIRMWARE_RANGE: FirmwareRange;
12
13
  export declare abstract class AbstractMethod<Name extends CallMethodPayload['method'], Params = undefined> {
13
14
  responseID: number;
14
15
  device: Device;
@@ -37,11 +38,11 @@ export declare abstract class AbstractMethod<Name extends CallMethodPayload['met
37
38
  network: NETWORK.NetworkType;
38
39
  useCardanoDerivation: boolean;
39
40
  confirmation?(): Promise<boolean | undefined>;
40
- noBackupConfirmation?(): Promise<boolean>;
41
+ noBackupConfirmation?(allowSuppression?: boolean): Promise<boolean>;
41
42
  getButtonRequestData?(code: string): UiRequestButtonData | undefined;
42
43
  postMessage: PostMessage;
43
44
  getPopupPromise: () => Deferred<void>;
44
- createUiPromise: <T extends UiPromiseResponse['type']>(promiseId: T, device?: Device) => UiPromise<T>;
45
+ createUiPromise: UiPromiseCreator;
45
46
  removeUiPromise: (promise: Deferred<any>) => void;
46
47
  initAsync?(): Promise<void>;
47
48
  initAsyncPromise?: Promise<void>;
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AbstractMethod = void 0;
3
+ exports.AbstractMethod = exports.DEFAULT_FIRMWARE_RANGE = void 0;
4
4
  const connect_common_1 = require("@trezor/connect-common");
5
+ const utils_1 = require("@trezor/utils");
5
6
  const DataManager_1 = require("../data/DataManager");
6
7
  const constants_1 = require("../constants");
7
8
  const events_1 = require("../events");
8
- const versionUtils_1 = require("../utils/versionUtils");
9
9
  const urlUtils_1 = require("../utils/urlUtils");
10
+ exports.DEFAULT_FIRMWARE_RANGE = {
11
+ T1B1: { min: '1.0.0', max: '0' },
12
+ T2T1: { min: '2.0.0', max: '0' },
13
+ T2B1: { min: '2.6.1', max: '0' },
14
+ };
10
15
  class AbstractMethod {
11
16
  get info() {
12
17
  return '';
@@ -44,10 +49,7 @@ class AbstractMethod {
44
49
  this.network = key;
45
50
  }
46
51
  });
47
- this.firmwareRange = {
48
- '1': { min: '1.0.0', max: '0' },
49
- '2': { min: '2.0.0', max: '0' },
50
- };
52
+ this.firmwareRange = exports.DEFAULT_FIRMWARE_RANGE;
51
53
  this.requiredPermissions = [];
52
54
  this.useDevice = true;
53
55
  this.useDeviceState = true;
@@ -130,19 +132,19 @@ class AbstractMethod {
130
132
  const { device } = this;
131
133
  if (!device.features)
132
134
  return;
133
- const version = device.getVersion();
134
- const model = version[0];
135
- const range = this.firmwareRange[model];
135
+ const range = this.firmwareRange[device.features.internal_model];
136
136
  if (device.firmwareStatus === 'none') {
137
137
  return events_1.UI.FIRMWARE_NOT_INSTALLED;
138
138
  }
139
139
  if (range.min === '0') {
140
140
  return events_1.UI.FIRMWARE_NOT_SUPPORTED;
141
141
  }
142
- if (device.firmwareStatus === 'required' || (0, versionUtils_1.versionCompare)(version, range.min) < 0) {
142
+ const version = device.getVersion().join('.');
143
+ if (device.firmwareStatus === 'required' ||
144
+ !utils_1.versionUtils.isNewerOrEqual(version, range.min)) {
143
145
  return events_1.UI.FIRMWARE_OLD;
144
146
  }
145
- if (range.max !== '0' && (0, versionUtils_1.versionCompare)(version, range.max) > 0) {
147
+ if (range.max !== '0' && utils_1.versionUtils.isNewer(version, range.max)) {
146
148
  if (isUsingPopup) {
147
149
  await this.getPopupPromise().promise;
148
150
  const uiPromise = this.createUiPromise(events_1.UI.RECEIVE_CONFIRMATION);
@@ -1,15 +1,16 @@
1
1
  /// <reference types="node" />
2
2
  import EventEmitter from 'events';
3
3
  import { TransportInfo, CoreMessage } from '../events';
4
+ import { LogWriter } from '../utils/debug';
4
5
  import type { ConnectSettings } from '../types';
5
6
  export declare const handleMessage: (message: CoreMessage) => void;
6
7
  export declare const onCall: (message: CoreMessage) => Promise<void>;
7
8
  export declare class Core extends EventEmitter {
8
9
  handleMessage(message: any): void;
9
10
  dispose(): Promise<void>;
10
- getCurrentMethod(): (import("../api").applyFlags | import("../api").applySettings | import("../api").authorizeCoinjoin | import("../api").cancelCoinjoinAuthorization | import("../api").showDeviceTutorial | import("../api").backupDevice | import("../api").binanceGetAddress | import("../api").binanceGetPublicKey | import("../api").binanceSignTransaction | import("../api").blockchainDisconnect | import("../api").blockchainEstimateFee | import("../api").blockchainGetAccountBalanceHistory | import("../api").blockchainGetCurrentFiatRates | import("../api").blockchainGetFiatRatesForTimestamps | import("../api").blockchainGetTransactions | import("../api").blockchainSetCustomBackend | import("../api").blockchainSubscribe | import("../api").blockchainSubscribeFiatRates | import("../api").blockchainUnsubscribe | import("../api").blockchainUnsubscribeFiatRates | import("../api").cardanoGetAddress | import("../api").cardanoGetNativeScriptHash | import("../api").cardanoGetPublicKey | import("../api").cardanoSignTransaction | import("../api").changePin | import("../api").cipherKeyValue | import("../api").composeTransaction | import("../api").eosGetPublicKey | import("../api").eosSignTransaction | import("../api").ethereumGetAddress | import("../api").ethereumGetPublicKey | import("../api").ethereumSignMessage | import("../api").ethereumSignTransaction | import("../api").ethereumSignTypedData | import("../api").ethereumVerifyMessage | import("../api").firmwareUpdate | import("../api").getAccountInfo | import("../api").getAddress | import("../api").getCoinInfo | import("../api").getDeviceState | import("../api").getFeatures | import("../api").getFirmwareHash | import("../api").getOwnershipId | import("../api").getOwnershipProof | import("../api").getPublicKey | import("../api").getSettings | import("../api").nemGetAddress | import("../api").nemSignTransaction | import("../api").pushTransaction | import("../api").rebootToBootloader | import("../api").recoveryDevice | import("../api").requestLogin | import("../api").resetDevice | import("../api").rippleGetAddress | import("../api").rippleSignTransaction | import("../api").setBusy | import("../api").setProxy | import("../api").signMessage | import("../api").signTransaction | import("../api").stellarGetAddress | import("../api").stellarSignTransaction | import("../api").tezosGetAddress | import("../api").tezosGetPublicKey | import("../api").tezosSignTransaction | import("../api").unlockPath | import("../api").verifyMessage | import("../api").wipeDevice | import("../api").checkFirmwareAuthenticity)[];
11
+ getCurrentMethod(): (import("../api").applyFlags | import("../api").applySettings | import("../api").authenticateDevice | import("../api").authorizeCoinjoin | import("../api").cancelCoinjoinAuthorization | import("../api").showDeviceTutorial | import("../api").backupDevice | import("../api").binanceGetAddress | import("../api").binanceGetPublicKey | import("../api").binanceSignTransaction | import("../api").blockchainDisconnect | import("../api").blockchainEstimateFee | import("../api").blockchainGetAccountBalanceHistory | import("../api").blockchainGetCurrentFiatRates | import("../api").blockchainGetFiatRatesForTimestamps | import("../api").blockchainGetTransactions | import("../api").blockchainSetCustomBackend | import("../api").blockchainSubscribe | import("../api").blockchainSubscribeFiatRates | import("../api").blockchainUnsubscribe | import("../api").blockchainUnsubscribeFiatRates | import("../api").cardanoGetAddress | import("../api").cardanoGetNativeScriptHash | import("../api").cardanoGetPublicKey | import("../api").cardanoSignTransaction | import("../api").changePin | import("../api").cipherKeyValue | import("../api").composeTransaction | import("../api").eosGetPublicKey | import("../api").eosSignTransaction | import("../api").ethereumGetAddress | import("../api").ethereumGetPublicKey | import("../api").ethereumSignMessage | import("../api").ethereumSignTransaction | import("../api").ethereumSignTypedData | import("../api").ethereumVerifyMessage | import("../api").firmwareUpdate | import("../api").getAccountInfo | import("../api").getAddress | import("../api").getCoinInfo | import("../api").getDeviceState | import("../api").getFeatures | import("../api").getFirmwareHash | import("../api").getOwnershipId | import("../api").getOwnershipProof | import("../api").getPublicKey | import("../api").getSettings | import("../api").nemGetAddress | import("../api").nemSignTransaction | import("../api").pushTransaction | import("../api").rebootToBootloader | import("../api").recoveryDevice | import("../api").requestLogin | import("../api").resetDevice | import("../api").rippleGetAddress | import("../api").rippleSignTransaction | import("../api").setBusy | import("../api").setProxy | import("../api").signMessage | import("../api").signTransaction | import("../api").stellarGetAddress | import("../api").stellarSignTransaction | import("../api").tezosGetAddress | import("../api").tezosGetPublicKey | import("../api").tezosSignTransaction | import("../api").unlockPath | import("../api").verifyMessage | import("../api").wipeDevice | import("../api").checkFirmwareAuthenticity)[];
11
12
  getTransportInfo(): TransportInfo | undefined;
12
13
  }
13
- export declare const initCore: (settings: ConnectSettings) => Promise<Core>;
14
+ export declare const initCore: (settings: ConnectSettings, logWriterFactory?: () => LogWriter | undefined) => Promise<Core>;
14
15
  export declare const initTransport: (settings: ConnectSettings) => Promise<void>;
15
16
  //# sourceMappingURL=index.d.ts.map
package/lib/core/index.js CHANGED
@@ -4,13 +4,13 @@ exports.initTransport = exports.initCore = exports.Core = exports.onCall = expor
4
4
  const tslib_1 = require("tslib");
5
5
  const events_1 = tslib_1.__importDefault(require("events"));
6
6
  const transport_1 = require("@trezor/transport");
7
+ const utils_1 = require("@trezor/utils");
7
8
  const DataManager_1 = require("../data/DataManager");
8
9
  const DeviceList_1 = require("../device/DeviceList");
9
10
  const analyticsInfo_1 = require("../data/analyticsInfo");
10
11
  const constants_1 = require("../constants");
11
12
  const events_2 = require("../events");
12
13
  const method_1 = require("./method");
13
- const deferred_1 = require("../utils/deferred");
14
14
  const promiseUtils_1 = require("../utils/promiseUtils");
15
15
  const debug_1 = require("../utils/debug");
16
16
  const BlockchainLink_1 = require("../backend/BlockchainLink");
@@ -18,7 +18,7 @@ const interactionTimeout_1 = require("../utils/interactionTimeout");
18
18
  let _core;
19
19
  let _deviceList;
20
20
  let _popupPromise;
21
- let _uiPromises = [];
21
+ const _uiPromises = [];
22
22
  const _callMethods = [];
23
23
  let _preferredDevice;
24
24
  let _interactionTimeout;
@@ -39,7 +39,7 @@ const getPopupPromise = (requestWindow = true) => {
39
39
  postMessage((0, events_2.createUiMessage)(events_2.UI.REQUEST_UI_WINDOW));
40
40
  }
41
41
  if (!_popupPromise) {
42
- _popupPromise = (0, deferred_1.create)();
42
+ _popupPromise = (0, utils_1.createDeferred)();
43
43
  }
44
44
  return _popupPromise;
45
45
  };
@@ -47,14 +47,17 @@ const interactionTimeout = () => _interactionTimeout.start(() => {
47
47
  onPopupClosed('Interaction timeout');
48
48
  });
49
49
  const createUiPromise = (promiseEvent, device) => {
50
- const uiPromise = (0, deferred_1.create)(promiseEvent, device);
50
+ const uiPromise = {
51
+ ...(0, utils_1.createDeferred)(promiseEvent),
52
+ device,
53
+ };
51
54
  _uiPromises.push(uiPromise);
52
55
  interactionTimeout();
53
56
  return uiPromise;
54
57
  };
55
58
  const findUiPromise = (promiseEvent) => _uiPromises.find(p => p.id === promiseEvent);
56
59
  const removeUiPromise = (promise) => {
57
- _uiPromises = _uiPromises.filter(p => p !== promise);
60
+ _uiPromises.splice(0).push(..._uiPromises.filter(p => p !== promise));
58
61
  };
59
62
  const handleMessage = (message) => {
60
63
  _log.debug('handleMessage', message);
@@ -100,6 +103,7 @@ const initDevice = async (method) => {
100
103
  if (!_deviceList) {
101
104
  throw constants_1.ERRORS.TypedError('Transport_Missing');
102
105
  }
106
+ await _deviceList.transportFirstEventPromise;
103
107
  const isWebUsb = _deviceList.transportType() === 'WebUsbTransport';
104
108
  let device;
105
109
  let showDeviceSelection = isWebUsb;
@@ -292,7 +296,7 @@ const onCall = async (message) => {
292
296
  }
293
297
  const deviceNeedsBackup = device.features.needs_backup;
294
298
  if (deviceNeedsBackup && typeof method.noBackupConfirmation === 'function') {
295
- const permitted = await method.noBackupConfirmation();
299
+ const permitted = await method.noBackupConfirmation(!isUsingPopup);
296
300
  if (!permitted) {
297
301
  return Promise.reject(constants_1.ERRORS.TypedError('Method_PermissionsNotGranted'));
298
302
  }
@@ -336,7 +340,7 @@ const onCall = async (message) => {
336
340
  }
337
341
  }
338
342
  catch (error) {
339
- if (error.message === 'PIN invalid' && PIN_TRIES < MAX_PIN_TRIES) {
343
+ if (error.message.includes('PIN invalid') && PIN_TRIES < MAX_PIN_TRIES) {
340
344
  PIN_TRIES++;
341
345
  postMessage((0, events_2.createUiMessage)(events_2.UI.INVALID_PIN, { device: device.toMessageObject() }));
342
346
  return inner();
@@ -390,7 +394,11 @@ const onCall = async (message) => {
390
394
  if (response) {
391
395
  if (method.name === 'rebootToBootloader' && response.success) {
392
396
  await (0, promiseUtils_1.resolveAfter)(1000).promise;
393
- await device.run(() => Promise.resolve(), { skipFinalReload: true });
397
+ try {
398
+ await device.run(() => Promise.resolve(), { skipFinalReload: true });
399
+ }
400
+ catch (err) {
401
+ }
394
402
  }
395
403
  await device.cleanup();
396
404
  closePopup();
@@ -410,7 +418,7 @@ const onCall = async (message) => {
410
418
  exports.onCall = onCall;
411
419
  const cleanup = () => {
412
420
  _popupPromise = undefined;
413
- _uiPromises = [];
421
+ _uiPromises.splice(0);
414
422
  _interactionTimeout.stop();
415
423
  _log.debug('Cleanup...');
416
424
  };
@@ -498,7 +506,7 @@ const onPopupClosed = (customErrorMessage) => {
498
506
  _uiPromises.forEach(p => {
499
507
  p.reject(error);
500
508
  });
501
- _uiPromises = [];
509
+ _uiPromises.splice(0);
502
510
  }
503
511
  if (_popupPromise) {
504
512
  _popupPromise.reject(error);
@@ -530,7 +538,7 @@ const handleDeviceSelectionChanges = (interruptDevice) => {
530
538
  const { path } = interruptDevice;
531
539
  let shouldClosePopup = false;
532
540
  _uiPromises.forEach(p => {
533
- if (p.data && p.data.getDevicePath() === path) {
541
+ if (p.device && p.device.getDevicePath() === path) {
534
542
  if (p.id === events_2.DEVICE.DISCONNECT) {
535
543
  p.resolve({ type: events_2.DEVICE.DISCONNECT });
536
544
  }
@@ -625,7 +633,10 @@ class Core extends events_1.default {
625
633
  }
626
634
  }
627
635
  exports.Core = Core;
628
- const initCore = async (settings) => {
636
+ const initCore = async (settings, logWriterFactory) => {
637
+ if (logWriterFactory) {
638
+ (0, debug_1.setLogWriter)(logWriterFactory);
639
+ }
629
640
  try {
630
641
  await DataManager_1.DataManager.load(settings);
631
642
  (0, debug_1.enableLog)(DataManager_1.DataManager.getSettings('debug'));