@trezor/connect 9.6.4-beta.1 → 9.6.5-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.
Files changed (73) hide show
  1. package/CHANGELOG.md +17 -6
  2. package/README.md +1 -1
  3. package/lib/api/authenticateDevice.d.ts +5 -1
  4. package/lib/api/authenticateDevice.js +31 -12
  5. package/lib/api/firmware/getBinary.d.ts +3 -3
  6. package/lib/api/firmware/getBinary.js +2 -2
  7. package/lib/api/firmware/uploadFirmware.js +5 -0
  8. package/lib/api/monero/api/index.d.ts +5 -0
  9. package/lib/api/monero/api/index.js +13 -0
  10. package/lib/api/monero/api/moneroGetAddress.d.ts +27 -0
  11. package/lib/api/monero/api/moneroGetAddress.js +96 -0
  12. package/lib/api/monero/api/moneroGetWatchKey.d.ts +13 -0
  13. package/lib/api/monero/api/moneroGetWatchKey.js +43 -0
  14. package/lib/api/monero/api/moneroKeyImageSync.d.ts +16 -0
  15. package/lib/api/monero/api/moneroKeyImageSync.js +127 -0
  16. package/lib/api/monero/api/moneroSignTransaction.d.ts +16 -0
  17. package/lib/api/monero/api/moneroSignTransaction.js +197 -0
  18. package/lib/constants/errors.d.ts +1 -0
  19. package/lib/constants/errors.js +1 -0
  20. package/lib/constants/network.d.ts +1 -1
  21. package/lib/constants/network.js +1 -0
  22. package/lib/core/method.native.js +1 -0
  23. package/lib/core/onCallFirmwareUpdate.d.ts +1 -0
  24. package/lib/core/onCallFirmwareUpdate.js +12 -10
  25. package/lib/data/config.js +23 -0
  26. package/lib/data/connectSettings.js +1 -1
  27. package/lib/data/version.d.ts +1 -1
  28. package/lib/data/version.js +1 -1
  29. package/lib/device/Device.js +8 -1
  30. package/lib/device/DeviceCurrentSession.d.ts +78 -0
  31. package/lib/device/thp/pairing.js +1 -1
  32. package/lib/device/workflow/checkFirmwareHash.js +1 -1
  33. package/lib/events/transport.d.ts +0 -2
  34. package/lib/events/transport.js +0 -2
  35. package/lib/events/ui-request.d.ts +2 -2
  36. package/lib/factory.js +17 -0
  37. package/lib/impl/core-in-module.js +8 -2
  38. package/lib/tsconfig.lib.tsbuildinfo +1 -1
  39. package/lib/types/api/authenticateDevice.d.ts +19 -19
  40. package/lib/types/api/authenticateDevice.js +3 -4
  41. package/lib/types/api/discoverAccounts.d.ts +8 -0
  42. package/lib/types/api/discoverAccounts.js +2 -0
  43. package/lib/types/api/index.d.ts +8 -0
  44. package/lib/types/api/monero/index.d.ts +275 -0
  45. package/lib/types/api/monero/index.js +170 -0
  46. package/lib/types/api/moneroGetAddress.d.ts +5 -0
  47. package/lib/types/api/moneroGetAddress.js +3 -0
  48. package/lib/types/api/moneroGetWatchKey.d.ts +4 -0
  49. package/lib/types/api/moneroGetWatchKey.js +3 -0
  50. package/lib/types/api/moneroKeyImageSync.d.ts +4 -0
  51. package/lib/types/api/moneroKeyImageSync.js +3 -0
  52. package/lib/types/api/moneroSignTransaction.d.ts +4 -0
  53. package/lib/types/api/moneroSignTransaction.js +3 -0
  54. package/lib/types/firmware.d.ts +1 -1
  55. package/lib/types/index.d.ts +1 -0
  56. package/lib/types/index.js +1 -0
  57. package/lib/types/settings.d.ts +2 -2
  58. package/lib/utils/uiPromiseManager.js +5 -0
  59. package/package.json +15 -14
  60. package/lib/api/firmware/verifyAuthenticityProof.d.ts +0 -15
  61. package/lib/api/firmware/verifyAuthenticityProof.js +0 -133
  62. package/lib/api/firmware/x509certificate.d.ts +0 -88
  63. package/lib/api/firmware/x509certificate.js +0 -302
  64. package/lib/data/deviceAuthenticityBlacklist.d.ts +0 -3
  65. package/lib/data/deviceAuthenticityBlacklist.js +0 -11
  66. package/lib/data/deviceAuthenticityBlacklistConfig.d.ts +0 -11
  67. package/lib/data/deviceAuthenticityBlacklistConfig.js +0 -15
  68. package/lib/data/deviceAuthenticityConfig.d.ts +0 -3
  69. package/lib/data/deviceAuthenticityConfig.js +0 -47
  70. package/lib/data/deviceAuthenticityConfigTypes.d.ts +0 -39
  71. package/lib/data/deviceAuthenticityConfigTypes.js +0 -26
  72. package/lib/data/transportInfo.d.ts +0 -13
  73. package/lib/data/transportInfo.js +0 -54
package/CHANGELOG.md CHANGED
@@ -1,17 +1,28 @@
1
1
  | Package | Stable | Canary |
2
2
  | :------------------------------: | :----: | :----------: |
3
- | npm @trezor/connect | 9.6.3 | 9.6.4-beta.1 |
4
- | npm @trezor/connect-web | 9.6.3 | 9.6.4-beta.1 |
5
- | npm @trezor/connect-webextension | 9.6.3 | 9.6.4-beta.1 |
6
- | npm @trezor/connect-mobile | 9.6.3 | 9.6.4-beta.1 |
3
+ | npm @trezor/connect | 9.6.4 | 9.6.5-beta.1 |
4
+ | npm @trezor/connect-web | 9.6.4 | 9.6.5-beta.1 |
5
+ | npm @trezor/connect-webextension | 9.6.4 | 9.6.5-beta.1 |
6
+ | npm @trezor/connect-mobile | 9.6.4 | 9.6.5-beta.1 |
7
7
 
8
8
  | Deployment | Stable | Canary |
9
9
  | :----------------: | :----: | :----------: |
10
- | connect.trezor.io/ | 9.6.3 | 9.6.4-beta.1 |
10
+ | connect.trezor.io/ | 9.6.4 | 9.6.5-beta.1 |
11
11
 
12
12
  Use the persistent link [connect.trezor.io/9](https://connect.trezor.io/9/) to access the latest stable version of Connect Explorer.
13
13
 
14
- # 9.6.4-beta.1
14
+ # 9.6.5-beta.1
15
+
16
+ This release introduces Monero support in Trezor Connect and enhances Trezor Suite Web for use as a Trezor Connect popup.
17
+
18
+ feat(connect-web): in core-in-suite-desktop handle permission error (41da933)
19
+ feat(connect): monero support (7e4e42c)
20
+ feat(connect-webextension): suite web popup implementation for webextension (175e40c)
21
+ feat(connect): use existing message channels for suite web (314464a)
22
+ feat(connect-explorer): suite web popup setting (9252ce3)
23
+ feat(connect): suite web popup implementation (6bafb1e)
24
+
25
+ # 9.6.4
15
26
 
16
27
  This release primarily introduces support for the new Trezor device and enhancements to the transport API, including a new API type:
17
28
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @trezor/connect
2
2
 
3
- API version 9.6.4-beta.1
3
+ API version 9.6.5-beta.1
4
4
 
5
5
  [![Build Status](https://github.com/trezor/trezor-suite/actions/workflows/test-connect.yml/badge.svg)](https://github.com/trezor/trezor-suite/actions/workflows/test-connect.yml)
6
6
  [![NPM](https://img.shields.io/npm/v/@trezor/connect.svg)](https://www.npmjs.org/package/@trezor/connect)
@@ -1,7 +1,11 @@
1
+ import { VerifyAuthenticityProofResult } from '@trezor/device-authenticity';
1
2
  import { AbstractMethod } from '../core/AbstractMethod';
2
3
  import { AuthenticateDeviceParams } from '../types/api/authenticateDevice';
3
4
  export default class AuthenticateDevice extends AbstractMethod<'authenticateDevice', AuthenticateDeviceParams> {
4
5
  init(): void;
5
- run(): Promise<import("../types/api/authenticateDevice").AuthenticateDeviceResult>;
6
+ run(): Promise<{
7
+ optigaResult: VerifyAuthenticityProofResult;
8
+ tropicResult: VerifyAuthenticityProofResult | null;
9
+ }>;
6
10
  }
7
11
  //# sourceMappingURL=authenticateDevice.d.ts.map
@@ -1,12 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const device_authenticity_1 = require("@trezor/device-authenticity");
3
4
  const schema_utils_1 = require("@trezor/schema-utils");
4
5
  const AbstractMethod_1 = require("../core/AbstractMethod");
5
- const deviceAuthenticityBlacklist_1 = require("../data/deviceAuthenticityBlacklist");
6
6
  const events_1 = require("../events");
7
7
  const paramsValidator_1 = require("./common/paramsValidator");
8
- const deviceAuthenticityConfig_1 = require("../data/deviceAuthenticityConfig");
9
- const verifyAuthenticityProof_1 = require("./firmware/verifyAuthenticityProof");
10
8
  const authenticateDevice_1 = require("../types/api/authenticateDevice");
11
9
  class AuthenticateDevice extends AbstractMethod_1.AbstractMethod {
12
10
  init() {
@@ -25,23 +23,44 @@ class AuthenticateDevice extends AbstractMethod_1.AbstractMethod {
25
23
  };
26
24
  }
27
25
  async run() {
28
- const challenge = (0, verifyAuthenticityProof_1.getRandomChallenge)();
26
+ const challenge = (0, device_authenticity_1.getRandomChallenge)();
29
27
  const { message } = await this.device
30
28
  .getCommands()
31
29
  .typedCall('AuthenticateDevice', 'AuthenticityProof', {
32
30
  challenge: challenge.toString('hex'),
33
31
  });
34
- const config = this.params.config || deviceAuthenticityConfig_1.deviceAuthenticityConfig;
35
- const blacklistConfig = this.params.blacklistConfig || deviceAuthenticityBlacklist_1.deviceAuthenticityBlacklist;
36
- const valid = await (0, verifyAuthenticityProof_1.verifyAuthenticityProof)({
37
- ...message,
32
+ const config = this.params.config || device_authenticity_1.deviceAuthenticityConfig;
33
+ const blacklistConfig = this.params.blacklistConfig || device_authenticity_1.deviceAuthenticityBlacklistConfig;
34
+ const commonParams = {
38
35
  challenge,
36
+ deviceModel: this.device.features.internal_model,
37
+ allowDebugKeys: this.params.allowDebugKeys,
39
38
  config,
40
39
  blacklistConfig,
41
- allowDebugKeys: this.params.allowDebugKeys,
42
- deviceModel: this.device.features.internal_model,
43
- });
44
- return valid;
40
+ };
41
+ const getOptigaResult = async () => {
42
+ const { optiga_signature: signature, optiga_certificates: certificates } = message;
43
+ const isAvailable = signature !== undefined && certificates.length > 0;
44
+ if (isAvailable) {
45
+ return await (0, device_authenticity_1.verifyAuthenticityProof)({ ...commonParams, certificates, signature });
46
+ }
47
+ return { valid: false, error: 'RESPONSE_PAYLOAD_MISSING' };
48
+ };
49
+ const getTropicResult = async () => {
50
+ const { tropic_signature: signature, tropic_certificates: certificates } = message;
51
+ const isAvailable = signature !== undefined && certificates.length > 0;
52
+ const isRequired = !this.device.unavailableCapabilities['tropicDeviceAuthentication'];
53
+ if (isAvailable) {
54
+ return await (0, device_authenticity_1.verifyAuthenticityProof)({ ...commonParams, certificates, signature });
55
+ }
56
+ if (isRequired) {
57
+ return { valid: false, error: 'RESPONSE_PAYLOAD_MISSING' };
58
+ }
59
+ return null;
60
+ };
61
+ const optigaResult = await getOptigaResult();
62
+ const tropicResult = await getTropicResult();
63
+ return { optigaResult, tropicResult };
45
64
  }
46
65
  }
47
66
  exports.default = AuthenticateDevice;
@@ -1,11 +1,11 @@
1
- import { VersionArray } from '@trezor/device-utils';
1
+ import { FirmwareRelease } from '@trezor/device-utils';
2
2
  import { BinaryInfo } from '../../types';
3
3
  interface GetBinaryParams {
4
4
  baseUrl: string;
5
5
  path: string;
6
- version: VersionArray;
6
+ release: FirmwareRelease;
7
7
  }
8
- export declare const getBinary: ({ baseUrl, path, version, }: GetBinaryParams) => Promise<BinaryInfo>;
8
+ export declare const getBinary: ({ baseUrl, path, release, }: GetBinaryParams) => Promise<BinaryInfo>;
9
9
  export declare const getBinaryOptional: (params: GetBinaryParams) => Promise<BinaryInfo | null>;
10
10
  export {};
11
11
  //# sourceMappingURL=getBinary.d.ts.map
@@ -6,7 +6,7 @@ const parseFirmwareHeaders_1 = require("./parseFirmwareHeaders");
6
6
  const constants_1 = require("../../constants");
7
7
  const assets_1 = require("../../utils/assets");
8
8
  const MIN_FIRMWARE_SIZE_BYTES = 200;
9
- const getBinary = async ({ baseUrl, path, version, }) => {
9
+ const getBinary = async ({ baseUrl, path, release, }) => {
10
10
  const sanitizedBaseUrl = (0, utils_1.removeTrailingSlashes)(baseUrl);
11
11
  const url = `${sanitizedBaseUrl}/${path}`;
12
12
  const binaryArrayBuffer = (await (0, assets_1.httpRequest)(url, 'binary'));
@@ -18,7 +18,7 @@ const getBinary = async ({ baseUrl, path, version, }) => {
18
18
  return {
19
19
  binary: binaryArrayBuffer,
20
20
  binaryVersion,
21
- releaseVersion: version,
21
+ release,
22
22
  };
23
23
  };
24
24
  exports.getBinary = getBinary;
@@ -45,6 +45,11 @@ const uploadFirmware = async ({ typedCall, postMessage, device, firmwareUploadRe
45
45
  const length = payload.byteLength;
46
46
  let progress = 0;
47
47
  let response = await typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], { length });
48
+ postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
49
+ device: device.toMessageObject(),
50
+ operation: 'start-flashing',
51
+ progress,
52
+ }));
48
53
  while (response.type !== 'Success') {
49
54
  const start = response.message.offset;
50
55
  const end = response.message.offset + response.message.length;
@@ -0,0 +1,5 @@
1
+ export { default as moneroGetAddress } from './moneroGetAddress';
2
+ export { default as moneroGetWatchKey } from './moneroGetWatchKey';
3
+ export { default as moneroKeyImageSync } from './moneroKeyImageSync';
4
+ export { default as moneroSignTransaction } from './moneroSignTransaction';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.moneroSignTransaction = exports.moneroKeyImageSync = exports.moneroGetWatchKey = exports.moneroGetAddress = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var moneroGetAddress_1 = require("./moneroGetAddress");
6
+ Object.defineProperty(exports, "moneroGetAddress", { enumerable: true, get: function () { return tslib_1.__importDefault(moneroGetAddress_1).default; } });
7
+ var moneroGetWatchKey_1 = require("./moneroGetWatchKey");
8
+ Object.defineProperty(exports, "moneroGetWatchKey", { enumerable: true, get: function () { return tslib_1.__importDefault(moneroGetWatchKey_1).default; } });
9
+ var moneroKeyImageSync_1 = require("./moneroKeyImageSync");
10
+ Object.defineProperty(exports, "moneroKeyImageSync", { enumerable: true, get: function () { return tslib_1.__importDefault(moneroKeyImageSync_1).default; } });
11
+ var moneroSignTransaction_1 = require("./moneroSignTransaction");
12
+ Object.defineProperty(exports, "moneroSignTransaction", { enumerable: true, get: function () { return tslib_1.__importDefault(moneroSignTransaction_1).default; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,27 @@
1
+ import { PROTO } from '../../../constants';
2
+ import { AbstractMethod } from '../../../core/AbstractMethod';
3
+ import { Address } from '../../../types/params';
4
+ type Params = PROTO.MoneroGetAddress & {
5
+ address?: string;
6
+ };
7
+ export default class MoneroGetAddress extends AbstractMethod<'moneroGetAddress', Params[]> {
8
+ hasBundle?: boolean;
9
+ progress: number;
10
+ init(): void;
11
+ get info(): string;
12
+ getButtonRequestData(code: string): {
13
+ type: "address";
14
+ serializedPath: string;
15
+ address: string;
16
+ } | undefined;
17
+ get confirmation(): {
18
+ view: "export-address";
19
+ label: string;
20
+ };
21
+ _call({ address_n, show_display, network_type, account, minor, payment_id, chunkify, }: Params): Promise<{
22
+ address: string;
23
+ }>;
24
+ run(): Promise<Address | Address[]>;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=moneroGetAddress.d.ts.map
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("../../../constants");
4
+ const AbstractMethod_1 = require("../../../core/AbstractMethod");
5
+ const coinInfo_1 = require("../../../data/coinInfo");
6
+ const pathUtils_1 = require("../../../utils/pathUtils");
7
+ const paramsValidator_1 = require("../../common/paramsValidator");
8
+ class MoneroGetAddress extends AbstractMethod_1.AbstractMethod {
9
+ hasBundle;
10
+ progress = 0;
11
+ init() {
12
+ this.noBackupConfirmationMode = 'always';
13
+ this.requiredPermissions = ['read'];
14
+ this.requiredDeviceCapabilities = ['Capability_Monero'];
15
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, (0, coinInfo_1.getMiscNetwork)('Monero'), this.firmwareRange);
16
+ this.hasBundle = !!this.payload.bundle;
17
+ const payload = !this.payload.bundle
18
+ ? { ...this.payload, bundle: [this.payload] }
19
+ : this.payload;
20
+ const bundle = payload.bundle.map(batch => {
21
+ const path = (0, pathUtils_1.validatePath)(batch.path, 3);
22
+ const allHardened = path.every(component => (component & pathUtils_1.HD_HARDENED) !== 0);
23
+ if (!allHardened) {
24
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Monero requires all path components to be hardened. Use m/44'/128'/0' format.`);
25
+ }
26
+ return {
27
+ address_n: path,
28
+ address: batch.address,
29
+ show_display: typeof batch.showOnTrezor === 'boolean' ? batch.showOnTrezor : true,
30
+ network_type: batch.networkType || constants_1.PROTO.MoneroNetworkType.MAINNET,
31
+ account: batch.account,
32
+ minor: batch.minor,
33
+ payment_id: batch.paymentId,
34
+ chunkify: typeof batch.chunkify === 'boolean' ? batch.chunkify : false,
35
+ };
36
+ });
37
+ this.params = bundle;
38
+ const useEventListener = payload.useEventListener &&
39
+ this.params.length === 1 &&
40
+ typeof this.params[0].address === 'string' &&
41
+ this.params[0].show_display;
42
+ this.useUi = !useEventListener;
43
+ }
44
+ get info() {
45
+ return 'Export Monero address';
46
+ }
47
+ getButtonRequestData(code) {
48
+ if (code === 'ButtonRequest_Address') {
49
+ const { address_n, address } = this.params[this.progress];
50
+ return {
51
+ type: 'address',
52
+ serializedPath: (0, pathUtils_1.getSerializedPath)(address_n),
53
+ address: address || 'not-set',
54
+ };
55
+ }
56
+ }
57
+ get confirmation() {
58
+ return {
59
+ view: 'export-address',
60
+ label: this.info,
61
+ };
62
+ }
63
+ async _call({ address_n, show_display, network_type, account, minor, payment_id, chunkify, }) {
64
+ const cmd = this.device.getCommands();
65
+ const response = await cmd.typedCall('MoneroGetAddress', 'MoneroAddress', {
66
+ address_n,
67
+ show_display,
68
+ network_type,
69
+ account,
70
+ minor,
71
+ payment_id,
72
+ chunkify,
73
+ });
74
+ const addressHex = response.message.address;
75
+ const addressBytes = Buffer.from(addressHex, 'hex');
76
+ const address = addressBytes.toString('utf8');
77
+ return {
78
+ address,
79
+ };
80
+ }
81
+ async run() {
82
+ const responses = [];
83
+ for (let i = 0; i < this.params.length; i++) {
84
+ const response = await this._call(this.params[i]);
85
+ responses.push({
86
+ address: response.address,
87
+ path: this.params[i].address_n,
88
+ serializedPath: (0, pathUtils_1.getSerializedPath)(this.params[i].address_n),
89
+ });
90
+ this.progress++;
91
+ }
92
+ return this.hasBundle ? responses : responses[0];
93
+ }
94
+ }
95
+ exports.default = MoneroGetAddress;
96
+ //# sourceMappingURL=moneroGetAddress.js.map
@@ -0,0 +1,13 @@
1
+ import { PROTO } from '../../../constants';
2
+ import { AbstractMethod } from '../../../core/AbstractMethod';
3
+ import type { MoneroWatchKey } from '../../../types/api/monero';
4
+ type Params = PROTO.MoneroGetWatchKey & {
5
+ address?: string;
6
+ };
7
+ export default class MoneroGetWatchKeyMethod extends AbstractMethod<'moneroGetWatchKey', Params> {
8
+ init(): void;
9
+ get info(): string;
10
+ run(): Promise<MoneroWatchKey>;
11
+ }
12
+ export {};
13
+ //# sourceMappingURL=moneroGetWatchKey.d.ts.map
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("../../../constants");
4
+ const AbstractMethod_1 = require("../../../core/AbstractMethod");
5
+ const coinInfo_1 = require("../../../data/coinInfo");
6
+ const pathUtils_1 = require("../../../utils/pathUtils");
7
+ const paramsValidator_1 = require("../../common/paramsValidator");
8
+ class MoneroGetWatchKeyMethod extends AbstractMethod_1.AbstractMethod {
9
+ init() {
10
+ this.requiredPermissions = ['read'];
11
+ this.requiredDeviceCapabilities = ['Capability_Monero'];
12
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, (0, coinInfo_1.getMiscNetwork)('Monero'), this.firmwareRange);
13
+ const { payload } = this;
14
+ const path = (0, pathUtils_1.validatePath)(payload.path, 3);
15
+ const allHardened = path.every(component => (component & pathUtils_1.HD_HARDENED) !== 0);
16
+ if (!allHardened) {
17
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Monero requires all path components to be hardened. Use m/44'/128'/0' format.`);
18
+ }
19
+ this.params = {
20
+ address_n: path,
21
+ network_type: payload.networkType || constants_1.PROTO.MoneroNetworkType.MAINNET,
22
+ };
23
+ }
24
+ get info() {
25
+ return 'Export Monero watch-only credentials';
26
+ }
27
+ async run() {
28
+ const cmd = this.device.getCommands();
29
+ const response = await cmd.typedCall('MoneroGetWatchKey', 'MoneroWatchKey', {
30
+ address_n: this.params.address_n,
31
+ network_type: this.params.network_type,
32
+ });
33
+ const addressHex = response.message.address;
34
+ const addressBytes = Buffer.from(addressHex, 'hex');
35
+ const address = addressBytes.toString('utf8');
36
+ return {
37
+ watch_key: response.message.watch_key,
38
+ address,
39
+ };
40
+ }
41
+ }
42
+ exports.default = MoneroGetWatchKeyMethod;
43
+ //# sourceMappingURL=moneroGetWatchKey.js.map
@@ -0,0 +1,16 @@
1
+ import { PROTO } from '../../../constants';
2
+ import { AbstractMethod } from '../../../core/AbstractMethod';
3
+ import type { MoneroKeyImageSyncResult } from '../../../types/api/monero';
4
+ type Params = {
5
+ address_n: number[];
6
+ network_type: PROTO.MoneroNetworkType;
7
+ subs: PROTO.MoneroSubAddressIndicesList[];
8
+ tdis: PROTO.MoneroTransferDetails[];
9
+ };
10
+ export default class MoneroKeyImageSyncMethod extends AbstractMethod<'moneroKeyImageSync', Params> {
11
+ init(): void;
12
+ get info(): string;
13
+ run(): Promise<MoneroKeyImageSyncResult>;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=moneroKeyImageSync.d.ts.map
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const sha3_1 = require("@noble/hashes/sha3");
4
+ const utils_1 = require("@noble/hashes/utils");
5
+ const constants_1 = require("../../../constants");
6
+ const AbstractMethod_1 = require("../../../core/AbstractMethod");
7
+ const coinInfo_1 = require("../../../data/coinInfo");
8
+ const pathUtils_1 = require("../../../utils/pathUtils");
9
+ const paramsValidator_1 = require("../../common/paramsValidator");
10
+ function encodeVarint(n) {
11
+ const bytes = [];
12
+ while (n >= 0x80) {
13
+ bytes.push((n & 0x7f) | 0x80);
14
+ n >>= 7;
15
+ }
16
+ bytes.push(n & 0x7f);
17
+ return new Uint8Array(bytes);
18
+ }
19
+ class MoneroKeyImageSyncMethod extends AbstractMethod_1.AbstractMethod {
20
+ init() {
21
+ this.requiredPermissions = ['read'];
22
+ this.requiredDeviceCapabilities = ['Capability_Monero'];
23
+ this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, (0, coinInfo_1.getMiscNetwork)('Monero'), this.firmwareRange);
24
+ const { payload } = this;
25
+ const path = (0, pathUtils_1.validatePath)(payload.path, 3);
26
+ const allHardened = path.every(component => (component & pathUtils_1.HD_HARDENED) !== 0);
27
+ if (!allHardened) {
28
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Monero requires all path components to be hardened. Use m/44'/128'/0' format.`);
29
+ }
30
+ if (!payload.tdis || payload.tdis.length === 0) {
31
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', 'tdis (transfer details) array is required and cannot be empty');
32
+ }
33
+ const tdis = payload.tdis.map((tdi, index) => {
34
+ if (tdi.out_key.length !== 64) {
35
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Invalid out_key length at index ${index}: expected 64 hex characters, got ${tdi.out_key.length}`);
36
+ }
37
+ if (tdi.tx_pub_key.length !== 64) {
38
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Invalid tx_pub_key length at index ${index}: expected 64 hex characters, got ${tdi.tx_pub_key.length}`);
39
+ }
40
+ let additionalKeys = [];
41
+ const addlKeys = tdi.additional_tx_pub_keys;
42
+ if (addlKeys) {
43
+ if (Array.isArray(addlKeys)) {
44
+ additionalKeys = addlKeys;
45
+ }
46
+ else if (typeof addlKeys === 'string') {
47
+ const trimmed = addlKeys.trim();
48
+ if (trimmed) {
49
+ additionalKeys = trimmed.split(',').map((k) => k.trim());
50
+ }
51
+ }
52
+ }
53
+ additionalKeys.forEach((key, keyIndex) => {
54
+ if (key && key.length !== 64) {
55
+ throw constants_1.ERRORS.TypedError('Method_InvalidParameter', `Invalid additional_tx_pub_keys[${keyIndex}] length at tdi index ${index}: expected 64 hex characters, got ${key.length}`);
56
+ }
57
+ });
58
+ return {
59
+ out_key: (0, utils_1.hexToBytes)(tdi.out_key),
60
+ tx_pub_key: (0, utils_1.hexToBytes)(tdi.tx_pub_key),
61
+ additional_tx_pub_keys: additionalKeys.map(k => (0, utils_1.hexToBytes)(k)),
62
+ internal_output_index: tdi.internal_output_index,
63
+ sub_addr_major: tdi.sub_addr_major,
64
+ sub_addr_minor: tdi.sub_addr_minor,
65
+ };
66
+ });
67
+ this.params = {
68
+ address_n: path,
69
+ network_type: payload.networkType || constants_1.PROTO.MoneroNetworkType.MAINNET,
70
+ subs: payload.subs || [],
71
+ tdis,
72
+ };
73
+ }
74
+ get info() {
75
+ return 'Export Monero key images for spent output tracking';
76
+ }
77
+ async run() {
78
+ const cmd = this.device.getCommands();
79
+ const tdHashes = [];
80
+ for (const tdi of this.params.tdis) {
81
+ const kck = sha3_1.keccak_256.create();
82
+ kck.update(tdi.out_key);
83
+ kck.update(tdi.tx_pub_key);
84
+ if (tdi.additional_tx_pub_keys && tdi.additional_tx_pub_keys.length > 0) {
85
+ for (const addKey of tdi.additional_tx_pub_keys) {
86
+ kck.update(addKey);
87
+ }
88
+ }
89
+ const indexVarint = encodeVarint(tdi.internal_output_index);
90
+ kck.update(indexVarint);
91
+ tdHashes.push(kck.digest());
92
+ }
93
+ const finalKck = sha3_1.keccak_256.create();
94
+ for (const hash of tdHashes) {
95
+ finalKck.update(hash);
96
+ }
97
+ const hashBytes = finalKck.digest();
98
+ const numOutputs = this.params.tdis.length;
99
+ await cmd.typedCall('MoneroKeyImageExportInitRequest', 'MoneroKeyImageExportInitAck', {
100
+ num: numOutputs,
101
+ hash: hashBytes,
102
+ address_n: this.params.address_n,
103
+ network_type: this.params.network_type,
104
+ subs: this.params.subs,
105
+ });
106
+ const allKeyImages = [];
107
+ const stepResponse = await cmd.typedCall('MoneroKeyImageSyncStepRequest', 'MoneroKeyImageSyncStepAck', {
108
+ tdis: this.params.tdis,
109
+ });
110
+ allKeyImages.push(...stepResponse.message.kis);
111
+ const finalResponse = await cmd.typedCall('MoneroKeyImageSyncFinalRequest', 'MoneroKeyImageSyncFinalAck', {});
112
+ const encKey = finalResponse.message.enc_key;
113
+ if (!encKey) {
114
+ throw constants_1.ERRORS.TypedError('Runtime', 'Device did not return encryption key for key images');
115
+ }
116
+ const keyImages = allKeyImages.map(ki => ({
117
+ iv: ki.iv || '',
118
+ key_image: ki.blob || '',
119
+ }));
120
+ return {
121
+ key_images: keyImages,
122
+ signature: encKey,
123
+ };
124
+ }
125
+ }
126
+ exports.default = MoneroKeyImageSyncMethod;
127
+ //# sourceMappingURL=moneroKeyImageSync.js.map
@@ -0,0 +1,16 @@
1
+ import { PROTO } from '../../../constants';
2
+ import { AbstractMethod, MethodReturnType } from '../../../core/AbstractMethod';
3
+ type Params = {
4
+ address_n: number[];
5
+ network_type: PROTO.MoneroNetworkType;
6
+ tsx_data: PROTO.MoneroTransactionData;
7
+ inputs: PROTO.MoneroTransactionSourceEntry[];
8
+ };
9
+ export default class MoneroSignTransactionMethod extends AbstractMethod<'moneroSignTransaction', Params> {
10
+ private state;
11
+ init(): void;
12
+ get info(): string;
13
+ run(): Promise<MethodReturnType<typeof this.name>>;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=moneroSignTransaction.d.ts.map