From e9a042518338e1b23fbf1542d4f08ea64dd930cd Mon Sep 17 00:00:00 2001 From: Peter Sanderson Date: Mon, 13 May 2024 12:00:10 +0200 Subject: [PATCH] feat(suite): Add adding a new shamir group into an existing setup --- docs/analytics/sentry.md | 4 +- .../components/src/components/Flex/Flex.tsx | 3 + .../components/src/components/Image/images.ts | 4 + .../src/components/assets/Icon/icons.ts | 12 +- .../components/src/images/icons/backup_2.svg | 3 + .../src/images/icons/camera_slash.svg | 3 + .../components/src/images/icons/eye_slash.svg | 3 + .../components/src/images/icons/timer.svg | 3 + .../connect/e2e/__fixtures__/getFeatures.ts | 503 +-- packages/connect/setupJest.ts | 4 +- packages/connect/src/api/recoveryDevice.ts | 3 +- packages/connect/src/core/index.ts | 2 +- .../src/types/api/__tests__/management.ts | 6 +- packages/protobuf/.eslintrc.js | 1 + packages/protobuf/messages.json | 83 +- .../scripts/protobuf-patches/index.js | 9 +- packages/protobuf/scripts/protobuf-types.js | 40 +- packages/protobuf/src/messages-schema.ts | 106 +- packages/protobuf/src/messages.ts | 77 +- .../tests/__snapshots__/codegen.input.ts | 2618 ---------------- .../tests/__snapshots__/codegen.test.ts.snap | 2754 ----------------- packages/schema-utils/tests/codegen.test.ts | 8 - .../files/images/png/create-shamir-group.png | Bin 0 -> 16481 bytes .../images/png/create-shamir-group@2x.png | Bin 0 -> 45142 bytes .../files/images/png/shamir-shares.png | Bin 0 -> 5731 bytes .../files/images/png/shamir-shares@2x.png | Bin 0 -> 12774 bytes .../suite-data/files/translations/en.json | 1 + .../src/actions/recovery/recoveryActions.ts | 16 +- .../src/components/firmware/CheckSeedStep.tsx | 4 +- .../src/components/suite/LearnMoreButton.tsx | 5 +- .../Preloader/__tests__/Preloader.test.tsx | 100 +- .../MultiShareBackupInProgress.tsx | 16 + .../PrerequisitesGuide/PrerequisitesGuide.tsx | 9 +- .../banners/SuiteBanners/SuiteBanners.tsx | 2 +- .../ModalSwitcher/ForegroundAppModal.tsx | 38 +- .../BackupInstructionsCard.tsx | 46 + .../BackupInstructionsStep.tsx | 118 + .../MultiShareBackupModal.tsx | 152 + .../MultiShareBackupStep1FirstInfo.tsx | 76 + .../MultiShareBackupStep2SecondInfo.tsx | 22 + .../MultiShareBackupStep3VerifyOwnership.tsx | 27 + .../MultiShareBackupStep4BackupSeed.tsx | 27 + .../MultiShareBackupStep5Done.tsx | 135 + .../instructionSteps.tsx | 87 + .../multiShareModalLayout.tsx | 15 + .../src/components/suite/modals/index.tsx | 1 + .../src/hooks/suite/usePreferredModal.ts | 34 +- .../recovery/recoveryMiddleware.ts | 6 +- packages/suite/src/support/messages.ts | 189 +- .../src/utils/device/isRecoveryInProgress.ts | 27 + .../suite/src/utils/suite/prerequisites.ts | 13 +- packages/suite/src/views/backup/index.tsx | 6 +- .../components/SecurityFeatures/index.tsx | 3 +- .../settings/SettingsDevice/BackupFailed.tsx | 4 +- .../SettingsDevice/BackupRecoverySeed.tsx | 2 +- .../SettingsDevice/CheckRecoverySeed.tsx | 2 +- .../SettingsDevice/MultiShareBackup.tsx | 61 + .../SettingsDevice/SettingsDevice.tsx | 6 +- .../src/views/view-only/ViewOnlyTooltip.tsx | 2 +- packages/urls/src/urls.ts | 10 +- suite-common/suite-config/src/routes.ts | 7 + suite-common/test-utils/src/mocks.ts | 4 +- .../wallet-core/src/device/deviceConstants.ts | 4 +- 63 files changed, 1708 insertions(+), 5818 deletions(-) create mode 100644 packages/components/src/images/icons/backup_2.svg create mode 100644 packages/components/src/images/icons/camera_slash.svg create mode 100644 packages/components/src/images/icons/eye_slash.svg create mode 100644 packages/components/src/images/icons/timer.svg delete mode 100644 packages/schema-utils/tests/__snapshots__/codegen.input.ts delete mode 100644 packages/schema-utils/tests/__snapshots__/codegen.test.ts.snap delete mode 100644 packages/schema-utils/tests/codegen.test.ts create mode 100644 packages/suite-data/files/images/png/create-shamir-group.png create mode 100644 packages/suite-data/files/images/png/create-shamir-group@2x.png create mode 100644 packages/suite-data/files/images/png/shamir-shares.png create mode 100644 packages/suite-data/files/images/png/shamir-shares@2x.png create mode 100644 packages/suite/src/components/suite/PrerequisitesGuide/MultiShareBackupInProgress.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/BackupInstructionsCard.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/BackupInstructionsStep.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep1FirstInfo.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep2SecondInfo.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep3VerifyOwnership.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep4BackupSeed.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep5Done.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx create mode 100644 packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/multiShareModalLayout.tsx create mode 100644 packages/suite/src/utils/device/isRecoveryInProgress.ts create mode 100644 packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx diff --git a/docs/analytics/sentry.md b/docs/analytics/sentry.md index 75f828b291..665b02286a 100644 --- a/docs/analytics/sentry.md +++ b/docs/analytics/sentry.md @@ -88,13 +88,13 @@ Browser (User Agent), System and HW specifications, Suite version, instance id s major_version: 2, minor_version: 4, model: T, - needs_backup: False, + backup_availability: 0, no_backup: False, passphrase_always_on_device: False, passphrase_protection: True, patch_version: 2, pin_protection: True, - recovery_mode: False, + recovery_status: 0, revision: 9276b1702361f70e094286e2f89e919d8a230d5c, safety_checks: Strict, sd_card_present: False, diff --git a/packages/components/src/components/Flex/Flex.tsx b/packages/components/src/components/Flex/Flex.tsx index b758b2a034..7363afc899 100644 --- a/packages/components/src/components/Flex/Flex.tsx +++ b/packages/components/src/components/Flex/Flex.tsx @@ -71,6 +71,7 @@ export type FlexProps = FrameProps & { flex?: Flex; flexWrap?: FlexWrap; isReversed?: boolean; + className?: string; }; const Flex = ({ @@ -83,6 +84,7 @@ const Flex = ({ flex = 'auto', flexWrap = 'nowrap', isReversed = false, + className, }: FlexProps) => { const frameProps = { margin, @@ -90,6 +92,7 @@ const Flex = ({ return ( + + diff --git a/packages/components/src/images/icons/camera_slash.svg b/packages/components/src/images/icons/camera_slash.svg new file mode 100644 index 0000000000..6afc28341e --- /dev/null +++ b/packages/components/src/images/icons/camera_slash.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/components/src/images/icons/eye_slash.svg b/packages/components/src/images/icons/eye_slash.svg new file mode 100644 index 0000000000..08802b125f --- /dev/null +++ b/packages/components/src/images/icons/eye_slash.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/components/src/images/icons/timer.svg b/packages/components/src/images/icons/timer.svg new file mode 100644 index 0000000000..ef9ff748ad --- /dev/null +++ b/packages/components/src/images/icons/timer.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/connect/e2e/__fixtures__/getFeatures.ts b/packages/connect/e2e/__fixtures__/getFeatures.ts index 4c27b26f47..cec46ce15b 100644 --- a/packages/connect/e2e/__fixtures__/getFeatures.ts +++ b/packages/connect/e2e/__fixtures__/getFeatures.ts @@ -22,253 +22,268 @@ const customFirmwareBuild = // integration tests in trezor-firmware repo use 2.99.99 version process.env.TESTS_FIRMWARE === '2.99.99'; +const tests = [ + { + description: 'T2T1/T2B1 features', + skip: ['1'], + params: {}, + result: { + device_id: expect.any(String), + vendor: 'trezor.io', + major_version: expect.any(Number), + minor_version: expect.any(Number), + patch_version: expect.any(Number), + bootloader_mode: null, + pin_protection: expect.any(Boolean), + passphrase_protection: expect.any(Boolean), + language: 'en-US', + label: expect.any(String), + initialized: true, + revision: expect.any(String), + bootloader_hash: null, + imported: null, + unlocked: expect.any(Boolean), + firmware_present: null, + backup_availability: expect.any(String), + // flags: expect.any(Number), // flags may be changed by applyFlags test + model: expect.any(String), // "T" | "R" + internal_model: expect.any(String), + fw_major: null, + fw_minor: null, + fw_patch: null, + // fw_vendor: null, // "EMULATOR" since 2.5.1 + unfinished_backup: expect.any(Boolean), + no_backup: expect.any(Boolean), + recovery_status: 'Nothing', + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Binance', + 'Capability_Cardano', + 'Capability_Crypto', + 'Capability_Ethereum', + 'Capability_Monero', + 'Capability_Ripple', + 'Capability_Stellar', + 'Capability_Tezos', + 'Capability_U2F', + 'Capability_Shamir', + 'Capability_ShamirGroups', + 'Capability_PassphraseEntry', + 'Capability_NEM', + 'Capability_EOS', + ]), + backup_type: 'Bip39', + sd_card_present: expect.any(Boolean), // T2T1 true, T2B1 false + sd_protection: false, + wipe_code_protection: false, + session_id: expect.any(String), + passphrase_always_on_device: false, + flags: expect.any(Number), + fw_vendor: expect.any(String), + safety_checks: expect.any(String), + auto_lock_delay_ms: expect.any(Number), + display_rotation: expect.any(Number), + experimental_features: expect.any(Boolean), + }, + legacyResults: [ + { + rules: ['<2.4.2'], // 2.4.2 removed Lisk capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Binance', + 'Capability_Cardano', + 'Capability_Crypto', + 'Capability_EOS', + 'Capability_Ethereum', + 'Capability_Lisk', + 'Capability_Monero', + 'Capability_NEM', + 'Capability_Ripple', + 'Capability_Stellar', + 'Capability_Tezos', + 'Capability_U2F', + 'Capability_Shamir', + 'Capability_ShamirGroups', + 'Capability_PassphraseEntry', + ]), + session_id: expect.any(String), + passphrase_always_on_device: false, + }, + }, + { + rules: ['<2.2.1'], // 2.2.1 added PassphraseEntry capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Binance', + 'Capability_Cardano', + 'Capability_Crypto', + 'Capability_EOS', + 'Capability_Ethereum', + 'Capability_Lisk', + 'Capability_Monero', + 'Capability_NEM', + 'Capability_Ripple', + 'Capability_Stellar', + 'Capability_Tezos', + 'Capability_U2F', + 'Capability_Shamir', + 'Capability_ShamirGroups', + ]), + backup_type: 'Bip39', + session_id: null, + passphrase_always_on_device: null, + }, + }, + { + rules: ['<2.1.6'], // 2.1.6 added ShamirGroups capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Binance', + 'Capability_Cardano', + 'Capability_Crypto', + 'Capability_EOS', + 'Capability_Ethereum', + 'Capability_Lisk', + 'Capability_Monero', + 'Capability_NEM', + 'Capability_Ripple', + 'Capability_Stellar', + 'Capability_Tezos', + 'Capability_U2F', + 'Capability_Shamir', + ]), + backup_type: undefined, + }, + }, + { + rules: ['<2.1.5'], // 2.1.5 added Shamir and Lisk capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Binance', + 'Capability_Cardano', + 'Capability_Crypto', + 'Capability_EOS', + 'Capability_Ethereum', + 'Capability_Monero', + 'Capability_NEM', + 'Capability_Ripple', + 'Capability_Stellar', + 'Capability_Tezos', + 'Capability_U2F', + ]), + backup_type: undefined, + }, + }, + ], + }, + { + description: 'T1B1 features', + skip: ['2'], + params: {}, + result: { + device_id: expect.any(String), + vendor: 'trezor.io', + major_version: customFirmwareBuild ? expect.any(Number) : Number(major), + minor_version: customFirmwareBuild ? expect.any(Number) : Number(minor), + patch_version: customFirmwareBuild ? expect.any(Number) : Number(patch), + bootloader_mode: null, + pin_protection: expect.any(Boolean), + passphrase_protection: expect.any(Boolean), + language: 'en-US', + label: expect.any(String), + initialized: true, + revision: expect.any(String), + bootloader_hash: expect.any(String), // difference between T2T1 + imported: true, // difference between T2T1 + unlocked: expect.any(Boolean), + firmware_present: null, + backup_availability: expect.any(String), + // flags: null, // flags may be changed by applyFlags test + model: '1', + internal_model: DeviceModelInternal.T1B1, + fw_major: null, + fw_minor: null, + fw_patch: null, + // fw_vendor: null, // "EMULATOR" since 1.11.1 + unfinished_backup: expect.any(Boolean), + no_backup: expect.any(Boolean), + recovery_status: 'Nothing', // difference between T2T1 + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Crypto', + 'Capability_Ethereum', + 'Capability_NEM', + 'Capability_Stellar', + 'Capability_U2F', + ]), + recovery_type: undefined, // difference between T2T1 + sd_card_present: null, // no sdcard in T1B1 + sd_protection: null, // no sdcard in T1B1 + wipe_code_protection: false, + session_id: expect.any(String), + passphrase_always_on_device: null, + flags: expect.any(Number), + fw_vendor: expect.any(String), + safety_checks: expect.any(String), + auto_lock_delay_ms: expect.any(Number), + display_rotation: expect.any(Number), + experimental_features: expect.any(Boolean), + backup_type: 'Bip39', + }, + legacyResults: [ + { + rules: ['<1.10.3'], // 1.10.3 removed Lisk capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Crypto', + 'Capability_Ethereum', + 'Capability_Lisk', + 'Capability_NEM', + 'Capability_Stellar', + 'Capability_U2F', + ]), + }, + }, + { + rules: ['<1.8.3'], // 1.8.3 added Lisk capability + success: true, + payload: { + capabilities: expect.arrayContaining([ + 'Capability_Bitcoin', + 'Capability_Bitcoin_like', + 'Capability_Crypto', + 'Capability_Ethereum', + 'Capability_NEM', + 'Capability_Stellar', + 'Capability_U2F', + ]), + }, + }, + ], + }, +]; + export default { method: 'getFeatures', setup: { mnemonic: 'mnemonic_12', }, - tests: [ - { - description: 'T2T1/T2B1 features', - skip: ['1'], - params: {}, - result: { - device_id: expect.any(String), - vendor: 'trezor.io', - major_version: expect.any(Number), - minor_version: expect.any(Number), - patch_version: expect.any(Number), - bootloader_mode: null, - pin_protection: expect.any(Boolean), - passphrase_protection: expect.any(Boolean), - language: 'en-US', - label: expect.any(String), - initialized: true, - revision: expect.any(String), - bootloader_hash: null, - imported: null, - unlocked: expect.any(Boolean), - firmware_present: null, - needs_backup: expect.any(Boolean), - // flags: expect.any(Number), // flags may be changed by applyFlags test - model: expect.any(String), // "T" | "R" - internal_model: expect.any(String), - fw_major: null, - fw_minor: null, - fw_patch: null, - // fw_vendor: null, // "EMULATOR" since 2.5.1 - unfinished_backup: expect.any(Boolean), - no_backup: expect.any(Boolean), - recovery_mode: false, - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Binance', - 'Capability_Cardano', - 'Capability_Crypto', - 'Capability_Ethereum', - 'Capability_Monero', - 'Capability_Ripple', - 'Capability_Stellar', - 'Capability_Tezos', - 'Capability_U2F', - 'Capability_Shamir', - 'Capability_ShamirGroups', - 'Capability_PassphraseEntry', - 'Capability_NEM', - 'Capability_EOS', - ]), - backup_type: 'Bip39', - sd_card_present: expect.any(Boolean), // T2T1 true, T2B1 false - sd_protection: false, - wipe_code_protection: false, - session_id: expect.any(String), - passphrase_always_on_device: false, - }, - legacyResults: [ - { - rules: ['<2.4.2'], // 2.4.2 removed Lisk capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Binance', - 'Capability_Cardano', - 'Capability_Crypto', - 'Capability_EOS', - 'Capability_Ethereum', - 'Capability_Lisk', - 'Capability_Monero', - 'Capability_NEM', - 'Capability_Ripple', - 'Capability_Stellar', - 'Capability_Tezos', - 'Capability_U2F', - 'Capability_Shamir', - 'Capability_ShamirGroups', - 'Capability_PassphraseEntry', - ]), - session_id: expect.any(String), - passphrase_always_on_device: false, - }, - }, - { - rules: ['<2.2.1'], // 2.2.1 added PassphraseEntry capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Binance', - 'Capability_Cardano', - 'Capability_Crypto', - 'Capability_EOS', - 'Capability_Ethereum', - 'Capability_Lisk', - 'Capability_Monero', - 'Capability_NEM', - 'Capability_Ripple', - 'Capability_Stellar', - 'Capability_Tezos', - 'Capability_U2F', - 'Capability_Shamir', - 'Capability_ShamirGroups', - ]), - backup_type: 'Bip39', - session_id: null, - passphrase_always_on_device: null, - }, - }, - { - rules: ['<2.1.6'], // 2.1.6 added ShamirGroups capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Binance', - 'Capability_Cardano', - 'Capability_Crypto', - 'Capability_EOS', - 'Capability_Ethereum', - 'Capability_Lisk', - 'Capability_Monero', - 'Capability_NEM', - 'Capability_Ripple', - 'Capability_Stellar', - 'Capability_Tezos', - 'Capability_U2F', - 'Capability_Shamir', - ]), - backup_type: undefined, - }, - }, - { - rules: ['<2.1.5'], // 2.1.5 added Shamir and Lisk capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Binance', - 'Capability_Cardano', - 'Capability_Crypto', - 'Capability_EOS', - 'Capability_Ethereum', - 'Capability_Monero', - 'Capability_NEM', - 'Capability_Ripple', - 'Capability_Stellar', - 'Capability_Tezos', - 'Capability_U2F', - ]), - backup_type: undefined, - }, - }, - ], - }, - { - description: 'T1B1 features', - skip: ['2'], - params: {}, - result: { - device_id: expect.any(String), - vendor: 'trezor.io', - major_version: customFirmwareBuild ? expect.any(Number) : Number(major), - minor_version: customFirmwareBuild ? expect.any(Number) : Number(minor), - patch_version: customFirmwareBuild ? expect.any(Number) : Number(patch), - bootloader_mode: null, - pin_protection: expect.any(Boolean), - passphrase_protection: expect.any(Boolean), - language: 'en-US', - label: expect.any(String), - initialized: true, - revision: expect.any(String), - bootloader_hash: expect.any(String), // difference between T2T1 - imported: true, // difference between T2T1 - unlocked: expect.any(Boolean), - firmware_present: null, - needs_backup: expect.any(Boolean), - // flags: null, // flags may be changed by applyFlags test - model: '1', - internal_model: DeviceModelInternal.T1B1, - fw_major: null, - fw_minor: null, - fw_patch: null, - // fw_vendor: null, // "EMULATOR" since 1.11.1 - unfinished_backup: expect.any(Boolean), - no_backup: expect.any(Boolean), - recovery_mode: null, // difference between T2T1 - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Crypto', - 'Capability_Ethereum', - 'Capability_NEM', - 'Capability_Stellar', - 'Capability_U2F', - ]), - backup_type: undefined, // difference between T2T1 - sd_card_present: null, // no sdcard in T1B1 - sd_protection: null, // no sdcard in T1B1 - wipe_code_protection: false, - session_id: expect.any(String), - passphrase_always_on_device: null, // no passphrase input on T1B1 device - }, - legacyResults: [ - { - rules: ['<1.10.3'], // 1.10.3 removed Lisk capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Crypto', - 'Capability_Ethereum', - 'Capability_Lisk', - 'Capability_NEM', - 'Capability_Stellar', - 'Capability_U2F', - ]), - }, - }, - { - rules: ['<1.8.3'], // 1.8.3 added Lisk capability - success: true, - payload: { - capabilities: expect.arrayContaining([ - 'Capability_Bitcoin', - 'Capability_Bitcoin_like', - 'Capability_Crypto', - 'Capability_Ethereum', - 'Capability_NEM', - 'Capability_Stellar', - 'Capability_U2F', - ]), - }, - }, - ], - }, - ], + tests, }; diff --git a/packages/connect/setupJest.ts b/packages/connect/setupJest.ts index c30cefc999..5cb45b9758 100644 --- a/packages/connect/setupJest.ts +++ b/packages/connect/setupJest.ts @@ -19,7 +19,7 @@ export const getDeviceFeatures = (feat?: Partial): Features => ({ imported: null, unlocked: true, firmware_present: null, - needs_backup: false, + backup_availability: 'NotAvailable', flags: 0, model: 'T', internal_model: DeviceModelInternal.T2T1, @@ -29,7 +29,7 @@ export const getDeviceFeatures = (feat?: Partial): Features => ({ fw_vendor: null, unfinished_backup: false, no_backup: false, - recovery_mode: false, + recovery_status: 'Nothing', capabilities: [], backup_type: 'Bip39', sd_card_present: false, diff --git a/packages/connect/src/api/recoveryDevice.ts b/packages/connect/src/api/recoveryDevice.ts index cea3e0d6f3..337557d7a7 100644 --- a/packages/connect/src/api/recoveryDevice.ts +++ b/packages/connect/src/api/recoveryDevice.ts @@ -21,10 +21,11 @@ export default class RecoveryDevice extends AbstractMethod<'recoveryDevice', PRO language: payload.language, label: payload.label, enforce_wordlist: payload.enforce_wordlist, + input_method: payload.input_method, type: payload.type, u2f_counter: payload.u2f_counter, - dry_run: payload.dry_run, }; + this.allowDeviceMode = [...this.allowDeviceMode, UI.INITIALIZE]; this.useDeviceState = false; } diff --git a/packages/connect/src/core/index.ts b/packages/connect/src/core/index.ts index 6ff257f712..24e520a6b0 100644 --- a/packages/connect/src/core/index.ts +++ b/packages/connect/src/core/index.ts @@ -317,7 +317,7 @@ const inner = async (method: AbstractMethod, device: Device) => { } } - const deviceNeedsBackup = device.features.needs_backup; + const deviceNeedsBackup = device.features.backup_availability === 'Required'; if (deviceNeedsBackup) { if ( method.noBackupConfirmationMode === 'always' || diff --git a/packages/connect/src/types/api/__tests__/management.ts b/packages/connect/src/types/api/__tests__/management.ts index 659e6e6476..232101e9ed 100644 --- a/packages/connect/src/types/api/__tests__/management.ts +++ b/packages/connect/src/types/api/__tests__/management.ts @@ -1,4 +1,4 @@ -import { TrezorConnect } from '../../..'; +import { PROTO, TrezorConnect } from '../../..'; export const management = async (api: TrezorConnect) => { const reset = await api.resetDevice({ @@ -65,8 +65,8 @@ export const management = async (api: TrezorConnect) => { passphrase_protection: true, pin_protection: true, label: 'My Trezor', - type: 1, - dry_run: true, + input_method: PROTO.RecoveryDeviceInputMethod.Matrix, + type: PROTO.RecoveryType.DryRun, word_count: 24, }); if (recovery.success) recovery.payload.message.toLowerCase(); diff --git a/packages/protobuf/.eslintrc.js b/packages/protobuf/.eslintrc.js index b201a1fde1..2c3cec6f75 100644 --- a/packages/protobuf/.eslintrc.js +++ b/packages/protobuf/.eslintrc.js @@ -1,5 +1,6 @@ module.exports = { rules: { '@typescript-eslint/ban-types': 'off', // allow {} in protobuf.d.ts + '@typescript-eslint/no-shadow': 'off', }, }; diff --git a/packages/protobuf/messages.json b/packages/protobuf/messages.json index a3fecb9299..7e90c6f523 100644 --- a/packages/protobuf/messages.json +++ b/packages/protobuf/messages.json @@ -4450,8 +4450,8 @@ "type": "bool", "id": 18 }, - "needs_backup": { - "type": "bool", + "backup_availability": { + "type": "BackupAvailability", "id": 19 }, "flags": { @@ -4486,8 +4486,8 @@ "type": "bool", "id": 28 }, - "recovery_mode": { - "type": "bool", + "recovery_status": { + "type": "RecoveryStatus", "id": 29 }, "capabilities": { @@ -4584,9 +4584,31 @@ "unit_packaging": { "type": "uint32", "id": 51 + }, + "haptic_feedback": { + "type": "bool", + "id": 52 + }, + "recovery_type": { + "type": "RecoveryType", + "id": 53 } }, "nested": { + "BackupAvailability": { + "values": { + "NotAvailable": 0, + "Required": 1, + "Available": 2 + } + }, + "RecoveryStatus": { + "values": { + "Nothing": 0, + "Recovery": 1, + "Backup": 2 + } + }, "Capability": { "options": { "(has_bitcoin_only_values)": true @@ -4612,6 +4634,12 @@ }, "Capability_Translations": { "(bitcoin_only)": true + }, + "Capability_Brightness": { + "(bitcoin_only)": true + }, + "Capability_Haptic": { + "(bitcoin_only)": true } }, "values": { @@ -4633,7 +4661,9 @@ "Capability_ShamirGroups": 16, "Capability_PassphraseEntry": 17, "Capability_Solana": 18, - "Capability_Translations": 19 + "Capability_Translations": 19, + "Capability_Brightness": 20, + "Capability_Haptic": 21 } } } @@ -4703,6 +4733,10 @@ "hide_passphrase_from_host": { "type": "bool", "id": 11 + }, + "haptic_feedback": { + "type": "bool", + "id": 13 } } }, @@ -5031,28 +5065,38 @@ "type": "bool", "id": 6 }, - "type": { - "type": "RecoveryDeviceType", + "input_method": { + "type": "RecoveryDeviceInputMethod", "id": 8 }, "u2f_counter": { "type": "uint32", "id": 9 }, - "dry_run": { - "type": "bool", - "id": 10 + "type": { + "type": "RecoveryType", + "id": 10, + "options": { + "default": "NormalRecovery" + } } }, "nested": { - "RecoveryDeviceType": { + "RecoveryDeviceInputMethod": { "values": { - "RecoveryDeviceType_ScrambledWords": 0, - "RecoveryDeviceType_Matrix": 1 + "ScrambledWords": 0, + "Matrix": 1 } } } }, + "RecoveryType": { + "values": { + "NormalRecovery": 0, + "DryRun": 1, + "UnlockRepeatedBackup": 2 + } + }, "WordRequest": { "fields": { "type": { @@ -5188,6 +5232,14 @@ "UnlockBootloader": { "fields": {} }, + "SetBrightness": { + "fields": { + "value": { + "type": "uint32", + "id": 1 + } + } + }, "MoneroNetworkType": { "values": { "MAINNET": 0, @@ -8081,6 +8133,10 @@ "(bitcoin_only)": true, "(wire_in)": true }, + "MessageType_SetBrightness": { + "(bitcoin_only)": true, + "(wire_in)": true + }, "MessageType_SetU2FCounter": { "(wire_in)": true }, @@ -8765,6 +8821,7 @@ "MessageType_ChangeLanguage": 990, "MessageType_TranslationDataRequest": 991, "MessageType_TranslationDataAck": 992, + "MessageType_SetBrightness": 993, "MessageType_SetU2FCounter": 63, "MessageType_GetNextU2FCounter": 80, "MessageType_NextU2FCounter": 81, diff --git a/packages/protobuf/scripts/protobuf-patches/index.js b/packages/protobuf/scripts/protobuf-patches/index.js index d08457a47c..0b42d4e6b5 100644 --- a/packages/protobuf/scripts/protobuf-patches/index.js +++ b/packages/protobuf/scripts/protobuf-patches/index.js @@ -48,7 +48,7 @@ const RULE_PATCH = { 'Features.imported': 'required', 'Features.unlocked': 'required', 'Features.firmware_present': 'required', - 'Features.needs_backup': 'required', + 'Features.backup_availability': 'required', 'Features.flags': 'required', 'Features.fw_major': 'required', 'Features.fw_minor': 'required', @@ -58,7 +58,7 @@ const RULE_PATCH = { 'Features.internal_model': 'required', 'Features.unfinished_backup': 'required', 'Features.no_backup': 'required', - 'Features.recovery_mode': 'required', + 'Features.recovery_status': 'required', 'Features.backup_type': 'required', 'Features.sd_card_present': 'required', 'Features.sd_protection': 'required', @@ -95,7 +95,7 @@ const TYPE_PATCH = { 'Features.imported': 'boolean | null', 'Features.unlocked': 'boolean | null', 'Features.firmware_present': 'boolean | null', - 'Features.needs_backup': 'boolean | null', + 'Features.backup_availability': 'BackupAvailability | null', 'Features.flags': 'number | null', 'Features.fw_major': 'number | null', 'Features.fw_minor': 'number | null', @@ -103,7 +103,7 @@ const TYPE_PATCH = { 'Features.fw_vendor': 'string | null', 'Features.unfinished_backup': 'boolean | null', 'Features.no_backup': 'boolean | null', - 'Features.recovery_mode': 'boolean | null', + 'Features.recovery_status': 'RecoveryStatus | null', 'Features.backup_type': 'BackupType | null', 'Features.sd_card_present': 'boolean | null', 'Features.sd_protection': 'boolean | null', @@ -204,6 +204,7 @@ const TYPE_PATCH = { 'TezosDelegationOp.source': 'Uint8Array', 'TezosDelegationOp.delegate': 'Uint8Array', 'TezosSignTx.branch': 'Uint8Array', + 'Features.recovery_type': 'RecoveryType', }; const DEFINITION_PATCH = { diff --git a/packages/protobuf/scripts/protobuf-types.js b/packages/protobuf/scripts/protobuf-types.js index 59b5970be4..b2a05a389e 100644 --- a/packages/protobuf/scripts/protobuf-types.js +++ b/packages/protobuf/scripts/protobuf-types.js @@ -11,6 +11,13 @@ const { SINT_TYPE, } = require('./protobuf-patches'); +CONSOLE_RED = "\x1b[31m" +CONSOLE_RESET = "\x1b[0m" + +const logError = (text) => { + console.error(`Error: ${CONSOLE_RED}${text}${CONSOLE_RESET}`); +} + const INDENT = ' '.repeat(4); // proto types to javascript types @@ -38,6 +45,9 @@ const ENUM_KEYS = [ 'PinMatrixRequestType', 'WordRequestType', 'HomescreenFormat', + "RecoveryStatus", + "BackupAvailability", + "RecoveryType", ]; const parseEnum = (itemName, item) => { @@ -131,26 +141,40 @@ const parseMessage = (messageName, message, depth = 0) => { // top level messages and nested messages Object.keys(json.nested).map(e => parseMessage(e, json.nested[e])); -// types needs reordering (used before defined) +// Types needs reordering (used before defined). +// The Type in the Value NEEDs (depends on) the Type in the Key. const ORDER = { BinanceCoin: 'BinanceInputOutput', HDNodeType: 'HDNodePathType', - CardanoAssetGroupType: 'CardanoTxOutputType', - CardanoTokenType: 'CardanoAssetGroupType', TxAck: 'TxAckInputWrapper', EthereumFieldType: 'EthereumStructMember', EthereumDataType: 'EthereumFieldType', PaymentRequestMemo: 'TxAckPaymentRequest', + RecoveryDevice: 'Features', + RecoveryType: 'RecoveryDevice', + RecoveryDeviceInputMethod: 'RecoveryType', }; Object.keys(ORDER).forEach(key => { + if (key === ORDER[key]) { + logError(`ORDER map cannot have key=value`) + } + // find indexes - const indexA = types.findIndex(t => t && t.name === key); - const indexB = types.findIndex(t => t && t.name === ORDER[key]); - const prevA = types[indexA]; + const indexOfDependency = types.findIndex(t => t && t.name === key); + if (indexOfDependency === -1) { + logError(`Type from key: '${key}' not found in the 'types' variable!`) + } + + const indexOfDependant = types.findIndex(t => t && t.name === ORDER[key]); + if (indexOfDependant === -1) { + logError(`Type from value: '${ORDER[key]}' not found in the 'types' variable!`) + } + + const dependency = types[indexOfDependency]; // replace values - delete types[indexA]; - types.splice(indexB, 0, prevA); + delete types[indexOfDependency]; + types.splice(indexOfDependant, 0, dependency); }); // skip not needed types diff --git a/packages/protobuf/src/messages-schema.ts b/packages/protobuf/src/messages-schema.ts index 0079a85185..c5e4a7dc43 100644 --- a/packages/protobuf/src/messages-schema.ts +++ b/packages/protobuf/src/messages-schema.ts @@ -2200,6 +2200,32 @@ export const Initialize = Type.Object( export type GetFeatures = Static; export const GetFeatures = Type.Object({}, { $id: 'GetFeatures' }); +export enum Enum_BackupAvailability { + NotAvailable = 0, + Required = 1, + Available = 2, +} + +export type EnumEnum_BackupAvailability = Static; +export const EnumEnum_BackupAvailability = Type.Enum(Enum_BackupAvailability); + +export type BackupAvailability = Static; +export const BackupAvailability = Type.KeyOfEnum(Enum_BackupAvailability, { + $id: 'BackupAvailability', +}); + +export enum Enum_RecoveryStatus { + Nothing = 0, + Recovery = 1, + Backup = 2, +} + +export type EnumEnum_RecoveryStatus = Static; +export const EnumEnum_RecoveryStatus = Type.Enum(Enum_RecoveryStatus); + +export type RecoveryStatus = Static; +export const RecoveryStatus = Type.KeyOfEnum(Enum_RecoveryStatus, { $id: 'RecoveryStatus' }); + export enum Enum_Capability { Capability_Bitcoin = 1, Capability_Bitcoin_like = 2, @@ -2220,6 +2246,8 @@ export enum Enum_Capability { Capability_PassphraseEntry = 17, Capability_Solana = 18, Capability_Translations = 19, + Capability_Brightness = 20, + Capability_Haptic = 21, } export type EnumEnum_Capability = Static; @@ -2228,6 +2256,42 @@ export const EnumEnum_Capability = Type.Enum(Enum_Capability); export type Capability = Static; export const Capability = Type.KeyOfEnum(Enum_Capability, { $id: 'Capability' }); +export enum RecoveryDeviceInputMethod { + ScrambledWords = 0, + Matrix = 1, +} + +export type EnumRecoveryDeviceInputMethod = Static; +export const EnumRecoveryDeviceInputMethod = Type.Enum(RecoveryDeviceInputMethod); + +export enum Enum_RecoveryType { + NormalRecovery = 0, + DryRun = 1, + UnlockRepeatedBackup = 2, +} + +export type EnumEnum_RecoveryType = Static; +export const EnumEnum_RecoveryType = Type.Enum(Enum_RecoveryType); + +export type RecoveryType = Static; +export const RecoveryType = Type.KeyOfEnum(Enum_RecoveryType, { $id: 'RecoveryType' }); + +export type RecoveryDevice = Static; +export const RecoveryDevice = Type.Object( + { + word_count: Type.Optional(Type.Number()), + passphrase_protection: Type.Optional(Type.Boolean()), + pin_protection: Type.Optional(Type.Boolean()), + language: Type.Optional(Type.String()), + label: Type.Optional(Type.String()), + enforce_wordlist: Type.Optional(Type.Boolean()), + input_method: Type.Optional(EnumRecoveryDeviceInputMethod), + u2f_counter: Type.Optional(Type.Number()), + type: Type.Optional(RecoveryType), + }, + { $id: 'RecoveryDevice' }, +); + export type Features = Static; export const Features = Type.Object( { @@ -2248,7 +2312,7 @@ export const Features = Type.Object( unlocked: Type.Union([Type.Boolean(), Type.Null()]), _passphrase_cached: Type.Optional(Type.Boolean()), firmware_present: Type.Union([Type.Boolean(), Type.Null()]), - needs_backup: Type.Union([Type.Boolean(), Type.Null()]), + backup_availability: Type.Union([BackupAvailability, Type.Null()]), flags: Type.Union([Type.Number(), Type.Null()]), model: Type.String(), fw_major: Type.Union([Type.Number(), Type.Null()]), @@ -2257,7 +2321,7 @@ export const Features = Type.Object( fw_vendor: Type.Union([Type.String(), Type.Null()]), unfinished_backup: Type.Union([Type.Boolean(), Type.Null()]), no_backup: Type.Union([Type.Boolean(), Type.Null()]), - recovery_mode: Type.Union([Type.Boolean(), Type.Null()]), + recovery_status: Type.Union([RecoveryStatus, Type.Null()]), capabilities: Type.Array(Capability), backup_type: Type.Union([BackupType, Type.Null()]), sd_card_present: Type.Union([Type.Boolean(), Type.Null()]), @@ -2280,6 +2344,8 @@ export const Features = Type.Object( bootloader_locked: Type.Optional(Type.Boolean()), language_version_matches: Type.Optional(Type.Boolean()), unit_packaging: Type.Optional(Type.Number()), + haptic_feedback: Type.Optional(Type.Boolean()), + recovery_type: Type.Optional(RecoveryType), }, { $id: 'Features' }, ); @@ -2312,6 +2378,7 @@ export const ApplySettings = Type.Object( safety_checks: Type.Optional(SafetyCheckLevel), experimental_features: Type.Optional(Type.Boolean()), hide_passphrase_from_host: Type.Optional(Type.Boolean()), + haptic_feedback: Type.Optional(Type.Boolean()), }, { $id: 'ApplySettings' }, ); @@ -2493,30 +2560,6 @@ export const EntropyAck = Type.Object( { $id: 'EntropyAck' }, ); -export enum RecoveryDeviceType { - RecoveryDeviceType_ScrambledWords = 0, - RecoveryDeviceType_Matrix = 1, -} - -export type EnumRecoveryDeviceType = Static; -export const EnumRecoveryDeviceType = Type.Enum(RecoveryDeviceType); - -export type RecoveryDevice = Static; -export const RecoveryDevice = Type.Object( - { - word_count: Type.Optional(Type.Number()), - passphrase_protection: Type.Optional(Type.Boolean()), - pin_protection: Type.Optional(Type.Boolean()), - language: Type.Optional(Type.String()), - label: Type.Optional(Type.String()), - enforce_wordlist: Type.Optional(Type.Boolean()), - type: Type.Optional(EnumRecoveryDeviceType), - u2f_counter: Type.Optional(Type.Number()), - dry_run: Type.Optional(Type.Boolean()), - }, - { $id: 'RecoveryDevice' }, -); - export enum Enum_WordRequestType { WordRequestType_Plain = 0, WordRequestType_Matrix9 = 1, @@ -2625,6 +2668,14 @@ export const ShowDeviceTutorial = Type.Object({}, { $id: 'ShowDeviceTutorial' }) export type UnlockBootloader = Static; export const UnlockBootloader = Type.Object({}, { $id: 'UnlockBootloader' }); +export type SetBrightness = Static; +export const SetBrightness = Type.Object( + { + value: Type.Optional(Type.Number()), + }, + { $id: 'SetBrightness' }, +); + export enum MoneroNetworkType { MAINNET = 0, TESTNET = 1, @@ -3598,6 +3649,7 @@ export const MessageType = Type.Object( EthereumTypedDataSignature, Initialize, GetFeatures, + RecoveryDevice, Features, LockDevice, SetBusy, @@ -3624,7 +3676,6 @@ export const MessageType = Type.Object( BackupDevice, EntropyRequest, EntropyAck, - RecoveryDevice, WordRequest, WordAck, SetU2FCounter, @@ -3640,6 +3691,7 @@ export const MessageType = Type.Object( UnlockedPathRequest, ShowDeviceTutorial, UnlockBootloader, + SetBrightness, NEMGetAddress, NEMAddress, NEMTransactionCommon, diff --git a/packages/protobuf/src/messages.ts b/packages/protobuf/src/messages.ts index 4d55fdaa83..67d20e15f1 100644 --- a/packages/protobuf/src/messages.ts +++ b/packages/protobuf/src/messages.ts @@ -1554,6 +1554,22 @@ export type Initialize = { // GetFeatures export type GetFeatures = {}; +export enum Enum_BackupAvailability { + NotAvailable = 0, + Required = 1, + Available = 2, +} + +export type BackupAvailability = keyof typeof Enum_BackupAvailability; + +export enum Enum_RecoveryStatus { + Nothing = 0, + Recovery = 1, + Backup = 2, +} + +export type RecoveryStatus = keyof typeof Enum_RecoveryStatus; + export enum Enum_Capability { Capability_Bitcoin = 1, Capability_Bitcoin_like = 2, @@ -1574,10 +1590,38 @@ export enum Enum_Capability { Capability_PassphraseEntry = 17, Capability_Solana = 18, Capability_Translations = 19, + Capability_Brightness = 20, + Capability_Haptic = 21, } export type Capability = keyof typeof Enum_Capability; +export enum RecoveryDeviceInputMethod { + ScrambledWords = 0, + Matrix = 1, +} + +export enum Enum_RecoveryType { + NormalRecovery = 0, + DryRun = 1, + UnlockRepeatedBackup = 2, +} + +export type RecoveryType = keyof typeof Enum_RecoveryType; + +// RecoveryDevice +export type RecoveryDevice = { + word_count?: number; + passphrase_protection?: boolean; + pin_protection?: boolean; + language?: string; + label?: string; + enforce_wordlist?: boolean; + input_method?: RecoveryDeviceInputMethod; + u2f_counter?: number; + type?: RecoveryType; +}; + // Features export type Features = { vendor: string; @@ -1597,7 +1641,7 @@ export type Features = { unlocked: boolean | null; _passphrase_cached?: boolean; firmware_present: boolean | null; - needs_backup: boolean | null; + backup_availability: BackupAvailability | null; flags: number | null; model: string; fw_major: number | null; @@ -1606,7 +1650,7 @@ export type Features = { fw_vendor: string | null; unfinished_backup: boolean | null; no_backup: boolean | null; - recovery_mode: boolean | null; + recovery_status: RecoveryStatus | null; capabilities: Capability[]; backup_type: BackupType | null; sd_card_present: boolean | null; @@ -1629,6 +1673,8 @@ export type Features = { bootloader_locked?: boolean; language_version_matches?: boolean; unit_packaging?: number; + haptic_feedback?: boolean; + recovery_type?: RecoveryType; }; // LockDevice @@ -1655,6 +1701,7 @@ export type ApplySettings = { safety_checks?: SafetyCheckLevel; experimental_features?: boolean; hide_passphrase_from_host?: boolean; + haptic_feedback?: boolean; }; // ChangeLanguage @@ -1776,24 +1823,6 @@ export type EntropyAck = { entropy: string; }; -export enum RecoveryDeviceType { - RecoveryDeviceType_ScrambledWords = 0, - RecoveryDeviceType_Matrix = 1, -} - -// RecoveryDevice -export type RecoveryDevice = { - word_count?: number; - passphrase_protection?: boolean; - pin_protection?: boolean; - language?: string; - label?: string; - enforce_wordlist?: boolean; - type?: RecoveryDeviceType; - u2f_counter?: number; - dry_run?: boolean; -}; - export enum Enum_WordRequestType { WordRequestType_Plain = 0, WordRequestType_Matrix9 = 1, @@ -1871,6 +1900,11 @@ export type ShowDeviceTutorial = {}; // UnlockBootloader export type UnlockBootloader = {}; +// SetBrightness +export type SetBrightness = { + value?: number; +}; + export enum MoneroNetworkType { MAINNET = 0, TESTNET = 1, @@ -2597,6 +2631,7 @@ export type MessageType = { EthereumTypedDataSignature: EthereumTypedDataSignature; Initialize: Initialize; GetFeatures: GetFeatures; + RecoveryDevice: RecoveryDevice; Features: Features; LockDevice: LockDevice; SetBusy: SetBusy; @@ -2623,7 +2658,6 @@ export type MessageType = { BackupDevice: BackupDevice; EntropyRequest: EntropyRequest; EntropyAck: EntropyAck; - RecoveryDevice: RecoveryDevice; WordRequest: WordRequest; WordAck: WordAck; SetU2FCounter: SetU2FCounter; @@ -2639,6 +2673,7 @@ export type MessageType = { UnlockedPathRequest: UnlockedPathRequest; ShowDeviceTutorial: ShowDeviceTutorial; UnlockBootloader: UnlockBootloader; + SetBrightness: SetBrightness; NEMGetAddress: NEMGetAddress; NEMAddress: NEMAddress; NEMTransactionCommon: NEMTransactionCommon; diff --git a/packages/schema-utils/tests/__snapshots__/codegen.input.ts b/packages/schema-utils/tests/__snapshots__/codegen.input.ts deleted file mode 100644 index 87f5c3ab24..0000000000 --- a/packages/schema-utils/tests/__snapshots__/codegen.input.ts +++ /dev/null @@ -1,2618 +0,0 @@ -// This file is auto generated from data/messages/message.json - -// custom type uint32/64 may be represented as string -export type UintType = string | number; - -export enum DeviceModelInternal { - T1B1 = 'T1B1', - T2T1 = 'T2T1', - T2B1 = 'T2B1', -} - -// BinanceGetAddress -export type BinanceGetAddress = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// BinanceAddress -export type BinanceAddress = { - address: string; -}; - -// BinanceGetPublicKey -export type BinanceGetPublicKey = { - address_n: number[]; - show_display?: boolean; -}; - -// BinancePublicKey -export type BinancePublicKey = { - public_key: string; -}; - -// BinanceSignTx -export type BinanceSignTx = { - address_n: number[]; - msg_count: number; - account_number: number; - chain_id?: string; - memo?: string; - sequence: number; - source: number; - chunkify?: boolean; -}; - -// BinanceTxRequest -export type BinanceTxRequest = {}; - -export type BinanceCoin = { - amount: UintType; - denom: string; -}; - -export type BinanceInputOutput = { - address: string; - coins: BinanceCoin[]; -}; - -// BinanceTransferMsg -export type BinanceTransferMsg = { - inputs: BinanceInputOutput[]; - outputs: BinanceInputOutput[]; - chunkify?: boolean; -}; - -export enum BinanceOrderType { - OT_UNKNOWN = 0, - MARKET = 1, - LIMIT = 2, - OT_RESERVED = 3, -} - -export enum BinanceOrderSide { - SIDE_UNKNOWN = 0, - BUY = 1, - SELL = 2, -} - -export enum BinanceTimeInForce { - TIF_UNKNOWN = 0, - GTE = 1, - TIF_RESERVED = 2, - IOC = 3, -} - -// BinanceOrderMsg -export type BinanceOrderMsg = { - id?: string; - ordertype: BinanceOrderType; - price: number; - quantity: number; - sender?: string; - side: BinanceOrderSide; - symbol?: string; - timeinforce: BinanceTimeInForce; -}; - -// BinanceCancelMsg -export type BinanceCancelMsg = { - refid?: string; - sender?: string; - symbol?: string; -}; - -// BinanceSignedTx -export type BinanceSignedTx = { - signature: string; - public_key: string; -}; - -export enum Enum_InputScriptType { - SPENDADDRESS = 0, - SPENDMULTISIG = 1, - EXTERNAL = 2, - SPENDWITNESS = 3, - SPENDP2SHWITNESS = 4, - SPENDTAPROOT = 5, -} - -export type InputScriptType = keyof typeof Enum_InputScriptType; - -export enum Enum_OutputScriptType { - PAYTOADDRESS = 0, - PAYTOSCRIPTHASH = 1, - PAYTOMULTISIG = 2, - PAYTOOPRETURN = 3, - PAYTOWITNESS = 4, - PAYTOP2SHWITNESS = 5, - PAYTOTAPROOT = 6, -} - -export type OutputScriptType = keyof typeof Enum_OutputScriptType; - -export enum DecredStakingSpendType { - SSGen = 0, - SSRTX = 1, -} - -export enum AmountUnit { - BITCOIN = 0, - MILLIBITCOIN = 1, - MICROBITCOIN = 2, - SATOSHI = 3, -} - -// HDNodeType -export type HDNodeType = { - depth: number; - fingerprint: number; - child_num: number; - chain_code: string; - private_key?: string; - public_key: string; -}; - -export type HDNodePathType = { - node: HDNodeType | string; - address_n: number[]; -}; - -// MultisigRedeemScriptType -export type MultisigRedeemScriptType = { - pubkeys: HDNodePathType[]; - signatures: string[]; - m: number; - nodes?: HDNodeType[]; - address_n?: number[]; -}; - -// GetPublicKey -export type GetPublicKey = { - address_n: number[]; - ecdsa_curve_name?: string; - show_display?: boolean; - coin_name?: string; - script_type?: InputScriptType; - ignore_xpub_magic?: boolean; -}; - -// PublicKey -export type PublicKey = { - node: HDNodeType; - xpub: string; - root_fingerprint?: number; -}; - -// GetAddress -export type GetAddress = { - address_n: number[]; - coin_name?: string; - show_display?: boolean; - multisig?: MultisigRedeemScriptType; - script_type?: InputScriptType; - ignore_xpub_magic?: boolean; - chunkify?: boolean; -}; - -// Address -export type Address = { - address: string; - mac?: string; -}; - -// GetOwnershipId -export type GetOwnershipId = { - address_n: number[]; - coin_name?: string; - multisig?: MultisigRedeemScriptType; - script_type?: InputScriptType; -}; - -// OwnershipId -export type OwnershipId = { - ownership_id: string; -}; - -// SignMessage -export type SignMessage = { - address_n: number[]; - message: string; - coin_name?: string; - script_type?: InputScriptType; - no_script_type?: boolean; -}; - -// MessageSignature -export type MessageSignature = { - address: string; - signature: string; -}; - -// VerifyMessage -export type VerifyMessage = { - address: string; - signature: string; - message: string; - coin_name?: string; -}; - -export type CoinJoinRequest = { - fee_rate: number; - no_fee_threshold: number; - min_registrable_amount: number; - mask_public_key: string; - signature: string; -}; - -// SignTx -export type SignTx = { - outputs_count: number; - inputs_count: number; - coin_name?: string; - version?: number; - lock_time?: number; - expiry?: number; - overwintered?: boolean; - version_group_id?: number; - timestamp?: number; - branch_id?: number; - amount_unit?: AmountUnit; - decred_staking_ticket?: boolean; - serialize?: boolean; - coinjoin_request?: CoinJoinRequest; - chunkify?: boolean; -}; - -export enum Enum_RequestType { - TXINPUT = 0, - TXOUTPUT = 1, - TXMETA = 2, - TXFINISHED = 3, - TXEXTRADATA = 4, - TXORIGINPUT = 5, - TXORIGOUTPUT = 6, - TXPAYMENTREQ = 7, -} - -export type RequestType = keyof typeof Enum_RequestType; - -export type TxRequestDetailsType = { - request_index: number; - tx_hash?: string; - extra_data_len?: number; - extra_data_offset?: number; -}; - -export type TxRequestSerializedType = { - signature_index?: number; - signature?: string; - serialized_tx?: string; -}; - -// TxRequest -export type TxRequest = { - request_type: RequestType; - details: TxRequestDetailsType; - serialized?: TxRequestSerializedType; -}; - -// TxInputType replacement -// TxInputType needs more exact types -// differences: external input (no address_n + required script_pubkey) - -export type InternalInputScriptType = Exclude; - -type CommonTxInputType = { - prev_hash: string; // required: previous transaction hash (reversed) - prev_index: number; // required: previous transaction index - amount: UintType; // required - sequence?: number; - multisig?: MultisigRedeemScriptType; - decred_tree?: number; - orig_hash?: string; // RBF - orig_index?: number; // RBF - decred_staking_spend?: DecredStakingSpendType; - script_pubkey?: string; // required if script_type=EXTERNAL - coinjoin_flags?: number; // bit field of coinjoin-specific flags - script_sig?: string; // used by EXTERNAL, depending on script_pubkey - witness?: string; // used by EXTERNAL, depending on script_pubkey - ownership_proof?: string; // used by EXTERNAL, depending on script_pubkey - commitment_data?: string; // used by EXTERNAL, depending on ownership_proof -}; - -export type TxInputType = - | (CommonTxInputType & { - address_n: number[]; - script_type?: InternalInputScriptType; - }) - | (CommonTxInputType & { - address_n?: typeof undefined; - script_type: 'EXTERNAL'; - script_pubkey: string; - }); - -export type TxInput = TxInputType; - -// TxInputType replacement end - -export type TxOutputBinType = { - amount: UintType; - script_pubkey: string; - decred_script_version?: number; -}; - -// TxOutputType replacement -// TxOutputType needs more exact types -// differences: external output (no address_n), opreturn output (no address_n, no address) - -export type ChangeOutputScriptType = Exclude; - -export type TxOutputType = - | { - address: string; - address_n?: typeof undefined; - script_type: 'PAYTOADDRESS'; - amount: UintType; - multisig?: MultisigRedeemScriptType; - orig_hash?: string; - orig_index?: number; - payment_req_index?: number; - } - | { - address?: typeof undefined; - address_n: number[]; - script_type?: ChangeOutputScriptType; - amount: UintType; - multisig?: MultisigRedeemScriptType; - orig_hash?: string; - orig_index?: number; - payment_req_index?: number; - } - | { - address?: typeof undefined; - address_n?: typeof undefined; - amount: '0'; - op_return_data: string; - script_type: 'PAYTOOPRETURN'; - orig_hash?: string; - orig_index?: number; - payment_req_index?: number; - }; - -export type TxOutput = TxOutputType; - -// - TxOutputType replacement end - -// PrevTx -export type PrevTx = { - version: number; - lock_time: number; - inputs_count: number; - outputs_count: number; - extra_data_len?: number; - expiry?: number; - version_group_id?: number; - timestamp?: number; - branch_id?: number; -}; - -// PrevInput -export type PrevInput = { - prev_hash: string; - prev_index: number; - script_sig: string; - sequence: number; - decred_tree?: number; -}; - -// PrevOutput -export type PrevOutput = { - amount: UintType; - script_pubkey: string; - decred_script_version?: number; -}; - -export type TextMemo = { - text: string; -}; - -export type RefundMemo = { - address: string; - mac: string; -}; - -export type CoinPurchaseMemo = { - coin_type: number; - amount: UintType; - address: string; - mac: string; -}; - -export type PaymentRequestMemo = { - text_memo?: TextMemo; - refund_memo?: RefundMemo; - coin_purchase_memo?: CoinPurchaseMemo; -}; - -// TxAckPaymentRequest -export type TxAckPaymentRequest = { - nonce?: string; - recipient_name: string; - memos?: PaymentRequestMemo[]; - amount?: UintType; - signature: string; -}; - -// TxAck -// TxAck replacement -// TxAck needs more exact types -// PrevInput and TxInputType requires exact responses in TxAckResponse -// main difference: PrevInput should not contain address_n (unexpected field by protobuf) - -export type TxAckResponse = - | { - inputs: Array; - } - | { - bin_outputs: TxOutputBinType[]; - } - | { - outputs: TxOutputType[]; - } - | { - extra_data: string; - } - | { - version?: number; - lock_time?: number; - inputs_cnt: number; - outputs_cnt: number; - extra_data?: string; - extra_data_len?: number; - timestamp?: number; - version_group_id?: number; - expiry?: number; - branch_id?: number; - }; - -export type TxAck = { - tx: TxAckResponse; -}; -// - TxAck replacement end - -export type TxAckInputWrapper = { - input: TxInput; -}; - -// TxAckInput -export type TxAckInput = { - tx: TxAckInputWrapper; -}; - -export type TxAckOutputWrapper = { - output: TxOutput; -}; - -// TxAckOutput -export type TxAckOutput = { - tx: TxAckOutputWrapper; -}; - -// TxAckPrevMeta -export type TxAckPrevMeta = { - tx: PrevTx; -}; - -export type TxAckPrevInputWrapper = { - input: PrevInput; -}; - -// TxAckPrevInput -export type TxAckPrevInput = { - tx: TxAckPrevInputWrapper; -}; - -export type TxAckPrevOutputWrapper = { - output: PrevOutput; -}; - -// TxAckPrevOutput -export type TxAckPrevOutput = { - tx: TxAckPrevOutputWrapper; -}; - -export type TxAckPrevExtraDataWrapper = { - extra_data_chunk: string; -}; - -// TxAckPrevExtraData -export type TxAckPrevExtraData = { - tx: TxAckPrevExtraDataWrapper; -}; - -// GetOwnershipProof -export type GetOwnershipProof = { - address_n: number[]; - coin_name?: string; - script_type?: InputScriptType; - multisig?: MultisigRedeemScriptType; - user_confirmation?: boolean; - ownership_ids?: string[]; - commitment_data?: string; -}; - -// OwnershipProof -export type OwnershipProof = { - ownership_proof: string; - signature: string; -}; - -// AuthorizeCoinJoin -export type AuthorizeCoinJoin = { - coordinator: string; - max_rounds: number; - max_coordinator_fee_rate: number; - max_fee_per_kvbyte: number; - address_n: number[]; - coin_name?: string; - script_type?: InputScriptType; - amount_unit?: AmountUnit; -}; - -// FirmwareErase -export type FirmwareErase = { - length?: number; -}; - -// FirmwareRequest -export type FirmwareRequest = { - offset: number; - length: number; -}; - -// FirmwareUpload -export type FirmwareUpload = { - payload: Buffer | ArrayBuffer; - hash?: string; -}; - -// SelfTest -export type SelfTest = { - payload?: string; -}; - -export enum CardanoDerivationType { - LEDGER = 0, - ICARUS = 1, - ICARUS_TREZOR = 2, -} - -export enum CardanoAddressType { - BASE = 0, - BASE_SCRIPT_KEY = 1, - BASE_KEY_SCRIPT = 2, - BASE_SCRIPT_SCRIPT = 3, - POINTER = 4, - POINTER_SCRIPT = 5, - ENTERPRISE = 6, - ENTERPRISE_SCRIPT = 7, - BYRON = 8, - REWARD = 14, - REWARD_SCRIPT = 15, -} - -export enum CardanoNativeScriptType { - PUB_KEY = 0, - ALL = 1, - ANY = 2, - N_OF_K = 3, - INVALID_BEFORE = 4, - INVALID_HEREAFTER = 5, -} - -export enum CardanoNativeScriptHashDisplayFormat { - HIDE = 0, - BECH32 = 1, - POLICY_ID = 2, -} - -export enum CardanoTxOutputSerializationFormat { - ARRAY_LEGACY = 0, - MAP_BABBAGE = 1, -} - -export enum CardanoCertificateType { - STAKE_REGISTRATION = 0, - STAKE_DEREGISTRATION = 1, - STAKE_DELEGATION = 2, - STAKE_POOL_REGISTRATION = 3, -} - -export enum CardanoPoolRelayType { - SINGLE_HOST_IP = 0, - SINGLE_HOST_NAME = 1, - MULTIPLE_HOST_NAME = 2, -} - -export enum CardanoTxAuxiliaryDataSupplementType { - NONE = 0, - CVOTE_REGISTRATION_SIGNATURE = 1, -} - -export enum CardanoCVoteRegistrationFormat { - CIP15 = 0, - CIP36 = 1, -} - -export enum CardanoTxSigningMode { - ORDINARY_TRANSACTION = 0, - POOL_REGISTRATION_AS_OWNER = 1, - MULTISIG_TRANSACTION = 2, - PLUTUS_TRANSACTION = 3, -} - -export enum CardanoTxWitnessType { - BYRON_WITNESS = 0, - SHELLEY_WITNESS = 1, -} - -// CardanoBlockchainPointerType -export type CardanoBlockchainPointerType = { - block_index: number; - tx_index: number; - certificate_index: number; -}; - -// CardanoNativeScript -export type CardanoNativeScript = { - type: CardanoNativeScriptType; - scripts?: CardanoNativeScript[]; - key_hash?: string; - key_path?: number[]; - required_signatures_count?: number; - invalid_before?: UintType; - invalid_hereafter?: UintType; -}; - -// CardanoGetNativeScriptHash -export type CardanoGetNativeScriptHash = { - script: CardanoNativeScript; - display_format: CardanoNativeScriptHashDisplayFormat; - derivation_type: CardanoDerivationType; -}; - -// CardanoNativeScriptHash -export type CardanoNativeScriptHash = { - script_hash: string; -}; - -// CardanoAddressParametersType -export type CardanoAddressParametersType = { - address_type: CardanoAddressType; - address_n: number[]; - address_n_staking: number[]; - staking_key_hash?: string; - certificate_pointer?: CardanoBlockchainPointerType; - script_payment_hash?: string; - script_staking_hash?: string; -}; - -// CardanoGetAddress -export type CardanoGetAddress = { - show_display?: boolean; - protocol_magic: number; - network_id: number; - address_parameters: CardanoAddressParametersType; - derivation_type: CardanoDerivationType; - chunkify?: boolean; -}; - -// CardanoAddress -export type CardanoAddress = { - address: string; -}; - -// CardanoGetPublicKey -export type CardanoGetPublicKey = { - address_n: number[]; - show_display?: boolean; - derivation_type: CardanoDerivationType; -}; - -// CardanoPublicKey -export type CardanoPublicKey = { - xpub: string; - node: HDNodeType; -}; - -// CardanoSignTxInit -export type CardanoSignTxInit = { - signing_mode: CardanoTxSigningMode; - protocol_magic: number; - network_id: number; - inputs_count: number; - outputs_count: number; - fee: UintType; - ttl?: UintType; - certificates_count: number; - withdrawals_count: number; - has_auxiliary_data: boolean; - validity_interval_start?: UintType; - witness_requests_count: number; - minting_asset_groups_count: number; - derivation_type: CardanoDerivationType; - include_network_id?: boolean; - script_data_hash?: string; - collateral_inputs_count: number; - required_signers_count: number; - has_collateral_return?: boolean; - total_collateral?: UintType; - reference_inputs_count?: number; - chunkify?: boolean; -}; - -// CardanoTxInput -export type CardanoTxInput = { - prev_hash: string; - prev_index: number; -}; - -// CardanoTxOutput -export type CardanoTxOutput = { - address?: string; - address_parameters?: CardanoAddressParametersType; - amount: UintType; - asset_groups_count: number; - datum_hash?: string; - format?: CardanoTxOutputSerializationFormat; - inline_datum_size?: number; - reference_script_size?: number; -}; - -// CardanoAssetGroup -export type CardanoAssetGroup = { - policy_id: string; - tokens_count: number; -}; - -// CardanoToken -export type CardanoToken = { - asset_name_bytes: string; - amount?: UintType; - mint_amount?: UintType; -}; - -// CardanoTxInlineDatumChunk -export type CardanoTxInlineDatumChunk = { - data: string; -}; - -// CardanoTxReferenceScriptChunk -export type CardanoTxReferenceScriptChunk = { - data: string; -}; - -// CardanoPoolOwner -export type CardanoPoolOwner = { - staking_key_path?: number[]; - staking_key_hash?: string; -}; - -// CardanoPoolRelayParameters -export type CardanoPoolRelayParameters = { - type: CardanoPoolRelayType; - ipv4_address?: string; - ipv6_address?: string; - host_name?: string; - port?: number; -}; - -// CardanoPoolMetadataType -export type CardanoPoolMetadataType = { - url: string; - hash: string; -}; - -// CardanoPoolParametersType -export type CardanoPoolParametersType = { - pool_id: string; - vrf_key_hash: string; - pledge: UintType; - cost: UintType; - margin_numerator: UintType; - margin_denominator: UintType; - reward_account: string; - metadata?: CardanoPoolMetadataType; - owners_count: number; - relays_count: number; -}; - -// CardanoTxCertificate -export type CardanoTxCertificate = { - type: CardanoCertificateType; - path?: number[]; - pool?: string; - pool_parameters?: CardanoPoolParametersType; - script_hash?: string; - key_hash?: string; -}; - -// CardanoTxWithdrawal -export type CardanoTxWithdrawal = { - path?: number[]; - amount: UintType; - script_hash?: string; - key_hash?: string; -}; - -// CardanoCVoteRegistrationDelegation -export type CardanoCVoteRegistrationDelegation = { - vote_public_key: string; - weight: UintType; -}; - -// CardanoCVoteRegistrationParametersType -export type CardanoCVoteRegistrationParametersType = { - vote_public_key?: string; - staking_path: number[]; - payment_address_parameters?: CardanoAddressParametersType; - nonce: UintType; - format?: CardanoCVoteRegistrationFormat; - delegations?: CardanoCVoteRegistrationDelegation[]; - voting_purpose?: UintType; - payment_address?: string; -}; - -// CardanoTxAuxiliaryData -export type CardanoTxAuxiliaryData = { - cvote_registration_parameters?: CardanoCVoteRegistrationParametersType; - hash?: string; -}; - -// CardanoTxMint -export type CardanoTxMint = { - asset_groups_count: number; -}; - -// CardanoTxCollateralInput -export type CardanoTxCollateralInput = { - prev_hash: string; - prev_index: number; -}; - -// CardanoTxRequiredSigner -export type CardanoTxRequiredSigner = { - key_hash?: string; - key_path?: number[]; -}; - -// CardanoTxReferenceInput -export type CardanoTxReferenceInput = { - prev_hash: string; - prev_index: number; -}; - -// CardanoTxItemAck -export type CardanoTxItemAck = {}; - -// CardanoTxAuxiliaryDataSupplement -export type CardanoTxAuxiliaryDataSupplement = { - type: CardanoTxAuxiliaryDataSupplementType; - auxiliary_data_hash?: string; - cvote_registration_signature?: string; -}; - -// CardanoTxWitnessRequest -export type CardanoTxWitnessRequest = { - path: number[]; -}; - -// CardanoTxWitnessResponse -export type CardanoTxWitnessResponse = { - type: CardanoTxWitnessType; - pub_key: string; - signature: string; - chain_code?: string; -}; - -// CardanoTxHostAck -export type CardanoTxHostAck = {}; - -// CardanoTxBodyHash -export type CardanoTxBodyHash = { - tx_hash: string; -}; - -// CardanoSignTxFinished -export type CardanoSignTxFinished = {}; - -// Success -export type Success = { - message: string; -}; - -export enum FailureType { - Failure_UnexpectedMessage = 1, - Failure_ButtonExpected = 2, - Failure_DataError = 3, - Failure_ActionCancelled = 4, - Failure_PinExpected = 5, - Failure_PinCancelled = 6, - Failure_PinInvalid = 7, - Failure_InvalidSignature = 8, - Failure_ProcessError = 9, - Failure_NotEnoughFunds = 10, - Failure_NotInitialized = 11, - Failure_PinMismatch = 12, - Failure_WipeCodeMismatch = 13, - Failure_InvalidSession = 14, - Failure_FirmwareError = 99, -} - -// Failure -export type Failure = { - code?: FailureType; - message?: string; -}; - -export enum Enum_ButtonRequestType { - ButtonRequest_Other = 1, - ButtonRequest_FeeOverThreshold = 2, - ButtonRequest_ConfirmOutput = 3, - ButtonRequest_ResetDevice = 4, - ButtonRequest_ConfirmWord = 5, - ButtonRequest_WipeDevice = 6, - ButtonRequest_ProtectCall = 7, - ButtonRequest_SignTx = 8, - ButtonRequest_FirmwareCheck = 9, - ButtonRequest_Address = 10, - ButtonRequest_PublicKey = 11, - ButtonRequest_MnemonicWordCount = 12, - ButtonRequest_MnemonicInput = 13, - _Deprecated_ButtonRequest_PassphraseType = 14, - ButtonRequest_UnknownDerivationPath = 15, - ButtonRequest_RecoveryHomepage = 16, - ButtonRequest_Success = 17, - ButtonRequest_Warning = 18, - ButtonRequest_PassphraseEntry = 19, - ButtonRequest_PinEntry = 20, -} - -export type ButtonRequestType = keyof typeof Enum_ButtonRequestType; - -// ButtonRequest -export type ButtonRequest = { - code?: ButtonRequestType; - pages?: number; -}; - -// ButtonAck -export type ButtonAck = {}; - -export enum Enum_PinMatrixRequestType { - PinMatrixRequestType_Current = 1, - PinMatrixRequestType_NewFirst = 2, - PinMatrixRequestType_NewSecond = 3, - PinMatrixRequestType_WipeCodeFirst = 4, - PinMatrixRequestType_WipeCodeSecond = 5, -} - -export type PinMatrixRequestType = keyof typeof Enum_PinMatrixRequestType; - -// PinMatrixRequest -export type PinMatrixRequest = { - type?: PinMatrixRequestType; -}; - -// PinMatrixAck -export type PinMatrixAck = { - pin: string; -}; - -// PassphraseRequest -export type PassphraseRequest = { - _on_device?: boolean; -}; - -// PassphraseAck -export type PassphraseAck = { - passphrase?: string; - _state?: string; - on_device?: boolean; -}; - -// Deprecated_PassphraseStateRequest -export type Deprecated_PassphraseStateRequest = { - state?: string; -}; - -// Deprecated_PassphraseStateAck -export type Deprecated_PassphraseStateAck = {}; - -// CipherKeyValue -export type CipherKeyValue = { - address_n: number[]; - key: string; - value: string; - encrypt?: boolean; - ask_on_encrypt?: boolean; - ask_on_decrypt?: boolean; - iv?: string; -}; - -// CipheredKeyValue -export type CipheredKeyValue = { - value: string; -}; - -// IdentityType -export type IdentityType = { - proto?: string; - user?: string; - host?: string; - port?: string; - path?: string; - index?: number; -}; - -// SignIdentity -export type SignIdentity = { - identity: IdentityType; - challenge_hidden?: string; - challenge_visual?: string; - ecdsa_curve_name?: string; -}; - -// SignedIdentity -export type SignedIdentity = { - address: string; - public_key: string; - signature: string; -}; - -// GetECDHSessionKey -export type GetECDHSessionKey = { - identity: IdentityType; - peer_public_key: string; - ecdsa_curve_name?: string; -}; - -// ECDHSessionKey -export type ECDHSessionKey = { - session_key: string; - public_key?: string; -}; - -export enum DebugButton { - NO = 0, - YES = 1, - INFO = 2, -} - -export enum DebugPhysicalButton { - LEFT_BTN = 0, - MIDDLE_BTN = 1, - RIGHT_BTN = 2, -} - -// DebugLinkResetDebugEvents -export type DebugLinkResetDebugEvents = {}; - -// EosGetPublicKey -export type EosGetPublicKey = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// EosPublicKey -export type EosPublicKey = { - wif_public_key: string; - raw_public_key: string; -}; - -export type EosTxHeader = { - expiration: number; - ref_block_num: number; - ref_block_prefix: number; - max_net_usage_words: number; - max_cpu_usage_ms: number; - delay_sec: number; -}; - -// EosSignTx -export type EosSignTx = { - address_n: number[]; - chain_id: string; - header: EosTxHeader; - num_actions: number; - chunkify?: boolean; -}; - -// EosTxActionRequest -export type EosTxActionRequest = { - data_size?: number; -}; - -export type EosAsset = { - amount: UintType; - symbol: string; -}; - -export type EosPermissionLevel = { - actor: string; - permission: string; -}; - -export type EosAuthorizationKey = { - type?: number; - key: string; - address_n?: number[]; - weight: number; -}; - -export type EosAuthorizationAccount = { - account: EosPermissionLevel; - weight: number; -}; - -export type EosAuthorizationWait = { - wait_sec: number; - weight: number; -}; - -export type EosAuthorization = { - threshold: number; - keys: EosAuthorizationKey[]; - accounts: EosAuthorizationAccount[]; - waits: EosAuthorizationWait[]; -}; - -export type EosActionCommon = { - account: string; - name: string; - authorization: EosPermissionLevel[]; -}; - -export type EosActionTransfer = { - sender: string; - receiver: string; - quantity: EosAsset; - memo: string; -}; - -export type EosActionDelegate = { - sender: string; - receiver: string; - net_quantity: EosAsset; - cpu_quantity: EosAsset; - transfer: boolean; -}; - -export type EosActionUndelegate = { - sender: string; - receiver: string; - net_quantity: EosAsset; - cpu_quantity: EosAsset; -}; - -export type EosActionRefund = { - owner: string; -}; - -export type EosActionBuyRam = { - payer: string; - receiver: string; - quantity: EosAsset; -}; - -export type EosActionBuyRamBytes = { - payer: string; - receiver: string; - bytes: number; -}; - -export type EosActionSellRam = { - account: string; - bytes: number; -}; - -export type EosActionVoteProducer = { - voter: string; - proxy: string; - producers: string[]; -}; - -export type EosActionUpdateAuth = { - account: string; - permission: string; - parent: string; - auth: EosAuthorization; -}; - -export type EosActionDeleteAuth = { - account: string; - permission: string; -}; - -export type EosActionLinkAuth = { - account: string; - code: string; - type: string; - requirement: string; -}; - -export type EosActionUnlinkAuth = { - account: string; - code: string; - type: string; -}; - -export type EosActionNewAccount = { - creator: string; - name: string; - owner: EosAuthorization; - active: EosAuthorization; -}; - -export type EosActionUnknown = { - data_size: number; - data_chunk: string; -}; - -// EosTxActionAck -export type EosTxActionAck = { - common: EosActionCommon; - transfer?: EosActionTransfer; - delegate?: EosActionDelegate; - undelegate?: EosActionUndelegate; - refund?: EosActionRefund; - buy_ram?: EosActionBuyRam; - buy_ram_bytes?: EosActionBuyRamBytes; - sell_ram?: EosActionSellRam; - vote_producer?: EosActionVoteProducer; - update_auth?: EosActionUpdateAuth; - delete_auth?: EosActionDeleteAuth; - link_auth?: EosActionLinkAuth; - unlink_auth?: EosActionUnlinkAuth; - new_account?: EosActionNewAccount; - unknown?: EosActionUnknown; -}; - -// EosSignedTx -export type EosSignedTx = { - signature: string; -}; - -export enum EthereumDefinitionType { - NETWORK = 0, - TOKEN = 1, -} - -// EthereumNetworkInfo -export type EthereumNetworkInfo = { - chain_id: number; - symbol: string; - slip44: number; - name: string; -}; - -// EthereumTokenInfo -export type EthereumTokenInfo = { - address: string; - chain_id: number; - symbol: string; - decimals: number; - name: string; -}; - -// EthereumDefinitions -export type EthereumDefinitions = { - encoded_network?: ArrayBuffer; - encoded_token?: ArrayBuffer; -}; - -// EthereumSignTypedData -export type EthereumSignTypedData = { - address_n: number[]; - primary_type: string; - metamask_v4_compat?: boolean; - definitions?: EthereumDefinitions; -}; - -// EthereumTypedDataStructRequest -export type EthereumTypedDataStructRequest = { - name: string; -}; - -export enum EthereumDataType { - UINT = 1, - INT = 2, - BYTES = 3, - STRING = 4, - BOOL = 5, - ADDRESS = 6, - ARRAY = 7, - STRUCT = 8, -} - -export type EthereumFieldType = { - data_type: EthereumDataType; - size?: number; - entry_type?: EthereumFieldType; - struct_name?: string; -}; - -export type EthereumStructMember = { - type: EthereumFieldType; - name: string; -}; - -// EthereumTypedDataStructAck -export type EthereumTypedDataStructAck = { - members: EthereumStructMember[]; -}; - -// EthereumTypedDataValueRequest -export type EthereumTypedDataValueRequest = { - member_path: number[]; -}; - -// EthereumTypedDataValueAck -export type EthereumTypedDataValueAck = { - value: string; -}; - -// EthereumGetPublicKey -export type EthereumGetPublicKey = { - address_n: number[]; - show_display?: boolean; -}; - -// EthereumPublicKey -export type EthereumPublicKey = { - node: HDNodeType; - xpub: string; -}; - -// EthereumGetAddress -export type EthereumGetAddress = { - address_n: number[]; - show_display?: boolean; - encoded_network?: ArrayBuffer; - chunkify?: boolean; -}; - -// EthereumAddress -export type EthereumAddress = { - _old_address?: string; - address: string; -}; - -// EthereumSignTx -export type EthereumSignTx = { - address_n: number[]; - nonce?: string; - gas_price: string; - gas_limit: string; - to?: string; - value?: string; - data_initial_chunk?: string; - data_length?: number; - chain_id: number; - tx_type?: number; - definitions?: EthereumDefinitions; - chunkify?: boolean; -}; - -export type EthereumAccessList = { - address: string; - storage_keys: string[]; -}; - -// EthereumSignTxEIP1559 -export type EthereumSignTxEIP1559 = { - address_n: number[]; - nonce: string; - max_gas_fee: string; - max_priority_fee: string; - gas_limit: string; - to?: string; - value: string; - data_initial_chunk?: string; - data_length: number; - chain_id: number; - access_list: EthereumAccessList[]; - definitions?: EthereumDefinitions; - chunkify?: boolean; -}; - -// EthereumTxRequest -export type EthereumTxRequest = { - data_length?: number; - signature_v?: number; - signature_r?: string; - signature_s?: string; -}; - -// EthereumTxAck -export type EthereumTxAck = { - data_chunk: string; -}; - -// EthereumSignMessage -export type EthereumSignMessage = { - address_n: number[]; - message: string; - encoded_network?: ArrayBuffer; -}; - -// EthereumMessageSignature -export type EthereumMessageSignature = { - signature: string; - address: string; -}; - -// EthereumVerifyMessage -export type EthereumVerifyMessage = { - signature: string; - message: string; - address: string; -}; - -// EthereumSignTypedHash -export type EthereumSignTypedHash = { - address_n: number[]; - domain_separator_hash: string; - message_hash?: string; - encoded_network?: ArrayBuffer; -}; - -// EthereumTypedDataSignature -export type EthereumTypedDataSignature = { - signature: string; - address: string; -}; - -export enum Enum_BackupType { - Bip39 = 0, - Slip39_Basic = 1, - Slip39_Advanced = 2, -} - -export type BackupType = keyof typeof Enum_BackupType; - -export enum Enum_SafetyCheckLevel { - Strict = 0, - PromptAlways = 1, - PromptTemporarily = 2, -} - -export type SafetyCheckLevel = keyof typeof Enum_SafetyCheckLevel; - -export enum Enum_HomescreenFormat { - Toif = 1, - Jpeg = 2, - ToiG = 3, -} - -export type HomescreenFormat = keyof typeof Enum_HomescreenFormat; - -// Initialize -export type Initialize = { - session_id?: string; - _skip_passphrase?: boolean; - derive_cardano?: boolean; -}; - -// GetFeatures -export type GetFeatures = {}; - -export enum Enum_Capability { - Capability_Bitcoin = 1, - Capability_Bitcoin_like = 2, - Capability_Binance = 3, - Capability_Cardano = 4, - Capability_Crypto = 5, - Capability_EOS = 6, - Capability_Ethereum = 7, - Capability_Lisk = 8, - Capability_Monero = 9, - Capability_NEM = 10, - Capability_Ripple = 11, - Capability_Stellar = 12, - Capability_Tezos = 13, - Capability_U2F = 14, - Capability_Shamir = 15, - Capability_ShamirGroups = 16, - Capability_PassphraseEntry = 17, - Capability_Solana = 18, -} - -export type Capability = keyof typeof Enum_Capability; - -// Features -export type Features = { - vendor: string; - major_version: number; - minor_version: number; - patch_version: number; - bootloader_mode: boolean | null; - device_id: string | null; - pin_protection: boolean | null; - passphrase_protection: boolean | null; - language: string | null; - label: string | null; - initialized: boolean | null; - revision: string | null; - bootloader_hash: string | null; - imported: boolean | null; - unlocked: boolean | null; - _passphrase_cached?: boolean; - firmware_present: boolean | null; - needs_backup: boolean | null; - flags: number | null; - model: string; - fw_major: number | null; - fw_minor: number | null; - fw_patch: number | null; - fw_vendor: string | null; - unfinished_backup: boolean | null; - no_backup: boolean | null; - recovery_mode: boolean | null; - capabilities: Capability[]; - backup_type: BackupType | null; - sd_card_present: boolean | null; - sd_protection: boolean | null; - wipe_code_protection: boolean | null; - session_id: string | null; - passphrase_always_on_device: boolean | null; - safety_checks: SafetyCheckLevel | null; - auto_lock_delay_ms: number | null; - display_rotation: number | null; - experimental_features: boolean | null; - busy?: boolean; - homescreen_format?: HomescreenFormat; - hide_passphrase_from_host?: boolean; - internal_model: DeviceModelInternal; - unit_color?: number; - unit_btconly?: boolean; - homescreen_width?: number; - homescreen_height?: number; - bootloader_locked?: boolean; -}; - -// LockDevice -export type LockDevice = {}; - -// SetBusy -export type SetBusy = { - expiry_ms?: number; -}; - -// EndSession -export type EndSession = {}; - -// ApplySettings -export type ApplySettings = { - language?: string; - label?: string; - use_passphrase?: boolean; - homescreen?: string; - _passphrase_source?: number; - auto_lock_delay_ms?: number; - display_rotation?: number; - passphrase_always_on_device?: boolean; - safety_checks?: SafetyCheckLevel; - experimental_features?: boolean; - hide_passphrase_from_host?: boolean; -}; - -// ApplyFlags -export type ApplyFlags = { - flags: number; -}; - -// ChangePin -export type ChangePin = { - remove?: boolean; -}; - -// ChangeWipeCode -export type ChangeWipeCode = { - remove?: boolean; -}; - -export enum SdProtectOperationType { - DISABLE = 0, - ENABLE = 1, - REFRESH = 2, -} - -// SdProtect -export type SdProtect = { - operation: SdProtectOperationType; -}; - -// Ping -export type Ping = { - message?: string; - button_protection?: boolean; -}; - -// Cancel -export type Cancel = {}; - -// GetEntropy -export type GetEntropy = { - size: number; -}; - -// Entropy -export type Entropy = { - entropy: string; -}; - -// GetFirmwareHash -export type GetFirmwareHash = { - challenge?: string; -}; - -// FirmwareHash -export type FirmwareHash = { - hash: string; -}; - -// AuthenticateDevice -export type AuthenticateDevice = { - challenge: string; -}; - -// AuthenticityProof -export type AuthenticityProof = { - certificates: string[]; - signature: string; -}; - -// WipeDevice -export type WipeDevice = {}; - -// ResetDevice -export type ResetDevice = { - display_random?: boolean; - strength?: number; - passphrase_protection?: boolean; - pin_protection?: boolean; - language?: string; - label?: string; - u2f_counter?: number; - skip_backup?: boolean; - no_backup?: boolean; - backup_type?: string | number; -}; - -// BackupDevice -export type BackupDevice = {}; - -// EntropyRequest -export type EntropyRequest = {}; - -// EntropyAck -export type EntropyAck = { - entropy: string; -}; - -export enum RecoveryDeviceType { - RecoveryDeviceType_ScrambledWords = 0, - RecoveryDeviceType_Matrix = 1, -} - -// RecoveryDevice -export type RecoveryDevice = { - word_count?: number; - passphrase_protection?: boolean; - pin_protection?: boolean; - language?: string; - label?: string; - enforce_wordlist?: boolean; - type?: RecoveryDeviceType; - u2f_counter?: number; - dry_run?: boolean; -}; - -export enum Enum_WordRequestType { - WordRequestType_Plain = 0, - WordRequestType_Matrix9 = 1, - WordRequestType_Matrix6 = 2, -} - -export type WordRequestType = keyof typeof Enum_WordRequestType; - -// WordRequest -export type WordRequest = { - type: WordRequestType; -}; - -// WordAck -export type WordAck = { - word: string; -}; - -// SetU2FCounter -export type SetU2FCounter = { - u2f_counter: number; -}; - -// GetNextU2FCounter -export type GetNextU2FCounter = {}; - -// NextU2FCounter -export type NextU2FCounter = { - u2f_counter: number; -}; - -// DoPreauthorized -export type DoPreauthorized = {}; - -// PreauthorizedRequest -export type PreauthorizedRequest = {}; - -// CancelAuthorization -export type CancelAuthorization = {}; - -// RebootToBootloader -export type RebootToBootloader = {}; - -// GetNonce -export type GetNonce = {}; - -// Nonce -export type Nonce = { - nonce: string; -}; - -// UnlockPath -export type UnlockPath = { - address_n: number[]; - mac?: string; -}; - -// UnlockedPathRequest -export type UnlockedPathRequest = { - mac?: string; -}; - -// ShowDeviceTutorial -export type ShowDeviceTutorial = {}; - -// UnlockBootloader -export type UnlockBootloader = {}; - -export enum MoneroNetworkType { - MAINNET = 0, - TESTNET = 1, - STAGENET = 2, - FAKECHAIN = 3, -} - -// NEMGetAddress -export type NEMGetAddress = { - address_n: number[]; - network?: number; - show_display?: boolean; - chunkify?: boolean; -}; - -// NEMAddress -export type NEMAddress = { - address: string; -}; - -export type NEMTransactionCommon = { - address_n?: number[]; - network?: number; - timestamp: number; - fee: UintType; - deadline: number; - signer?: string; -}; - -export type NEMMosaic = { - namespace: string; - mosaic: string; - quantity: number; -}; - -export type NEMTransfer = { - recipient: string; - amount: UintType; - payload?: string; - public_key?: string; - mosaics?: NEMMosaic[]; -}; - -export type NEMProvisionNamespace = { - namespace: string; - parent?: string; - sink: string; - fee: UintType; -}; - -export enum NEMMosaicLevy { - MosaicLevy_Absolute = 1, - MosaicLevy_Percentile = 2, -} - -export type NEMMosaicDefinition = { - name?: string; - ticker?: string; - namespace: string; - mosaic: string; - divisibility?: number; - levy?: NEMMosaicLevy; - fee?: UintType; - levy_address?: string; - levy_namespace?: string; - levy_mosaic?: string; - supply?: number; - mutable_supply?: boolean; - transferable?: boolean; - description: string; - networks?: number[]; -}; - -export type NEMMosaicCreation = { - definition: NEMMosaicDefinition; - sink: string; - fee: UintType; -}; - -export enum NEMSupplyChangeType { - SupplyChange_Increase = 1, - SupplyChange_Decrease = 2, -} - -export type NEMMosaicSupplyChange = { - namespace: string; - mosaic: string; - type: NEMSupplyChangeType; - delta: number; -}; - -export enum NEMModificationType { - CosignatoryModification_Add = 1, - CosignatoryModification_Delete = 2, -} - -export type NEMCosignatoryModification = { - type: NEMModificationType; - public_key: string; -}; - -export type NEMAggregateModification = { - modifications?: NEMCosignatoryModification[]; - relative_change?: number; -}; - -export enum NEMImportanceTransferMode { - ImportanceTransfer_Activate = 1, - ImportanceTransfer_Deactivate = 2, -} - -export type NEMImportanceTransfer = { - mode: NEMImportanceTransferMode; - public_key: string; -}; - -// NEMSignTx -export type NEMSignTx = { - transaction: NEMTransactionCommon; - multisig?: NEMTransactionCommon; - transfer?: NEMTransfer; - cosigning?: boolean; - provision_namespace?: NEMProvisionNamespace; - mosaic_creation?: NEMMosaicCreation; - supply_change?: NEMMosaicSupplyChange; - aggregate_modification?: NEMAggregateModification; - importance_transfer?: NEMImportanceTransfer; - chunkify?: boolean; -}; - -// NEMSignedTx -export type NEMSignedTx = { - data: string; - signature: string; -}; - -// NEMDecryptMessage -export type NEMDecryptMessage = { - address_n: number[]; - network?: number; - public_key?: string; - payload?: string; -}; - -// NEMDecryptedMessage -export type NEMDecryptedMessage = { - payload: string; -}; - -// RippleGetAddress -export type RippleGetAddress = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// RippleAddress -export type RippleAddress = { - address: string; -}; - -export type RipplePayment = { - amount: UintType; - destination: string; - destination_tag?: number; -}; - -// RippleSignTx -export type RippleSignTx = { - address_n: number[]; - fee: UintType; - flags?: number; - sequence: number; - last_ledger_sequence?: number; - payment: RipplePayment; - chunkify?: boolean; -}; - -// RippleSignedTx -export type RippleSignedTx = { - signature: string; - serialized_tx: string; -}; - -// SolanaGetPublicKey -export type SolanaGetPublicKey = { - address_n: number[]; - show_display?: boolean; -}; - -// SolanaPublicKey -export type SolanaPublicKey = { - public_key: string; -}; - -// SolanaGetAddress -export type SolanaGetAddress = { - address_n: number[]; - show_display?: boolean; -}; - -// SolanaAddress -export type SolanaAddress = { - address: string; -}; - -// SolanaSignTx -export type SolanaSignTx = { - address_n: number[]; - serialized_tx: string; -}; - -// SolanaTxSignature -export type SolanaTxSignature = { - signature: string; -}; - -export enum StellarAssetType { - NATIVE = 0, - ALPHANUM4 = 1, - ALPHANUM12 = 2, -} - -// StellarAsset -export type StellarAsset = { - type: StellarAssetType; - code?: string; - issuer?: string; -}; - -// StellarGetAddress -export type StellarGetAddress = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// StellarAddress -export type StellarAddress = { - address: string; -}; - -export enum StellarMemoType { - NONE = 0, - TEXT = 1, - ID = 2, - HASH = 3, - RETURN = 4, -} - -// StellarSignTx -export type StellarSignTx = { - address_n: number[]; - network_passphrase: string; - source_account: string; - fee: UintType; - sequence_number: UintType; - timebounds_start: number; - timebounds_end: number; - memo_type: StellarMemoType; - memo_text?: string; - memo_id?: string; - memo_hash?: Buffer | string; - num_operations: number; -}; - -// StellarTxOpRequest -export type StellarTxOpRequest = {}; - -// StellarPaymentOp -export type StellarPaymentOp = { - source_account?: string; - destination_account: string; - asset: StellarAsset; - amount: UintType; -}; - -// StellarCreateAccountOp -export type StellarCreateAccountOp = { - source_account?: string; - new_account: string; - starting_balance: UintType; -}; - -// StellarPathPaymentStrictReceiveOp -export type StellarPathPaymentStrictReceiveOp = { - source_account?: string; - send_asset: StellarAsset; - send_max: UintType; - destination_account: string; - destination_asset: StellarAsset; - destination_amount: UintType; - paths?: StellarAsset[]; -}; - -// StellarPathPaymentStrictSendOp -export type StellarPathPaymentStrictSendOp = { - source_account?: string; - send_asset: StellarAsset; - send_amount: UintType; - destination_account: string; - destination_asset: StellarAsset; - destination_min: UintType; - paths?: StellarAsset[]; -}; - -// StellarManageSellOfferOp -export type StellarManageSellOfferOp = { - source_account?: string; - selling_asset: StellarAsset; - buying_asset: StellarAsset; - amount: UintType; - price_n: number; - price_d: number; - offer_id: UintType; -}; - -// StellarManageBuyOfferOp -export type StellarManageBuyOfferOp = { - source_account?: string; - selling_asset: StellarAsset; - buying_asset: StellarAsset; - amount: UintType; - price_n: number; - price_d: number; - offer_id: UintType; -}; - -// StellarCreatePassiveSellOfferOp -export type StellarCreatePassiveSellOfferOp = { - source_account?: string; - selling_asset: StellarAsset; - buying_asset: StellarAsset; - amount: UintType; - price_n: number; - price_d: number; -}; - -export enum StellarSignerType { - ACCOUNT = 0, - PRE_AUTH = 1, - HASH = 2, -} - -// StellarSetOptionsOp -export type StellarSetOptionsOp = { - source_account?: string; - inflation_destination_account?: string; - clear_flags?: number; - set_flags?: number; - master_weight?: UintType; - low_threshold?: UintType; - medium_threshold?: UintType; - high_threshold?: UintType; - home_domain?: string; - signer_type?: StellarSignerType; - signer_key?: Buffer | string; - signer_weight?: number; -}; - -// StellarChangeTrustOp -export type StellarChangeTrustOp = { - source_account?: string; - asset: StellarAsset; - limit: UintType; -}; - -// StellarAllowTrustOp -export type StellarAllowTrustOp = { - source_account?: string; - trusted_account: string; - asset_type: StellarAssetType; - asset_code?: string; - is_authorized: boolean; -}; - -// StellarAccountMergeOp -export type StellarAccountMergeOp = { - source_account?: string; - destination_account: string; -}; - -// StellarManageDataOp -export type StellarManageDataOp = { - source_account?: string; - key: string; - value?: Buffer | string; -}; - -// StellarBumpSequenceOp -export type StellarBumpSequenceOp = { - source_account?: string; - bump_to: UintType; -}; - -// StellarClaimClaimableBalanceOp -export type StellarClaimClaimableBalanceOp = { - source_account?: string; - balance_id: string; -}; - -// StellarSignedTx -export type StellarSignedTx = { - public_key: string; - signature: string; -}; - -// TezosGetAddress -export type TezosGetAddress = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// TezosAddress -export type TezosAddress = { - address: string; -}; - -// TezosGetPublicKey -export type TezosGetPublicKey = { - address_n: number[]; - show_display?: boolean; - chunkify?: boolean; -}; - -// TezosPublicKey -export type TezosPublicKey = { - public_key: string; -}; - -export enum TezosContractType { - Implicit = 0, - Originated = 1, -} - -export type TezosContractID = { - tag: number; - hash: Uint8Array; -}; - -export type TezosRevealOp = { - source: Uint8Array; - fee: UintType; - counter: number; - gas_limit: number; - storage_limit: number; - public_key: Uint8Array; -}; - -export type TezosManagerTransfer = { - destination: TezosContractID; - amount: UintType; -}; - -export type TezosParametersManager = { - set_delegate?: Uint8Array; - cancel_delegate?: boolean; - transfer?: TezosManagerTransfer; -}; - -export type TezosTransactionOp = { - source: Uint8Array; - fee: UintType; - counter: number; - gas_limit: number; - storage_limit: number; - amount: UintType; - destination: TezosContractID; - parameters?: number[]; - parameters_manager?: TezosParametersManager; -}; - -export type TezosOriginationOp = { - source: Uint8Array; - fee: UintType; - counter: number; - gas_limit: number; - storage_limit: number; - manager_pubkey?: string; - balance: number; - spendable?: boolean; - delegatable?: boolean; - delegate?: Uint8Array; - script: string | number[]; -}; - -export type TezosDelegationOp = { - source: Uint8Array; - fee: UintType; - counter: number; - gas_limit: number; - storage_limit: number; - delegate: Uint8Array; -}; - -export type TezosProposalOp = { - source: string; - period: number; - proposals: string[]; -}; - -export enum TezosBallotType { - Yay = 0, - Nay = 1, - Pass = 2, -} - -export type TezosBallotOp = { - source: string; - period: number; - proposal: string; - ballot: TezosBallotType; -}; - -// TezosSignTx -export type TezosSignTx = { - address_n: number[]; - branch: Uint8Array; - reveal?: TezosRevealOp; - transaction?: TezosTransactionOp; - origination?: TezosOriginationOp; - delegation?: TezosDelegationOp; - proposal?: TezosProposalOp; - ballot?: TezosBallotOp; - chunkify?: boolean; -}; - -// TezosSignedTx -export type TezosSignedTx = { - signature: string; - sig_op_contents: string; - operation_hash: string; -}; - -// experimental_message -export type experimental_message = {}; - -// experimental_field -export type experimental_field = {}; - -// custom connect definitions -export type MessageType = { - BinanceGetAddress: BinanceGetAddress; - BinanceAddress: BinanceAddress; - BinanceGetPublicKey: BinanceGetPublicKey; - BinancePublicKey: BinancePublicKey; - BinanceSignTx: BinanceSignTx; - BinanceTxRequest: BinanceTxRequest; - BinanceCoin: BinanceCoin; - BinanceInputOutput: BinanceInputOutput; - BinanceTransferMsg: BinanceTransferMsg; - BinanceOrderMsg: BinanceOrderMsg; - BinanceCancelMsg: BinanceCancelMsg; - BinanceSignedTx: BinanceSignedTx; - HDNodeType: HDNodeType; - HDNodePathType: HDNodePathType; - MultisigRedeemScriptType: MultisigRedeemScriptType; - GetPublicKey: GetPublicKey; - PublicKey: PublicKey; - GetAddress: GetAddress; - Address: Address; - GetOwnershipId: GetOwnershipId; - OwnershipId: OwnershipId; - SignMessage: SignMessage; - MessageSignature: MessageSignature; - VerifyMessage: VerifyMessage; - CoinJoinRequest: CoinJoinRequest; - SignTx: SignTx; - TxRequestDetailsType: TxRequestDetailsType; - TxRequestSerializedType: TxRequestSerializedType; - TxRequest: TxRequest; - TxInputType: TxInputType; - TxOutputBinType: TxOutputBinType; - TxOutputType: TxOutputType; - PrevTx: PrevTx; - PrevInput: PrevInput; - PrevOutput: PrevOutput; - TextMemo: TextMemo; - RefundMemo: RefundMemo; - CoinPurchaseMemo: CoinPurchaseMemo; - PaymentRequestMemo: PaymentRequestMemo; - TxAckPaymentRequest: TxAckPaymentRequest; - TxAck: TxAck; - TxAckInputWrapper: TxAckInputWrapper; - TxAckInput: TxAckInput; - TxAckOutputWrapper: TxAckOutputWrapper; - TxAckOutput: TxAckOutput; - TxAckPrevMeta: TxAckPrevMeta; - TxAckPrevInputWrapper: TxAckPrevInputWrapper; - TxAckPrevInput: TxAckPrevInput; - TxAckPrevOutputWrapper: TxAckPrevOutputWrapper; - TxAckPrevOutput: TxAckPrevOutput; - TxAckPrevExtraDataWrapper: TxAckPrevExtraDataWrapper; - TxAckPrevExtraData: TxAckPrevExtraData; - GetOwnershipProof: GetOwnershipProof; - OwnershipProof: OwnershipProof; - AuthorizeCoinJoin: AuthorizeCoinJoin; - FirmwareErase: FirmwareErase; - FirmwareRequest: FirmwareRequest; - FirmwareUpload: FirmwareUpload; - SelfTest: SelfTest; - CardanoBlockchainPointerType: CardanoBlockchainPointerType; - CardanoNativeScript: CardanoNativeScript; - CardanoGetNativeScriptHash: CardanoGetNativeScriptHash; - CardanoNativeScriptHash: CardanoNativeScriptHash; - CardanoAddressParametersType: CardanoAddressParametersType; - CardanoGetAddress: CardanoGetAddress; - CardanoAddress: CardanoAddress; - CardanoGetPublicKey: CardanoGetPublicKey; - CardanoPublicKey: CardanoPublicKey; - CardanoSignTxInit: CardanoSignTxInit; - CardanoTxInput: CardanoTxInput; - CardanoTxOutput: CardanoTxOutput; - CardanoAssetGroup: CardanoAssetGroup; - CardanoToken: CardanoToken; - CardanoTxInlineDatumChunk: CardanoTxInlineDatumChunk; - CardanoTxReferenceScriptChunk: CardanoTxReferenceScriptChunk; - CardanoPoolOwner: CardanoPoolOwner; - CardanoPoolRelayParameters: CardanoPoolRelayParameters; - CardanoPoolMetadataType: CardanoPoolMetadataType; - CardanoPoolParametersType: CardanoPoolParametersType; - CardanoTxCertificate: CardanoTxCertificate; - CardanoTxWithdrawal: CardanoTxWithdrawal; - CardanoCVoteRegistrationDelegation: CardanoCVoteRegistrationDelegation; - CardanoCVoteRegistrationParametersType: CardanoCVoteRegistrationParametersType; - CardanoTxAuxiliaryData: CardanoTxAuxiliaryData; - CardanoTxMint: CardanoTxMint; - CardanoTxCollateralInput: CardanoTxCollateralInput; - CardanoTxRequiredSigner: CardanoTxRequiredSigner; - CardanoTxReferenceInput: CardanoTxReferenceInput; - CardanoTxItemAck: CardanoTxItemAck; - CardanoTxAuxiliaryDataSupplement: CardanoTxAuxiliaryDataSupplement; - CardanoTxWitnessRequest: CardanoTxWitnessRequest; - CardanoTxWitnessResponse: CardanoTxWitnessResponse; - CardanoTxHostAck: CardanoTxHostAck; - CardanoTxBodyHash: CardanoTxBodyHash; - CardanoSignTxFinished: CardanoSignTxFinished; - Success: Success; - Failure: Failure; - ButtonRequest: ButtonRequest; - ButtonAck: ButtonAck; - PinMatrixRequest: PinMatrixRequest; - PinMatrixAck: PinMatrixAck; - PassphraseRequest: PassphraseRequest; - PassphraseAck: PassphraseAck; - Deprecated_PassphraseStateRequest: Deprecated_PassphraseStateRequest; - Deprecated_PassphraseStateAck: Deprecated_PassphraseStateAck; - CipherKeyValue: CipherKeyValue; - CipheredKeyValue: CipheredKeyValue; - IdentityType: IdentityType; - SignIdentity: SignIdentity; - SignedIdentity: SignedIdentity; - GetECDHSessionKey: GetECDHSessionKey; - ECDHSessionKey: ECDHSessionKey; - DebugLinkResetDebugEvents: DebugLinkResetDebugEvents; - EosGetPublicKey: EosGetPublicKey; - EosPublicKey: EosPublicKey; - EosTxHeader: EosTxHeader; - EosSignTx: EosSignTx; - EosTxActionRequest: EosTxActionRequest; - EosAsset: EosAsset; - EosPermissionLevel: EosPermissionLevel; - EosAuthorizationKey: EosAuthorizationKey; - EosAuthorizationAccount: EosAuthorizationAccount; - EosAuthorizationWait: EosAuthorizationWait; - EosAuthorization: EosAuthorization; - EosActionCommon: EosActionCommon; - EosActionTransfer: EosActionTransfer; - EosActionDelegate: EosActionDelegate; - EosActionUndelegate: EosActionUndelegate; - EosActionRefund: EosActionRefund; - EosActionBuyRam: EosActionBuyRam; - EosActionBuyRamBytes: EosActionBuyRamBytes; - EosActionSellRam: EosActionSellRam; - EosActionVoteProducer: EosActionVoteProducer; - EosActionUpdateAuth: EosActionUpdateAuth; - EosActionDeleteAuth: EosActionDeleteAuth; - EosActionLinkAuth: EosActionLinkAuth; - EosActionUnlinkAuth: EosActionUnlinkAuth; - EosActionNewAccount: EosActionNewAccount; - EosActionUnknown: EosActionUnknown; - EosTxActionAck: EosTxActionAck; - EosSignedTx: EosSignedTx; - EthereumNetworkInfo: EthereumNetworkInfo; - EthereumTokenInfo: EthereumTokenInfo; - EthereumDefinitions: EthereumDefinitions; - EthereumSignTypedData: EthereumSignTypedData; - EthereumTypedDataStructRequest: EthereumTypedDataStructRequest; - EthereumFieldType: EthereumFieldType; - EthereumStructMember: EthereumStructMember; - EthereumTypedDataStructAck: EthereumTypedDataStructAck; - EthereumTypedDataValueRequest: EthereumTypedDataValueRequest; - EthereumTypedDataValueAck: EthereumTypedDataValueAck; - EthereumGetPublicKey: EthereumGetPublicKey; - EthereumPublicKey: EthereumPublicKey; - EthereumGetAddress: EthereumGetAddress; - EthereumAddress: EthereumAddress; - EthereumSignTx: EthereumSignTx; - EthereumAccessList: EthereumAccessList; - EthereumSignTxEIP1559: EthereumSignTxEIP1559; - EthereumTxRequest: EthereumTxRequest; - EthereumTxAck: EthereumTxAck; - EthereumSignMessage: EthereumSignMessage; - EthereumMessageSignature: EthereumMessageSignature; - EthereumVerifyMessage: EthereumVerifyMessage; - EthereumSignTypedHash: EthereumSignTypedHash; - EthereumTypedDataSignature: EthereumTypedDataSignature; - Initialize: Initialize; - GetFeatures: GetFeatures; - Features: Features; - LockDevice: LockDevice; - SetBusy: SetBusy; - EndSession: EndSession; - ApplySettings: ApplySettings; - ApplyFlags: ApplyFlags; - ChangePin: ChangePin; - ChangeWipeCode: ChangeWipeCode; - SdProtect: SdProtect; - Ping: Ping; - Cancel: Cancel; - GetEntropy: GetEntropy; - Entropy: Entropy; - GetFirmwareHash: GetFirmwareHash; - FirmwareHash: FirmwareHash; - AuthenticateDevice: AuthenticateDevice; - AuthenticityProof: AuthenticityProof; - WipeDevice: WipeDevice; - ResetDevice: ResetDevice; - BackupDevice: BackupDevice; - EntropyRequest: EntropyRequest; - EntropyAck: EntropyAck; - RecoveryDevice: RecoveryDevice; - WordRequest: WordRequest; - WordAck: WordAck; - SetU2FCounter: SetU2FCounter; - GetNextU2FCounter: GetNextU2FCounter; - NextU2FCounter: NextU2FCounter; - DoPreauthorized: DoPreauthorized; - PreauthorizedRequest: PreauthorizedRequest; - CancelAuthorization: CancelAuthorization; - RebootToBootloader: RebootToBootloader; - GetNonce: GetNonce; - Nonce: Nonce; - UnlockPath: UnlockPath; - UnlockedPathRequest: UnlockedPathRequest; - ShowDeviceTutorial: ShowDeviceTutorial; - UnlockBootloader: UnlockBootloader; - NEMGetAddress: NEMGetAddress; - NEMAddress: NEMAddress; - NEMTransactionCommon: NEMTransactionCommon; - NEMMosaic: NEMMosaic; - NEMTransfer: NEMTransfer; - NEMProvisionNamespace: NEMProvisionNamespace; - NEMMosaicDefinition: NEMMosaicDefinition; - NEMMosaicCreation: NEMMosaicCreation; - NEMMosaicSupplyChange: NEMMosaicSupplyChange; - NEMCosignatoryModification: NEMCosignatoryModification; - NEMAggregateModification: NEMAggregateModification; - NEMImportanceTransfer: NEMImportanceTransfer; - NEMSignTx: NEMSignTx; - NEMSignedTx: NEMSignedTx; - NEMDecryptMessage: NEMDecryptMessage; - NEMDecryptedMessage: NEMDecryptedMessage; - RippleGetAddress: RippleGetAddress; - RippleAddress: RippleAddress; - RipplePayment: RipplePayment; - RippleSignTx: RippleSignTx; - RippleSignedTx: RippleSignedTx; - SolanaGetPublicKey: SolanaGetPublicKey; - SolanaPublicKey: SolanaPublicKey; - SolanaGetAddress: SolanaGetAddress; - SolanaAddress: SolanaAddress; - SolanaSignTx: SolanaSignTx; - SolanaTxSignature: SolanaTxSignature; - StellarAsset: StellarAsset; - StellarGetAddress: StellarGetAddress; - StellarAddress: StellarAddress; - StellarSignTx: StellarSignTx; - StellarTxOpRequest: StellarTxOpRequest; - StellarPaymentOp: StellarPaymentOp; - StellarCreateAccountOp: StellarCreateAccountOp; - StellarPathPaymentStrictReceiveOp: StellarPathPaymentStrictReceiveOp; - StellarPathPaymentStrictSendOp: StellarPathPaymentStrictSendOp; - StellarManageSellOfferOp: StellarManageSellOfferOp; - StellarManageBuyOfferOp: StellarManageBuyOfferOp; - StellarCreatePassiveSellOfferOp: StellarCreatePassiveSellOfferOp; - StellarSetOptionsOp: StellarSetOptionsOp; - StellarChangeTrustOp: StellarChangeTrustOp; - StellarAllowTrustOp: StellarAllowTrustOp; - StellarAccountMergeOp: StellarAccountMergeOp; - StellarManageDataOp: StellarManageDataOp; - StellarBumpSequenceOp: StellarBumpSequenceOp; - StellarClaimClaimableBalanceOp: StellarClaimClaimableBalanceOp; - StellarSignedTx: StellarSignedTx; - TezosGetAddress: TezosGetAddress; - TezosAddress: TezosAddress; - TezosGetPublicKey: TezosGetPublicKey; - TezosPublicKey: TezosPublicKey; - TezosContractID: TezosContractID; - TezosRevealOp: TezosRevealOp; - TezosManagerTransfer: TezosManagerTransfer; - TezosParametersManager: TezosParametersManager; - TezosTransactionOp: TezosTransactionOp; - TezosOriginationOp: TezosOriginationOp; - TezosDelegationOp: TezosDelegationOp; - TezosProposalOp: TezosProposalOp; - TezosBallotOp: TezosBallotOp; - TezosSignTx: TezosSignTx; - TezosSignedTx: TezosSignedTx; - experimental_message: experimental_message; - experimental_field: experimental_field; -}; - -export type MessageKey = keyof MessageType; - -export type MessageResponse = { - type: T; - message: MessageType[T]; -}; - -export type TypedCall = ( - type: T, - resType: R, - message?: MessageType[T], -) => Promise>; diff --git a/packages/schema-utils/tests/__snapshots__/codegen.test.ts.snap b/packages/schema-utils/tests/__snapshots__/codegen.test.ts.snap deleted file mode 100644 index ae707e53e6..0000000000 --- a/packages/schema-utils/tests/__snapshots__/codegen.test.ts.snap +++ /dev/null @@ -1,2754 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`codegen should generate code for protobuf messages example 1`] = ` -"/* eslint-disable camelcase */ -import { Type, Static, TypeClone } from '@trezor/schema-utils'; - - -export type Type.Uint() = Static -export const Type.Uint() = Type.Union([ -Type.String(), -Type.Number() -], {"$id":"Type.Uint()"}) - -export enum DeviceModelInternal { T1B1 = 'T1B1', T2T1 = 'T2T1', T2B1 = 'T2B1' } - -export type EnumDeviceModelInternal = Static -export const EnumDeviceModelInternal = Type.Enum(DeviceModelInternal) - -export type BinanceGetAddress = Static -export const BinanceGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"BinanceGetAddress"}) - -export type BinanceAddress = Static -export const BinanceAddress = Type.Object({ -address: Type.String() -}, {"$id":"BinanceAddress"}) - -export type BinanceGetPublicKey = Static -export const BinanceGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()) -}, {"$id":"BinanceGetPublicKey"}) - -export type BinancePublicKey = Static -export const BinancePublicKey = Type.Object({ -public_key: Type.String() -}, {"$id":"BinancePublicKey"}) - -export type BinanceSignTx = Static -export const BinanceSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -msg_count: Type.Number(), -account_number: Type.Number(), -chain_id: Type.Optional(Type.String()), -memo: Type.Optional(Type.String()), -sequence: Type.Number(), -source: Type.Number(), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"BinanceSignTx"}) - -export type BinanceTxRequest = Static -export const BinanceTxRequest = Type.Object({ - -}, {"$id":"BinanceTxRequest"}) - -export type BinanceCoin = Static -export const BinanceCoin = Type.Object({ -amount: Type.Uint(), -denom: Type.String() -}, {"$id":"BinanceCoin"}) - -export type BinanceInputOutput = Static -export const BinanceInputOutput = Type.Object({ -address: Type.String(), -coins: Type.Array(BinanceCoin) -}, {"$id":"BinanceInputOutput"}) - -export type BinanceTransferMsg = Static -export const BinanceTransferMsg = Type.Object({ -inputs: Type.Array(BinanceInputOutput), -outputs: Type.Array(BinanceInputOutput), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"BinanceTransferMsg"}) - -export enum BinanceOrderType { OT_UNKNOWN = 0, MARKET = 1, LIMIT = 2, OT_RESERVED = 3 } - -export type EnumBinanceOrderType = Static -export const EnumBinanceOrderType = Type.Enum(BinanceOrderType) - -export enum BinanceOrderSide { SIDE_UNKNOWN = 0, BUY = 1, SELL = 2 } - -export type EnumBinanceOrderSide = Static -export const EnumBinanceOrderSide = Type.Enum(BinanceOrderSide) - -export enum BinanceTimeInForce { TIF_UNKNOWN = 0, GTE = 1, TIF_RESERVED = 2, IOC = 3 } - -export type EnumBinanceTimeInForce = Static -export const EnumBinanceTimeInForce = Type.Enum(BinanceTimeInForce) - -export type BinanceOrderMsg = Static -export const BinanceOrderMsg = Type.Object({ -id: Type.Optional(Type.String()), -ordertype: EnumBinanceOrderType, -price: Type.Number(), -quantity: Type.Number(), -sender: Type.Optional(Type.String()), -side: EnumBinanceOrderSide, -symbol: Type.Optional(Type.String()), -timeinforce: EnumBinanceTimeInForce -}, {"$id":"BinanceOrderMsg"}) - -export type BinanceCancelMsg = Static -export const BinanceCancelMsg = Type.Object({ -refid: Type.Optional(Type.String()), -sender: Type.Optional(Type.String()), -symbol: Type.Optional(Type.String()) -}, {"$id":"BinanceCancelMsg"}) - -export type BinanceSignedTx = Static -export const BinanceSignedTx = Type.Object({ -signature: Type.String(), -public_key: Type.String() -}, {"$id":"BinanceSignedTx"}) - -export enum Enum_InputScriptType { SPENDADDRESS = 0, SPENDMULTISIG = 1, EXTERNAL = 2, SPENDWITNESS = 3, SPENDP2SHWITNESS = 4, SPENDTAPROOT = 5 } - -export type EnumEnum_InputScriptType = Static -export const EnumEnum_InputScriptType = Type.Enum(Enum_InputScriptType) - -export type InputScriptType = Static -export const InputScriptType = Type.KeyOfEnum(Enum_InputScriptType, {"$id":"InputScriptType"}) - -export enum Enum_OutputScriptType { PAYTOADDRESS = 0, PAYTOSCRIPTHASH = 1, PAYTOMULTISIG = 2, PAYTOOPRETURN = 3, PAYTOWITNESS = 4, PAYTOP2SHWITNESS = 5, PAYTOTAPROOT = 6 } - -export type EnumEnum_OutputScriptType = Static -export const EnumEnum_OutputScriptType = Type.Enum(Enum_OutputScriptType) - -export type OutputScriptType = Static -export const OutputScriptType = Type.KeyOfEnum(Enum_OutputScriptType, {"$id":"OutputScriptType"}) - -export enum DecredStakingSpendType { SSGen = 0, SSRTX = 1 } - -export type EnumDecredStakingSpendType = Static -export const EnumDecredStakingSpendType = Type.Enum(DecredStakingSpendType) - -export enum AmountUnit { BITCOIN = 0, MILLIBITCOIN = 1, MICROBITCOIN = 2, SATOSHI = 3 } - -export type EnumAmountUnit = Static -export const EnumAmountUnit = Type.Enum(AmountUnit) - -export type HDNodeType = Static -export const HDNodeType = Type.Object({ -depth: Type.Number(), -fingerprint: Type.Number(), -child_num: Type.Number(), -chain_code: Type.String(), -private_key: Type.Optional(Type.String()), -public_key: Type.String() -}, {"$id":"HDNodeType"}) - -export type HDNodePathType = Static -export const HDNodePathType = Type.Object({ -node: Type.Union([ -HDNodeType, -Type.String() -]), -address_n: Type.Array(Type.Number()) -}, {"$id":"HDNodePathType"}) - -export type MultisigRedeemScriptType = Static -export const MultisigRedeemScriptType = Type.Object({ -pubkeys: Type.Array(HDNodePathType), -signatures: Type.Array(Type.String()), -m: Type.Number(), -nodes: Type.Optional(Type.Array(HDNodeType)), -address_n: Type.Optional(Type.Array(Type.Number())) -}, {"$id":"MultisigRedeemScriptType"}) - -export type GetPublicKey = Static -export const GetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -ecdsa_curve_name: Type.Optional(Type.String()), -show_display: Type.Optional(Type.Boolean()), -coin_name: Type.Optional(Type.String()), -script_type: Type.Optional(InputScriptType), -ignore_xpub_magic: Type.Optional(Type.Boolean()) -}, {"$id":"GetPublicKey"}) - -export type PublicKey = Static -export const PublicKey = Type.Object({ -node: HDNodeType, -xpub: Type.String(), -root_fingerprint: Type.Optional(Type.Number()) -}, {"$id":"PublicKey"}) - -export type GetAddress = Static -export const GetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -coin_name: Type.Optional(Type.String()), -show_display: Type.Optional(Type.Boolean()), -multisig: Type.Optional(MultisigRedeemScriptType), -script_type: Type.Optional(InputScriptType), -ignore_xpub_magic: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"GetAddress"}) - -export type Address = Static -export const Address = Type.Object({ -address: Type.String(), -mac: Type.Optional(Type.String()) -}, {"$id":"Address"}) - -export type GetOwnershipId = Static -export const GetOwnershipId = Type.Object({ -address_n: Type.Array(Type.Number()), -coin_name: Type.Optional(Type.String()), -multisig: Type.Optional(MultisigRedeemScriptType), -script_type: Type.Optional(InputScriptType) -}, {"$id":"GetOwnershipId"}) - -export type OwnershipId = Static -export const OwnershipId = Type.Object({ -ownership_id: Type.String() -}, {"$id":"OwnershipId"}) - -export type SignMessage = Static -export const SignMessage = Type.Object({ -address_n: Type.Array(Type.Number()), -message: Type.String(), -coin_name: Type.Optional(Type.String()), -script_type: Type.Optional(InputScriptType), -no_script_type: Type.Optional(Type.Boolean()) -}, {"$id":"SignMessage"}) - -export type MessageSignature = Static -export const MessageSignature = Type.Object({ -address: Type.String(), -signature: Type.String() -}, {"$id":"MessageSignature"}) - -export type VerifyMessage = Static -export const VerifyMessage = Type.Object({ -address: Type.String(), -signature: Type.String(), -message: Type.String(), -coin_name: Type.Optional(Type.String()) -}, {"$id":"VerifyMessage"}) - -export type CoinJoinRequest = Static -export const CoinJoinRequest = Type.Object({ -fee_rate: Type.Number(), -no_fee_threshold: Type.Number(), -min_registrable_amount: Type.Number(), -mask_public_key: Type.String(), -signature: Type.String() -}, {"$id":"CoinJoinRequest"}) - -export type SignTx = Static -export const SignTx = Type.Object({ -outputs_count: Type.Number(), -inputs_count: Type.Number(), -coin_name: Type.Optional(Type.String()), -version: Type.Optional(Type.Number()), -lock_time: Type.Optional(Type.Number()), -expiry: Type.Optional(Type.Number()), -overwintered: Type.Optional(Type.Boolean()), -version_group_id: Type.Optional(Type.Number()), -timestamp: Type.Optional(Type.Number()), -branch_id: Type.Optional(Type.Number()), -amount_unit: Type.Optional(EnumAmountUnit), -decred_staking_ticket: Type.Optional(Type.Boolean()), -serialize: Type.Optional(Type.Boolean()), -coinjoin_request: Type.Optional(CoinJoinRequest), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"SignTx"}) - -export enum Enum_RequestType { TXINPUT = 0, TXOUTPUT = 1, TXMETA = 2, TXFINISHED = 3, TXEXTRADATA = 4, TXORIGINPUT = 5, TXORIGOUTPUT = 6, TXPAYMENTREQ = 7 } - -export type EnumEnum_RequestType = Static -export const EnumEnum_RequestType = Type.Enum(Enum_RequestType) - -export type RequestType = Static -export const RequestType = Type.KeyOfEnum(Enum_RequestType, {"$id":"RequestType"}) - -export type TxRequestDetailsType = Static -export const TxRequestDetailsType = Type.Object({ -request_index: Type.Number(), -tx_hash: Type.Optional(Type.String()), -extra_data_len: Type.Optional(Type.Number()), -extra_data_offset: Type.Optional(Type.Number()) -}, {"$id":"TxRequestDetailsType"}) - -export type TxRequestSerializedType = Static -export const TxRequestSerializedType = Type.Object({ -signature_index: Type.Optional(Type.Number()), -signature: Type.Optional(Type.String()), -serialized_tx: Type.Optional(Type.String()) -}, {"$id":"TxRequestSerializedType"}) - -export type TxRequest = Static -export const TxRequest = Type.Object({ -request_type: RequestType, -details: TxRequestDetailsType, -serialized: Type.Optional(TxRequestSerializedType) -}, {"$id":"TxRequest"}) - -export type InternalInputScriptType = Static -export const InternalInputScriptType = Type.Exclude(InputScriptType, Type.Literal('EXTERNAL'), {"$id":"InternalInputScriptType"}) - -type CommonTxInputType = Static -const CommonTxInputType = Type.Object({ -prev_hash: Type.String(), -prev_index: Type.Number(), -amount: Type.Uint(), -sequence: Type.Optional(Type.Number()), -multisig: Type.Optional(MultisigRedeemScriptType), -decred_tree: Type.Optional(Type.Number()), -orig_hash: Type.Optional(Type.String()), -orig_index: Type.Optional(Type.Number()), -decred_staking_spend: Type.Optional(EnumDecredStakingSpendType), -script_pubkey: Type.Optional(Type.String()), -coinjoin_flags: Type.Optional(Type.Number()), -script_sig: Type.Optional(Type.String()), -witness: Type.Optional(Type.String()), -ownership_proof: Type.Optional(Type.String()), -commitment_data: Type.Optional(Type.String()) -}, {"$id":"CommonTxInputType"}) - -export type TxInputType = Static -export const TxInputType = Type.Union([ -Type.Intersect([ -CommonTxInputType, -Type.Object({ -address_n: Type.Array(Type.Number()), -script_type: Type.Optional(InternalInputScriptType) -}) -]), -Type.Intersect([ -CommonTxInputType, -Type.Object({ -address_n: Type.Optional(Type.Undefined()), -script_type: Type.Literal('EXTERNAL'), -script_pubkey: Type.String() -}) -]) -], {"$id":"TxInputType"}) - -export type TxInput = Static -export const TxInput = TypeClone.Type(TxInputType, {"$id":"TxInput"}) - -export type TxOutputBinType = Static -export const TxOutputBinType = Type.Object({ -amount: Type.Uint(), -script_pubkey: Type.String(), -decred_script_version: Type.Optional(Type.Number()) -}, {"$id":"TxOutputBinType"}) - -export type ChangeOutputScriptType = Static -export const ChangeOutputScriptType = Type.Exclude(OutputScriptType, Type.Literal('PAYTOOPRETURN'), {"$id":"ChangeOutputScriptType"}) - -export type TxOutputType = Static -export const TxOutputType = Type.Union([ -Type.Object({ -address: Type.String(), -address_n: Type.Optional(Type.Undefined()), -script_type: Type.Literal('PAYTOADDRESS'), -amount: Type.Uint(), -multisig: Type.Optional(MultisigRedeemScriptType), -orig_hash: Type.Optional(Type.String()), -orig_index: Type.Optional(Type.Number()), -payment_req_index: Type.Optional(Type.Number()) -}), -Type.Object({ -address: Type.Optional(Type.Undefined()), -address_n: Type.Array(Type.Number()), -script_type: Type.Optional(ChangeOutputScriptType), -amount: Type.Uint(), -multisig: Type.Optional(MultisigRedeemScriptType), -orig_hash: Type.Optional(Type.String()), -orig_index: Type.Optional(Type.Number()), -payment_req_index: Type.Optional(Type.Number()) -}), -Type.Object({ -address: Type.Optional(Type.Undefined()), -address_n: Type.Optional(Type.Undefined()), -amount: Type.Literal('0'), -op_return_data: Type.String(), -script_type: Type.Literal('PAYTOOPRETURN'), -orig_hash: Type.Optional(Type.String()), -orig_index: Type.Optional(Type.Number()), -payment_req_index: Type.Optional(Type.Number()) -}) -], {"$id":"TxOutputType"}) - -export type TxOutput = Static -export const TxOutput = TypeClone.Type(TxOutputType, {"$id":"TxOutput"}) - -export type PrevTx = Static -export const PrevTx = Type.Object({ -version: Type.Number(), -lock_time: Type.Number(), -inputs_count: Type.Number(), -outputs_count: Type.Number(), -extra_data_len: Type.Optional(Type.Number()), -expiry: Type.Optional(Type.Number()), -version_group_id: Type.Optional(Type.Number()), -timestamp: Type.Optional(Type.Number()), -branch_id: Type.Optional(Type.Number()) -}, {"$id":"PrevTx"}) - -export type PrevInput = Static -export const PrevInput = Type.Object({ -prev_hash: Type.String(), -prev_index: Type.Number(), -script_sig: Type.String(), -sequence: Type.Number(), -decred_tree: Type.Optional(Type.Number()) -}, {"$id":"PrevInput"}) - -export type PrevOutput = Static -export const PrevOutput = Type.Object({ -amount: Type.Uint(), -script_pubkey: Type.String(), -decred_script_version: Type.Optional(Type.Number()) -}, {"$id":"PrevOutput"}) - -export type TextMemo = Static -export const TextMemo = Type.Object({ -text: Type.String() -}, {"$id":"TextMemo"}) - -export type RefundMemo = Static -export const RefundMemo = Type.Object({ -address: Type.String(), -mac: Type.String() -}, {"$id":"RefundMemo"}) - -export type CoinPurchaseMemo = Static -export const CoinPurchaseMemo = Type.Object({ -coin_type: Type.Number(), -amount: Type.Uint(), -address: Type.String(), -mac: Type.String() -}, {"$id":"CoinPurchaseMemo"}) - -export type PaymentRequestMemo = Static -export const PaymentRequestMemo = Type.Object({ -text_memo: Type.Optional(TextMemo), -refund_memo: Type.Optional(RefundMemo), -coin_purchase_memo: Type.Optional(CoinPurchaseMemo) -}, {"$id":"PaymentRequestMemo"}) - -export type TxAckPaymentRequest = Static -export const TxAckPaymentRequest = Type.Object({ -nonce: Type.Optional(Type.String()), -recipient_name: Type.String(), -memos: Type.Optional(Type.Array(PaymentRequestMemo)), -amount: Type.Optional(Type.Uint()), -signature: Type.String() -}, {"$id":"TxAckPaymentRequest"}) - -export type TxAckResponse = Static -export const TxAckResponse = Type.Union([ -Type.Object({ -inputs: Type.Array(Type.Union([ -TxInputType, -PrevInput -])) -}), -Type.Object({ -bin_outputs: Type.Array(TxOutputBinType) -}), -Type.Object({ -outputs: Type.Array(TxOutputType) -}), -Type.Object({ -extra_data: Type.String() -}), -Type.Object({ -version: Type.Optional(Type.Number()), -lock_time: Type.Optional(Type.Number()), -inputs_cnt: Type.Number(), -outputs_cnt: Type.Number(), -extra_data: Type.Optional(Type.String()), -extra_data_len: Type.Optional(Type.Number()), -timestamp: Type.Optional(Type.Number()), -version_group_id: Type.Optional(Type.Number()), -expiry: Type.Optional(Type.Number()), -branch_id: Type.Optional(Type.Number()) -}) -], {"$id":"TxAckResponse"}) - -export type TxAck = Static -export const TxAck = Type.Object({ -tx: TxAckResponse -}, {"$id":"TxAck"}) - -export type TxAckInputWrapper = Static -export const TxAckInputWrapper = Type.Object({ -input: TxInput -}, {"$id":"TxAckInputWrapper"}) - -export type TxAckInput = Static -export const TxAckInput = Type.Object({ -tx: TxAckInputWrapper -}, {"$id":"TxAckInput"}) - -export type TxAckOutputWrapper = Static -export const TxAckOutputWrapper = Type.Object({ -output: TxOutput -}, {"$id":"TxAckOutputWrapper"}) - -export type TxAckOutput = Static -export const TxAckOutput = Type.Object({ -tx: TxAckOutputWrapper -}, {"$id":"TxAckOutput"}) - -export type TxAckPrevMeta = Static -export const TxAckPrevMeta = Type.Object({ -tx: PrevTx -}, {"$id":"TxAckPrevMeta"}) - -export type TxAckPrevInputWrapper = Static -export const TxAckPrevInputWrapper = Type.Object({ -input: PrevInput -}, {"$id":"TxAckPrevInputWrapper"}) - -export type TxAckPrevInput = Static -export const TxAckPrevInput = Type.Object({ -tx: TxAckPrevInputWrapper -}, {"$id":"TxAckPrevInput"}) - -export type TxAckPrevOutputWrapper = Static -export const TxAckPrevOutputWrapper = Type.Object({ -output: PrevOutput -}, {"$id":"TxAckPrevOutputWrapper"}) - -export type TxAckPrevOutput = Static -export const TxAckPrevOutput = Type.Object({ -tx: TxAckPrevOutputWrapper -}, {"$id":"TxAckPrevOutput"}) - -export type TxAckPrevExtraDataWrapper = Static -export const TxAckPrevExtraDataWrapper = Type.Object({ -extra_data_chunk: Type.String() -}, {"$id":"TxAckPrevExtraDataWrapper"}) - -export type TxAckPrevExtraData = Static -export const TxAckPrevExtraData = Type.Object({ -tx: TxAckPrevExtraDataWrapper -}, {"$id":"TxAckPrevExtraData"}) - -export type GetOwnershipProof = Static -export const GetOwnershipProof = Type.Object({ -address_n: Type.Array(Type.Number()), -coin_name: Type.Optional(Type.String()), -script_type: Type.Optional(InputScriptType), -multisig: Type.Optional(MultisigRedeemScriptType), -user_confirmation: Type.Optional(Type.Boolean()), -ownership_ids: Type.Optional(Type.Array(Type.String())), -commitment_data: Type.Optional(Type.String()) -}, {"$id":"GetOwnershipProof"}) - -export type OwnershipProof = Static -export const OwnershipProof = Type.Object({ -ownership_proof: Type.String(), -signature: Type.String() -}, {"$id":"OwnershipProof"}) - -export type AuthorizeCoinJoin = Static -export const AuthorizeCoinJoin = Type.Object({ -coordinator: Type.String(), -max_rounds: Type.Number(), -max_coordinator_fee_rate: Type.Number(), -max_fee_per_kvbyte: Type.Number(), -address_n: Type.Array(Type.Number()), -coin_name: Type.Optional(Type.String()), -script_type: Type.Optional(InputScriptType), -amount_unit: Type.Optional(EnumAmountUnit) -}, {"$id":"AuthorizeCoinJoin"}) - -export type FirmwareErase = Static -export const FirmwareErase = Type.Object({ -length: Type.Optional(Type.Number()) -}, {"$id":"FirmwareErase"}) - -export type FirmwareRequest = Static -export const FirmwareRequest = Type.Object({ -offset: Type.Number(), -length: Type.Number() -}, {"$id":"FirmwareRequest"}) - -export type FirmwareUpload = Static -export const FirmwareUpload = Type.Object({ -payload: Type.Union([ -Type.Buffer(), -Type.ArrayBuffer() -]), -hash: Type.Optional(Type.String()) -}, {"$id":"FirmwareUpload"}) - -export type SelfTest = Static -export const SelfTest = Type.Object({ -payload: Type.Optional(Type.String()) -}, {"$id":"SelfTest"}) - -export enum CardanoDerivationType { LEDGER = 0, ICARUS = 1, ICARUS_TREZOR = 2 } - -export type EnumCardanoDerivationType = Static -export const EnumCardanoDerivationType = Type.Enum(CardanoDerivationType) - -export enum CardanoAddressType { BASE = 0, BASE_SCRIPT_KEY = 1, BASE_KEY_SCRIPT = 2, BASE_SCRIPT_SCRIPT = 3, POINTER = 4, POINTER_SCRIPT = 5, ENTERPRISE = 6, ENTERPRISE_SCRIPT = 7, BYRON = 8, REWARD = 14, REWARD_SCRIPT = 15 } - -export type EnumCardanoAddressType = Static -export const EnumCardanoAddressType = Type.Enum(CardanoAddressType) - -export enum CardanoNativeScriptType { PUB_KEY = 0, ALL = 1, ANY = 2, N_OF_K = 3, INVALID_BEFORE = 4, INVALID_HEREAFTER = 5 } - -export type EnumCardanoNativeScriptType = Static -export const EnumCardanoNativeScriptType = Type.Enum(CardanoNativeScriptType) - -export enum CardanoNativeScriptHashDisplayFormat { HIDE = 0, BECH32 = 1, POLICY_ID = 2 } - -export type EnumCardanoNativeScriptHashDisplayFormat = Static -export const EnumCardanoNativeScriptHashDisplayFormat = Type.Enum(CardanoNativeScriptHashDisplayFormat) - -export enum CardanoTxOutputSerializationFormat { ARRAY_LEGACY = 0, MAP_BABBAGE = 1 } - -export type EnumCardanoTxOutputSerializationFormat = Static -export const EnumCardanoTxOutputSerializationFormat = Type.Enum(CardanoTxOutputSerializationFormat) - -export enum CardanoCertificateType { STAKE_REGISTRATION = 0, STAKE_DEREGISTRATION = 1, STAKE_DELEGATION = 2, STAKE_POOL_REGISTRATION = 3 } - -export type EnumCardanoCertificateType = Static -export const EnumCardanoCertificateType = Type.Enum(CardanoCertificateType) - -export enum CardanoPoolRelayType { SINGLE_HOST_IP = 0, SINGLE_HOST_NAME = 1, MULTIPLE_HOST_NAME = 2 } - -export type EnumCardanoPoolRelayType = Static -export const EnumCardanoPoolRelayType = Type.Enum(CardanoPoolRelayType) - -export enum CardanoTxAuxiliaryDataSupplementType { NONE = 0, CVOTE_REGISTRATION_SIGNATURE = 1 } - -export type EnumCardanoTxAuxiliaryDataSupplementType = Static -export const EnumCardanoTxAuxiliaryDataSupplementType = Type.Enum(CardanoTxAuxiliaryDataSupplementType) - -export enum CardanoCVoteRegistrationFormat { CIP15 = 0, CIP36 = 1 } - -export type EnumCardanoCVoteRegistrationFormat = Static -export const EnumCardanoCVoteRegistrationFormat = Type.Enum(CardanoCVoteRegistrationFormat) - -export enum CardanoTxSigningMode { ORDINARY_TRANSACTION = 0, POOL_REGISTRATION_AS_OWNER = 1, MULTISIG_TRANSACTION = 2, PLUTUS_TRANSACTION = 3 } - -export type EnumCardanoTxSigningMode = Static -export const EnumCardanoTxSigningMode = Type.Enum(CardanoTxSigningMode) - -export enum CardanoTxWitnessType { BYRON_WITNESS = 0, SHELLEY_WITNESS = 1 } - -export type EnumCardanoTxWitnessType = Static -export const EnumCardanoTxWitnessType = Type.Enum(CardanoTxWitnessType) - -export type CardanoBlockchainPointerType = Static -export const CardanoBlockchainPointerType = Type.Object({ -block_index: Type.Number(), -tx_index: Type.Number(), -certificate_index: Type.Number() -}, {"$id":"CardanoBlockchainPointerType"}) - -export type CardanoNativeScript = Static -export const CardanoNativeScript = Type.Recursive(This => Type.Object({ -type: EnumCardanoNativeScriptType, -scripts: Type.Optional(Type.Array(This)), -key_hash: Type.Optional(Type.String()), -key_path: Type.Optional(Type.Array(Type.Number())), -required_signatures_count: Type.Optional(Type.Number()), -invalid_before: Type.Optional(Type.Uint()), -invalid_hereafter: Type.Optional(Type.Uint()) -}), {"$id":"CardanoNativeScript"}) - -export type CardanoGetNativeScriptHash = Static -export const CardanoGetNativeScriptHash = Type.Object({ -script: CardanoNativeScript, -display_format: EnumCardanoNativeScriptHashDisplayFormat, -derivation_type: EnumCardanoDerivationType -}, {"$id":"CardanoGetNativeScriptHash"}) - -export type CardanoNativeScriptHash = Static -export const CardanoNativeScriptHash = Type.Object({ -script_hash: Type.String() -}, {"$id":"CardanoNativeScriptHash"}) - -export type CardanoAddressParametersType = Static -export const CardanoAddressParametersType = Type.Object({ -address_type: EnumCardanoAddressType, -address_n: Type.Array(Type.Number()), -address_n_staking: Type.Array(Type.Number()), -staking_key_hash: Type.Optional(Type.String()), -certificate_pointer: Type.Optional(CardanoBlockchainPointerType), -script_payment_hash: Type.Optional(Type.String()), -script_staking_hash: Type.Optional(Type.String()) -}, {"$id":"CardanoAddressParametersType"}) - -export type CardanoGetAddress = Static -export const CardanoGetAddress = Type.Object({ -show_display: Type.Optional(Type.Boolean()), -protocol_magic: Type.Number(), -network_id: Type.Number(), -address_parameters: CardanoAddressParametersType, -derivation_type: EnumCardanoDerivationType, -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"CardanoGetAddress"}) - -export type CardanoAddress = Static -export const CardanoAddress = Type.Object({ -address: Type.String() -}, {"$id":"CardanoAddress"}) - -export type CardanoGetPublicKey = Static -export const CardanoGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -derivation_type: EnumCardanoDerivationType -}, {"$id":"CardanoGetPublicKey"}) - -export type CardanoPublicKey = Static -export const CardanoPublicKey = Type.Object({ -xpub: Type.String(), -node: HDNodeType -}, {"$id":"CardanoPublicKey"}) - -export type CardanoSignTxInit = Static -export const CardanoSignTxInit = Type.Object({ -signing_mode: EnumCardanoTxSigningMode, -protocol_magic: Type.Number(), -network_id: Type.Number(), -inputs_count: Type.Number(), -outputs_count: Type.Number(), -fee: Type.Uint(), -ttl: Type.Optional(Type.Uint()), -certificates_count: Type.Number(), -withdrawals_count: Type.Number(), -has_auxiliary_data: Type.Boolean(), -validity_interval_start: Type.Optional(Type.Uint()), -witness_requests_count: Type.Number(), -minting_asset_groups_count: Type.Number(), -derivation_type: EnumCardanoDerivationType, -include_network_id: Type.Optional(Type.Boolean()), -script_data_hash: Type.Optional(Type.String()), -collateral_inputs_count: Type.Number(), -required_signers_count: Type.Number(), -has_collateral_return: Type.Optional(Type.Boolean()), -total_collateral: Type.Optional(Type.Uint()), -reference_inputs_count: Type.Optional(Type.Number()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"CardanoSignTxInit"}) - -export type CardanoTxInput = Static -export const CardanoTxInput = Type.Object({ -prev_hash: Type.String(), -prev_index: Type.Number() -}, {"$id":"CardanoTxInput"}) - -export type CardanoTxOutput = Static -export const CardanoTxOutput = Type.Object({ -address: Type.Optional(Type.String()), -address_parameters: Type.Optional(CardanoAddressParametersType), -amount: Type.Uint(), -asset_groups_count: Type.Number(), -datum_hash: Type.Optional(Type.String()), -format: Type.Optional(EnumCardanoTxOutputSerializationFormat), -inline_datum_size: Type.Optional(Type.Number()), -reference_script_size: Type.Optional(Type.Number()) -}, {"$id":"CardanoTxOutput"}) - -export type CardanoAssetGroup = Static -export const CardanoAssetGroup = Type.Object({ -policy_id: Type.String(), -tokens_count: Type.Number() -}, {"$id":"CardanoAssetGroup"}) - -export type CardanoToken = Static -export const CardanoToken = Type.Object({ -asset_name_bytes: Type.String(), -amount: Type.Optional(Type.Uint()), -mint_amount: Type.Optional(Type.Uint()) -}, {"$id":"CardanoToken"}) - -export type CardanoTxInlineDatumChunk = Static -export const CardanoTxInlineDatumChunk = Type.Object({ -data: Type.String() -}, {"$id":"CardanoTxInlineDatumChunk"}) - -export type CardanoTxReferenceScriptChunk = Static -export const CardanoTxReferenceScriptChunk = Type.Object({ -data: Type.String() -}, {"$id":"CardanoTxReferenceScriptChunk"}) - -export type CardanoPoolOwner = Static -export const CardanoPoolOwner = Type.Object({ -staking_key_path: Type.Optional(Type.Array(Type.Number())), -staking_key_hash: Type.Optional(Type.String()) -}, {"$id":"CardanoPoolOwner"}) - -export type CardanoPoolRelayParameters = Static -export const CardanoPoolRelayParameters = Type.Object({ -type: EnumCardanoPoolRelayType, -ipv4_address: Type.Optional(Type.String()), -ipv6_address: Type.Optional(Type.String()), -host_name: Type.Optional(Type.String()), -port: Type.Optional(Type.Number()) -}, {"$id":"CardanoPoolRelayParameters"}) - -export type CardanoPoolMetadataType = Static -export const CardanoPoolMetadataType = Type.Object({ -url: Type.String(), -hash: Type.String() -}, {"$id":"CardanoPoolMetadataType"}) - -export type CardanoPoolParametersType = Static -export const CardanoPoolParametersType = Type.Object({ -pool_id: Type.String(), -vrf_key_hash: Type.String(), -pledge: Type.Uint(), -cost: Type.Uint(), -margin_numerator: Type.Uint(), -margin_denominator: Type.Uint(), -reward_account: Type.String(), -metadata: Type.Optional(CardanoPoolMetadataType), -owners_count: Type.Number(), -relays_count: Type.Number() -}, {"$id":"CardanoPoolParametersType"}) - -export type CardanoTxCertificate = Static -export const CardanoTxCertificate = Type.Object({ -type: EnumCardanoCertificateType, -path: Type.Optional(Type.Array(Type.Number())), -pool: Type.Optional(Type.String()), -pool_parameters: Type.Optional(CardanoPoolParametersType), -script_hash: Type.Optional(Type.String()), -key_hash: Type.Optional(Type.String()) -}, {"$id":"CardanoTxCertificate"}) - -export type CardanoTxWithdrawal = Static -export const CardanoTxWithdrawal = Type.Object({ -path: Type.Optional(Type.Array(Type.Number())), -amount: Type.Uint(), -script_hash: Type.Optional(Type.String()), -key_hash: Type.Optional(Type.String()) -}, {"$id":"CardanoTxWithdrawal"}) - -export type CardanoCVoteRegistrationDelegation = Static -export const CardanoCVoteRegistrationDelegation = Type.Object({ -vote_public_key: Type.String(), -weight: Type.Uint() -}, {"$id":"CardanoCVoteRegistrationDelegation"}) - -export type CardanoCVoteRegistrationParametersType = Static -export const CardanoCVoteRegistrationParametersType = Type.Object({ -vote_public_key: Type.Optional(Type.String()), -staking_path: Type.Array(Type.Number()), -payment_address_parameters: Type.Optional(CardanoAddressParametersType), -nonce: Type.Uint(), -format: Type.Optional(EnumCardanoCVoteRegistrationFormat), -delegations: Type.Optional(Type.Array(CardanoCVoteRegistrationDelegation)), -voting_purpose: Type.Optional(Type.Uint()), -payment_address: Type.Optional(Type.String()) -}, {"$id":"CardanoCVoteRegistrationParametersType"}) - -export type CardanoTxAuxiliaryData = Static -export const CardanoTxAuxiliaryData = Type.Object({ -cvote_registration_parameters: Type.Optional(CardanoCVoteRegistrationParametersType), -hash: Type.Optional(Type.String()) -}, {"$id":"CardanoTxAuxiliaryData"}) - -export type CardanoTxMint = Static -export const CardanoTxMint = Type.Object({ -asset_groups_count: Type.Number() -}, {"$id":"CardanoTxMint"}) - -export type CardanoTxCollateralInput = Static -export const CardanoTxCollateralInput = Type.Object({ -prev_hash: Type.String(), -prev_index: Type.Number() -}, {"$id":"CardanoTxCollateralInput"}) - -export type CardanoTxRequiredSigner = Static -export const CardanoTxRequiredSigner = Type.Object({ -key_hash: Type.Optional(Type.String()), -key_path: Type.Optional(Type.Array(Type.Number())) -}, {"$id":"CardanoTxRequiredSigner"}) - -export type CardanoTxReferenceInput = Static -export const CardanoTxReferenceInput = Type.Object({ -prev_hash: Type.String(), -prev_index: Type.Number() -}, {"$id":"CardanoTxReferenceInput"}) - -export type CardanoTxItemAck = Static -export const CardanoTxItemAck = Type.Object({ - -}, {"$id":"CardanoTxItemAck"}) - -export type CardanoTxAuxiliaryDataSupplement = Static -export const CardanoTxAuxiliaryDataSupplement = Type.Object({ -type: EnumCardanoTxAuxiliaryDataSupplementType, -auxiliary_data_hash: Type.Optional(Type.String()), -cvote_registration_signature: Type.Optional(Type.String()) -}, {"$id":"CardanoTxAuxiliaryDataSupplement"}) - -export type CardanoTxWitnessRequest = Static -export const CardanoTxWitnessRequest = Type.Object({ -path: Type.Array(Type.Number()) -}, {"$id":"CardanoTxWitnessRequest"}) - -export type CardanoTxWitnessResponse = Static -export const CardanoTxWitnessResponse = Type.Object({ -type: EnumCardanoTxWitnessType, -pub_key: Type.String(), -signature: Type.String(), -chain_code: Type.Optional(Type.String()) -}, {"$id":"CardanoTxWitnessResponse"}) - -export type CardanoTxHostAck = Static -export const CardanoTxHostAck = Type.Object({ - -}, {"$id":"CardanoTxHostAck"}) - -export type CardanoTxBodyHash = Static -export const CardanoTxBodyHash = Type.Object({ -tx_hash: Type.String() -}, {"$id":"CardanoTxBodyHash"}) - -export type CardanoSignTxFinished = Static -export const CardanoSignTxFinished = Type.Object({ - -}, {"$id":"CardanoSignTxFinished"}) - -export type Success = Static -export const Success = Type.Object({ -message: Type.String() -}, {"$id":"Success"}) - -export enum FailureType { Failure_UnexpectedMessage = 1, Failure_ButtonExpected = 2, Failure_DataError = 3, Failure_ActionCancelled = 4, Failure_PinExpected = 5, Failure_PinCancelled = 6, Failure_PinInvalid = 7, Failure_InvalidSignature = 8, Failure_ProcessError = 9, Failure_NotEnoughFunds = 10, Failure_NotInitialized = 11, Failure_PinMismatch = 12, Failure_WipeCodeMismatch = 13, Failure_InvalidSession = 14, Failure_FirmwareError = 99 } - -export type EnumFailureType = Static -export const EnumFailureType = Type.Enum(FailureType) - -export type Failure = Static -export const Failure = Type.Object({ -code: Type.Optional(EnumFailureType), -message: Type.Optional(Type.String()) -}, {"$id":"Failure"}) - -export enum Enum_ButtonRequestType { ButtonRequest_Other = 1, ButtonRequest_FeeOverThreshold = 2, ButtonRequest_ConfirmOutput = 3, ButtonRequest_ResetDevice = 4, ButtonRequest_ConfirmWord = 5, ButtonRequest_WipeDevice = 6, ButtonRequest_ProtectCall = 7, ButtonRequest_SignTx = 8, ButtonRequest_FirmwareCheck = 9, ButtonRequest_Address = 10, ButtonRequest_PublicKey = 11, ButtonRequest_MnemonicWordCount = 12, ButtonRequest_MnemonicInput = 13, _Deprecated_ButtonRequest_PassphraseType = 14, ButtonRequest_UnknownDerivationPath = 15, ButtonRequest_RecoveryHomepage = 16, ButtonRequest_Success = 17, ButtonRequest_Warning = 18, ButtonRequest_PassphraseEntry = 19, ButtonRequest_PinEntry = 20 } - -export type EnumEnum_ButtonRequestType = Static -export const EnumEnum_ButtonRequestType = Type.Enum(Enum_ButtonRequestType) - -export type ButtonRequestType = Static -export const ButtonRequestType = Type.KeyOfEnum(Enum_ButtonRequestType, {"$id":"ButtonRequestType"}) - -export type ButtonRequest = Static -export const ButtonRequest = Type.Object({ -code: Type.Optional(ButtonRequestType), -pages: Type.Optional(Type.Number()) -}, {"$id":"ButtonRequest"}) - -export type ButtonAck = Static -export const ButtonAck = Type.Object({ - -}, {"$id":"ButtonAck"}) - -export enum Enum_PinMatrixRequestType { PinMatrixRequestType_Current = 1, PinMatrixRequestType_NewFirst = 2, PinMatrixRequestType_NewSecond = 3, PinMatrixRequestType_WipeCodeFirst = 4, PinMatrixRequestType_WipeCodeSecond = 5 } - -export type EnumEnum_PinMatrixRequestType = Static -export const EnumEnum_PinMatrixRequestType = Type.Enum(Enum_PinMatrixRequestType) - -export type PinMatrixRequestType = Static -export const PinMatrixRequestType = Type.KeyOfEnum(Enum_PinMatrixRequestType, {"$id":"PinMatrixRequestType"}) - -export type PinMatrixRequest = Static -export const PinMatrixRequest = Type.Object({ -type: Type.Optional(PinMatrixRequestType) -}, {"$id":"PinMatrixRequest"}) - -export type PinMatrixAck = Static -export const PinMatrixAck = Type.Object({ -pin: Type.String() -}, {"$id":"PinMatrixAck"}) - -export type PassphraseRequest = Static -export const PassphraseRequest = Type.Object({ -_on_device: Type.Optional(Type.Boolean()) -}, {"$id":"PassphraseRequest"}) - -export type PassphraseAck = Static -export const PassphraseAck = Type.Object({ -passphrase: Type.Optional(Type.String()), -_state: Type.Optional(Type.String()), -on_device: Type.Optional(Type.Boolean()) -}, {"$id":"PassphraseAck"}) - -export type Deprecated_PassphraseStateRequest = Static -export const Deprecated_PassphraseStateRequest = Type.Object({ -state: Type.Optional(Type.String()) -}, {"$id":"Deprecated_PassphraseStateRequest"}) - -export type Deprecated_PassphraseStateAck = Static -export const Deprecated_PassphraseStateAck = Type.Object({ - -}, {"$id":"Deprecated_PassphraseStateAck"}) - -export type CipherKeyValue = Static -export const CipherKeyValue = Type.Object({ -address_n: Type.Array(Type.Number()), -key: Type.String(), -value: Type.String(), -encrypt: Type.Optional(Type.Boolean()), -ask_on_encrypt: Type.Optional(Type.Boolean()), -ask_on_decrypt: Type.Optional(Type.Boolean()), -iv: Type.Optional(Type.String()) -}, {"$id":"CipherKeyValue"}) - -export type CipheredKeyValue = Static -export const CipheredKeyValue = Type.Object({ -value: Type.String() -}, {"$id":"CipheredKeyValue"}) - -export type IdentityType = Static -export const IdentityType = Type.Object({ -proto: Type.Optional(Type.String()), -user: Type.Optional(Type.String()), -host: Type.Optional(Type.String()), -port: Type.Optional(Type.String()), -path: Type.Optional(Type.String()), -index: Type.Optional(Type.Number()) -}, {"$id":"IdentityType"}) - -export type SignIdentity = Static -export const SignIdentity = Type.Object({ -identity: IdentityType, -challenge_hidden: Type.Optional(Type.String()), -challenge_visual: Type.Optional(Type.String()), -ecdsa_curve_name: Type.Optional(Type.String()) -}, {"$id":"SignIdentity"}) - -export type SignedIdentity = Static -export const SignedIdentity = Type.Object({ -address: Type.String(), -public_key: Type.String(), -signature: Type.String() -}, {"$id":"SignedIdentity"}) - -export type GetECDHSessionKey = Static -export const GetECDHSessionKey = Type.Object({ -identity: IdentityType, -peer_public_key: Type.String(), -ecdsa_curve_name: Type.Optional(Type.String()) -}, {"$id":"GetECDHSessionKey"}) - -export type ECDHSessionKey = Static -export const ECDHSessionKey = Type.Object({ -session_key: Type.String(), -public_key: Type.Optional(Type.String()) -}, {"$id":"ECDHSessionKey"}) - -export enum DebugButton { NO = 0, YES = 1, INFO = 2 } - -export type EnumDebugButton = Static -export const EnumDebugButton = Type.Enum(DebugButton) - -export enum DebugPhysicalButton { LEFT_BTN = 0, MIDDLE_BTN = 1, RIGHT_BTN = 2 } - -export type EnumDebugPhysicalButton = Static -export const EnumDebugPhysicalButton = Type.Enum(DebugPhysicalButton) - -export type DebugLinkResetDebugEvents = Static -export const DebugLinkResetDebugEvents = Type.Object({ - -}, {"$id":"DebugLinkResetDebugEvents"}) - -export type EosGetPublicKey = Static -export const EosGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"EosGetPublicKey"}) - -export type EosPublicKey = Static -export const EosPublicKey = Type.Object({ -wif_public_key: Type.String(), -raw_public_key: Type.String() -}, {"$id":"EosPublicKey"}) - -export type EosTxHeader = Static -export const EosTxHeader = Type.Object({ -expiration: Type.Number(), -ref_block_num: Type.Number(), -ref_block_prefix: Type.Number(), -max_net_usage_words: Type.Number(), -max_cpu_usage_ms: Type.Number(), -delay_sec: Type.Number() -}, {"$id":"EosTxHeader"}) - -export type EosSignTx = Static -export const EosSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -chain_id: Type.String(), -header: EosTxHeader, -num_actions: Type.Number(), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"EosSignTx"}) - -export type EosTxActionRequest = Static -export const EosTxActionRequest = Type.Object({ -data_size: Type.Optional(Type.Number()) -}, {"$id":"EosTxActionRequest"}) - -export type EosAsset = Static -export const EosAsset = Type.Object({ -amount: Type.Uint(), -symbol: Type.String() -}, {"$id":"EosAsset"}) - -export type EosPermissionLevel = Static -export const EosPermissionLevel = Type.Object({ -actor: Type.String(), -permission: Type.String() -}, {"$id":"EosPermissionLevel"}) - -export type EosAuthorizationKey = Static -export const EosAuthorizationKey = Type.Object({ -type: Type.Optional(Type.Number()), -key: Type.String(), -address_n: Type.Optional(Type.Array(Type.Number())), -weight: Type.Number() -}, {"$id":"EosAuthorizationKey"}) - -export type EosAuthorizationAccount = Static -export const EosAuthorizationAccount = Type.Object({ -account: EosPermissionLevel, -weight: Type.Number() -}, {"$id":"EosAuthorizationAccount"}) - -export type EosAuthorizationWait = Static -export const EosAuthorizationWait = Type.Object({ -wait_sec: Type.Number(), -weight: Type.Number() -}, {"$id":"EosAuthorizationWait"}) - -export type EosAuthorization = Static -export const EosAuthorization = Type.Object({ -threshold: Type.Number(), -keys: Type.Array(EosAuthorizationKey), -accounts: Type.Array(EosAuthorizationAccount), -waits: Type.Array(EosAuthorizationWait) -}, {"$id":"EosAuthorization"}) - -export type EosActionCommon = Static -export const EosActionCommon = Type.Object({ -account: Type.String(), -name: Type.String(), -authorization: Type.Array(EosPermissionLevel) -}, {"$id":"EosActionCommon"}) - -export type EosActionTransfer = Static -export const EosActionTransfer = Type.Object({ -sender: Type.String(), -receiver: Type.String(), -quantity: EosAsset, -memo: Type.String() -}, {"$id":"EosActionTransfer"}) - -export type EosActionDelegate = Static -export const EosActionDelegate = Type.Object({ -sender: Type.String(), -receiver: Type.String(), -net_quantity: EosAsset, -cpu_quantity: EosAsset, -transfer: Type.Boolean() -}, {"$id":"EosActionDelegate"}) - -export type EosActionUndelegate = Static -export const EosActionUndelegate = Type.Object({ -sender: Type.String(), -receiver: Type.String(), -net_quantity: EosAsset, -cpu_quantity: EosAsset -}, {"$id":"EosActionUndelegate"}) - -export type EosActionRefund = Static -export const EosActionRefund = Type.Object({ -owner: Type.String() -}, {"$id":"EosActionRefund"}) - -export type EosActionBuyRam = Static -export const EosActionBuyRam = Type.Object({ -payer: Type.String(), -receiver: Type.String(), -quantity: EosAsset -}, {"$id":"EosActionBuyRam"}) - -export type EosActionBuyRamBytes = Static -export const EosActionBuyRamBytes = Type.Object({ -payer: Type.String(), -receiver: Type.String(), -bytes: Type.Number() -}, {"$id":"EosActionBuyRamBytes"}) - -export type EosActionSellRam = Static -export const EosActionSellRam = Type.Object({ -account: Type.String(), -bytes: Type.Number() -}, {"$id":"EosActionSellRam"}) - -export type EosActionVoteProducer = Static -export const EosActionVoteProducer = Type.Object({ -voter: Type.String(), -proxy: Type.String(), -producers: Type.Array(Type.String()) -}, {"$id":"EosActionVoteProducer"}) - -export type EosActionUpdateAuth = Static -export const EosActionUpdateAuth = Type.Object({ -account: Type.String(), -permission: Type.String(), -parent: Type.String(), -auth: EosAuthorization -}, {"$id":"EosActionUpdateAuth"}) - -export type EosActionDeleteAuth = Static -export const EosActionDeleteAuth = Type.Object({ -account: Type.String(), -permission: Type.String() -}, {"$id":"EosActionDeleteAuth"}) - -export type EosActionLinkAuth = Static -export const EosActionLinkAuth = Type.Object({ -account: Type.String(), -code: Type.String(), -type: Type.String(), -requirement: Type.String() -}, {"$id":"EosActionLinkAuth"}) - -export type EosActionUnlinkAuth = Static -export const EosActionUnlinkAuth = Type.Object({ -account: Type.String(), -code: Type.String(), -type: Type.String() -}, {"$id":"EosActionUnlinkAuth"}) - -export type EosActionNewAccount = Static -export const EosActionNewAccount = Type.Object({ -creator: Type.String(), -name: Type.String(), -owner: EosAuthorization, -active: EosAuthorization -}, {"$id":"EosActionNewAccount"}) - -export type EosActionUnknown = Static -export const EosActionUnknown = Type.Object({ -data_size: Type.Number(), -data_chunk: Type.String() -}, {"$id":"EosActionUnknown"}) - -export type EosTxActionAck = Static -export const EosTxActionAck = Type.Object({ -common: EosActionCommon, -transfer: Type.Optional(EosActionTransfer), -delegate: Type.Optional(EosActionDelegate), -undelegate: Type.Optional(EosActionUndelegate), -refund: Type.Optional(EosActionRefund), -buy_ram: Type.Optional(EosActionBuyRam), -buy_ram_bytes: Type.Optional(EosActionBuyRamBytes), -sell_ram: Type.Optional(EosActionSellRam), -vote_producer: Type.Optional(EosActionVoteProducer), -update_auth: Type.Optional(EosActionUpdateAuth), -delete_auth: Type.Optional(EosActionDeleteAuth), -link_auth: Type.Optional(EosActionLinkAuth), -unlink_auth: Type.Optional(EosActionUnlinkAuth), -new_account: Type.Optional(EosActionNewAccount), -unknown: Type.Optional(EosActionUnknown) -}, {"$id":"EosTxActionAck"}) - -export type EosSignedTx = Static -export const EosSignedTx = Type.Object({ -signature: Type.String() -}, {"$id":"EosSignedTx"}) - -export enum EthereumDefinitionType { NETWORK = 0, TOKEN = 1 } - -export type EnumEthereumDefinitionType = Static -export const EnumEthereumDefinitionType = Type.Enum(EthereumDefinitionType) - -export type EthereumNetworkInfo = Static -export const EthereumNetworkInfo = Type.Object({ -chain_id: Type.Number(), -symbol: Type.String(), -slip44: Type.Number(), -name: Type.String() -}, {"$id":"EthereumNetworkInfo"}) - -export type EthereumTokenInfo = Static -export const EthereumTokenInfo = Type.Object({ -address: Type.String(), -chain_id: Type.Number(), -symbol: Type.String(), -decimals: Type.Number(), -name: Type.String() -}, {"$id":"EthereumTokenInfo"}) - -export type EthereumDefinitions = Static -export const EthereumDefinitions = Type.Object({ -encoded_network: Type.Optional(Type.ArrayBuffer()), -encoded_token: Type.Optional(Type.ArrayBuffer()) -}, {"$id":"EthereumDefinitions"}) - -export type EthereumSignTypedData = Static -export const EthereumSignTypedData = Type.Object({ -address_n: Type.Array(Type.Number()), -primary_type: Type.String(), -metamask_v4_compat: Type.Optional(Type.Boolean()), -definitions: Type.Optional(EthereumDefinitions) -}, {"$id":"EthereumSignTypedData"}) - -export type EthereumTypedDataStructRequest = Static -export const EthereumTypedDataStructRequest = Type.Object({ -name: Type.String() -}, {"$id":"EthereumTypedDataStructRequest"}) - -export enum EthereumDataType { UINT = 1, INT = 2, BYTES = 3, STRING = 4, BOOL = 5, ADDRESS = 6, ARRAY = 7, STRUCT = 8 } - -export type EnumEthereumDataType = Static -export const EnumEthereumDataType = Type.Enum(EthereumDataType) - -export type EthereumFieldType = Static -export const EthereumFieldType = Type.Recursive(This => Type.Object({ -data_type: EnumEthereumDataType, -size: Type.Optional(Type.Number()), -entry_type: Type.Optional(This), -struct_name: Type.Optional(Type.String()) -}), {"$id":"EthereumFieldType"}) - -export type EthereumStructMember = Static -export const EthereumStructMember = Type.Object({ -type: EthereumFieldType, -name: Type.String() -}, {"$id":"EthereumStructMember"}) - -export type EthereumTypedDataStructAck = Static -export const EthereumTypedDataStructAck = Type.Object({ -members: Type.Array(EthereumStructMember) -}, {"$id":"EthereumTypedDataStructAck"}) - -export type EthereumTypedDataValueRequest = Static -export const EthereumTypedDataValueRequest = Type.Object({ -member_path: Type.Array(Type.Number()) -}, {"$id":"EthereumTypedDataValueRequest"}) - -export type EthereumTypedDataValueAck = Static -export const EthereumTypedDataValueAck = Type.Object({ -value: Type.String() -}, {"$id":"EthereumTypedDataValueAck"}) - -export type EthereumGetPublicKey = Static -export const EthereumGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()) -}, {"$id":"EthereumGetPublicKey"}) - -export type EthereumPublicKey = Static -export const EthereumPublicKey = Type.Object({ -node: HDNodeType, -xpub: Type.String() -}, {"$id":"EthereumPublicKey"}) - -export type EthereumGetAddress = Static -export const EthereumGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -encoded_network: Type.Optional(Type.ArrayBuffer()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"EthereumGetAddress"}) - -export type EthereumAddress = Static -export const EthereumAddress = Type.Object({ -_old_address: Type.Optional(Type.String()), -address: Type.String() -}, {"$id":"EthereumAddress"}) - -export type EthereumSignTx = Static -export const EthereumSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -nonce: Type.Optional(Type.String()), -gas_price: Type.String(), -gas_limit: Type.String(), -to: Type.Optional(Type.String()), -value: Type.Optional(Type.String()), -data_initial_chunk: Type.Optional(Type.String()), -data_length: Type.Optional(Type.Number()), -chain_id: Type.Number(), -tx_type: Type.Optional(Type.Number()), -definitions: Type.Optional(EthereumDefinitions), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"EthereumSignTx"}) - -export type EthereumAccessList = Static -export const EthereumAccessList = Type.Object({ -address: Type.String(), -storage_keys: Type.Array(Type.String()) -}, {"$id":"EthereumAccessList"}) - -export type EthereumSignTxEIP1559 = Static -export const EthereumSignTxEIP1559 = Type.Object({ -address_n: Type.Array(Type.Number()), -nonce: Type.String(), -max_gas_fee: Type.String(), -max_priority_fee: Type.String(), -gas_limit: Type.String(), -to: Type.Optional(Type.String()), -value: Type.String(), -data_initial_chunk: Type.Optional(Type.String()), -data_length: Type.Number(), -chain_id: Type.Number(), -access_list: Type.Array(EthereumAccessList), -definitions: Type.Optional(EthereumDefinitions), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"EthereumSignTxEIP1559"}) - -export type EthereumTxRequest = Static -export const EthereumTxRequest = Type.Object({ -data_length: Type.Optional(Type.Number()), -signature_v: Type.Optional(Type.Number()), -signature_r: Type.Optional(Type.String()), -signature_s: Type.Optional(Type.String()) -}, {"$id":"EthereumTxRequest"}) - -export type EthereumTxAck = Static -export const EthereumTxAck = Type.Object({ -data_chunk: Type.String() -}, {"$id":"EthereumTxAck"}) - -export type EthereumSignMessage = Static -export const EthereumSignMessage = Type.Object({ -address_n: Type.Array(Type.Number()), -message: Type.String(), -encoded_network: Type.Optional(Type.ArrayBuffer()) -}, {"$id":"EthereumSignMessage"}) - -export type EthereumMessageSignature = Static -export const EthereumMessageSignature = Type.Object({ -signature: Type.String(), -address: Type.String() -}, {"$id":"EthereumMessageSignature"}) - -export type EthereumVerifyMessage = Static -export const EthereumVerifyMessage = Type.Object({ -signature: Type.String(), -message: Type.String(), -address: Type.String() -}, {"$id":"EthereumVerifyMessage"}) - -export type EthereumSignTypedHash = Static -export const EthereumSignTypedHash = Type.Object({ -address_n: Type.Array(Type.Number()), -domain_separator_hash: Type.String(), -message_hash: Type.Optional(Type.String()), -encoded_network: Type.Optional(Type.ArrayBuffer()) -}, {"$id":"EthereumSignTypedHash"}) - -export type EthereumTypedDataSignature = Static -export const EthereumTypedDataSignature = Type.Object({ -signature: Type.String(), -address: Type.String() -}, {"$id":"EthereumTypedDataSignature"}) - -export enum Enum_BackupType { Bip39 = 0, Slip39_Basic = 1, Slip39_Advanced = 2 } - -export type EnumEnum_BackupType = Static -export const EnumEnum_BackupType = Type.Enum(Enum_BackupType) - -export type BackupType = Static -export const BackupType = Type.KeyOfEnum(Enum_BackupType, {"$id":"BackupType"}) - -export enum Enum_SafetyCheckLevel { Strict = 0, PromptAlways = 1, PromptTemporarily = 2 } - -export type EnumEnum_SafetyCheckLevel = Static -export const EnumEnum_SafetyCheckLevel = Type.Enum(Enum_SafetyCheckLevel) - -export type SafetyCheckLevel = Static -export const SafetyCheckLevel = Type.KeyOfEnum(Enum_SafetyCheckLevel, {"$id":"SafetyCheckLevel"}) - -export enum Enum_HomescreenFormat { Toif = 1, Jpeg = 2, ToiG = 3 } - -export type EnumEnum_HomescreenFormat = Static -export const EnumEnum_HomescreenFormat = Type.Enum(Enum_HomescreenFormat) - -export type HomescreenFormat = Static -export const HomescreenFormat = Type.KeyOfEnum(Enum_HomescreenFormat, {"$id":"HomescreenFormat"}) - -export type Initialize = Static -export const Initialize = Type.Object({ -session_id: Type.Optional(Type.String()), -_skip_passphrase: Type.Optional(Type.Boolean()), -derive_cardano: Type.Optional(Type.Boolean()) -}, {"$id":"Initialize"}) - -export type GetFeatures = Static -export const GetFeatures = Type.Object({ - -}, {"$id":"GetFeatures"}) - -export enum Enum_Capability { Capability_Bitcoin = 1, Capability_Bitcoin_like = 2, Capability_Binance = 3, Capability_Cardano = 4, Capability_Crypto = 5, Capability_EOS = 6, Capability_Ethereum = 7, Capability_Lisk = 8, Capability_Monero = 9, Capability_NEM = 10, Capability_Ripple = 11, Capability_Stellar = 12, Capability_Tezos = 13, Capability_U2F = 14, Capability_Shamir = 15, Capability_ShamirGroups = 16, Capability_PassphraseEntry = 17, Capability_Solana = 18 } - -export type EnumEnum_Capability = Static -export const EnumEnum_Capability = Type.Enum(Enum_Capability) - -export type Capability = Static -export const Capability = Type.KeyOfEnum(Enum_Capability, {"$id":"Capability"}) - -export type Features = Static -export const Features = Type.Object({ -vendor: Type.String(), -major_version: Type.Number(), -minor_version: Type.Number(), -patch_version: Type.Number(), -bootloader_mode: Type.Union([ -Type.Boolean(), -Type.Null() -]), -device_id: Type.Union([ -Type.String(), -Type.Null() -]), -pin_protection: Type.Union([ -Type.Boolean(), -Type.Null() -]), -passphrase_protection: Type.Union([ -Type.Boolean(), -Type.Null() -]), -language: Type.Union([ -Type.String(), -Type.Null() -]), -label: Type.Union([ -Type.String(), -Type.Null() -]), -initialized: Type.Union([ -Type.Boolean(), -Type.Null() -]), -revision: Type.Union([ -Type.String(), -Type.Null() -]), -bootloader_hash: Type.Union([ -Type.String(), -Type.Null() -]), -imported: Type.Union([ -Type.Boolean(), -Type.Null() -]), -unlocked: Type.Union([ -Type.Boolean(), -Type.Null() -]), -_passphrase_cached: Type.Optional(Type.Boolean()), -firmware_present: Type.Union([ -Type.Boolean(), -Type.Null() -]), -needs_backup: Type.Union([ -Type.Boolean(), -Type.Null() -]), -flags: Type.Union([ -Type.Number(), -Type.Null() -]), -model: Type.String(), -fw_major: Type.Union([ -Type.Number(), -Type.Null() -]), -fw_minor: Type.Union([ -Type.Number(), -Type.Null() -]), -fw_patch: Type.Union([ -Type.Number(), -Type.Null() -]), -fw_vendor: Type.Union([ -Type.String(), -Type.Null() -]), -unfinished_backup: Type.Union([ -Type.Boolean(), -Type.Null() -]), -no_backup: Type.Union([ -Type.Boolean(), -Type.Null() -]), -recovery_mode: Type.Union([ -Type.Boolean(), -Type.Null() -]), -capabilities: Type.Array(Capability), -backup_type: Type.Union([ -BackupType, -Type.Null() -]), -sd_card_present: Type.Union([ -Type.Boolean(), -Type.Null() -]), -sd_protection: Type.Union([ -Type.Boolean(), -Type.Null() -]), -wipe_code_protection: Type.Union([ -Type.Boolean(), -Type.Null() -]), -session_id: Type.Union([ -Type.String(), -Type.Null() -]), -passphrase_always_on_device: Type.Union([ -Type.Boolean(), -Type.Null() -]), -safety_checks: Type.Union([ -SafetyCheckLevel, -Type.Null() -]), -auto_lock_delay_ms: Type.Union([ -Type.Number(), -Type.Null() -]), -display_rotation: Type.Union([ -Type.Number(), -Type.Null() -]), -experimental_features: Type.Union([ -Type.Boolean(), -Type.Null() -]), -busy: Type.Optional(Type.Boolean()), -homescreen_format: Type.Optional(HomescreenFormat), -hide_passphrase_from_host: Type.Optional(Type.Boolean()), -internal_model: EnumDeviceModelInternal, -unit_color: Type.Optional(Type.Number()), -unit_btconly: Type.Optional(Type.Boolean()), -homescreen_width: Type.Optional(Type.Number()), -homescreen_height: Type.Optional(Type.Number()), -bootloader_locked: Type.Optional(Type.Boolean()) -}, {"$id":"Features"}) - -export type LockDevice = Static -export const LockDevice = Type.Object({ - -}, {"$id":"LockDevice"}) - -export type SetBusy = Static -export const SetBusy = Type.Object({ -expiry_ms: Type.Optional(Type.Number()) -}, {"$id":"SetBusy"}) - -export type EndSession = Static -export const EndSession = Type.Object({ - -}, {"$id":"EndSession"}) - -export type ApplySettings = Static -export const ApplySettings = Type.Object({ -language: Type.Optional(Type.String()), -label: Type.Optional(Type.String()), -use_passphrase: Type.Optional(Type.Boolean()), -homescreen: Type.Optional(Type.String()), -_passphrase_source: Type.Optional(Type.Number()), -auto_lock_delay_ms: Type.Optional(Type.Number()), -display_rotation: Type.Optional(Type.Number()), -passphrase_always_on_device: Type.Optional(Type.Boolean()), -safety_checks: Type.Optional(SafetyCheckLevel), -experimental_features: Type.Optional(Type.Boolean()), -hide_passphrase_from_host: Type.Optional(Type.Boolean()) -}, {"$id":"ApplySettings"}) - -export type ApplyFlags = Static -export const ApplyFlags = Type.Object({ -flags: Type.Number() -}, {"$id":"ApplyFlags"}) - -export type ChangePin = Static -export const ChangePin = Type.Object({ -remove: Type.Optional(Type.Boolean()) -}, {"$id":"ChangePin"}) - -export type ChangeWipeCode = Static -export const ChangeWipeCode = Type.Object({ -remove: Type.Optional(Type.Boolean()) -}, {"$id":"ChangeWipeCode"}) - -export enum SdProtectOperationType { DISABLE = 0, ENABLE = 1, REFRESH = 2 } - -export type EnumSdProtectOperationType = Static -export const EnumSdProtectOperationType = Type.Enum(SdProtectOperationType) - -export type SdProtect = Static -export const SdProtect = Type.Object({ -operation: EnumSdProtectOperationType -}, {"$id":"SdProtect"}) - -export type Ping = Static -export const Ping = Type.Object({ -message: Type.Optional(Type.String()), -button_protection: Type.Optional(Type.Boolean()) -}, {"$id":"Ping"}) - -export type Cancel = Static -export const Cancel = Type.Object({ - -}, {"$id":"Cancel"}) - -export type GetEntropy = Static -export const GetEntropy = Type.Object({ -size: Type.Number() -}, {"$id":"GetEntropy"}) - -export type Entropy = Static -export const Entropy = Type.Object({ -entropy: Type.String() -}, {"$id":"Entropy"}) - -export type GetFirmwareHash = Static -export const GetFirmwareHash = Type.Object({ -challenge: Type.Optional(Type.String()) -}, {"$id":"GetFirmwareHash"}) - -export type FirmwareHash = Static -export const FirmwareHash = Type.Object({ -hash: Type.String() -}, {"$id":"FirmwareHash"}) - -export type AuthenticateDevice = Static -export const AuthenticateDevice = Type.Object({ -challenge: Type.String() -}, {"$id":"AuthenticateDevice"}) - -export type AuthenticityProof = Static -export const AuthenticityProof = Type.Object({ -certificates: Type.Array(Type.String()), -signature: Type.String() -}, {"$id":"AuthenticityProof"}) - -export type WipeDevice = Static -export const WipeDevice = Type.Object({ - -}, {"$id":"WipeDevice"}) - -export type ResetDevice = Static -export const ResetDevice = Type.Object({ -display_random: Type.Optional(Type.Boolean()), -strength: Type.Optional(Type.Number()), -passphrase_protection: Type.Optional(Type.Boolean()), -pin_protection: Type.Optional(Type.Boolean()), -language: Type.Optional(Type.String()), -label: Type.Optional(Type.String()), -u2f_counter: Type.Optional(Type.Number()), -skip_backup: Type.Optional(Type.Boolean()), -no_backup: Type.Optional(Type.Boolean()), -backup_type: Type.Optional(Type.Union([ -Type.String(), -Type.Number() -])) -}, {"$id":"ResetDevice"}) - -export type BackupDevice = Static -export const BackupDevice = Type.Object({ - -}, {"$id":"BackupDevice"}) - -export type EntropyRequest = Static -export const EntropyRequest = Type.Object({ - -}, {"$id":"EntropyRequest"}) - -export type EntropyAck = Static -export const EntropyAck = Type.Object({ -entropy: Type.String() -}, {"$id":"EntropyAck"}) - -export enum RecoveryDeviceType { RecoveryDeviceType_ScrambledWords = 0, RecoveryDeviceType_Matrix = 1 } - -export type EnumRecoveryDeviceType = Static -export const EnumRecoveryDeviceType = Type.Enum(RecoveryDeviceType) - -export type RecoveryDevice = Static -export const RecoveryDevice = Type.Object({ -word_count: Type.Optional(Type.Number()), -passphrase_protection: Type.Optional(Type.Boolean()), -pin_protection: Type.Optional(Type.Boolean()), -language: Type.Optional(Type.String()), -label: Type.Optional(Type.String()), -enforce_wordlist: Type.Optional(Type.Boolean()), -type: Type.Optional(EnumRecoveryDeviceType), -u2f_counter: Type.Optional(Type.Number()), -dry_run: Type.Optional(Type.Boolean()) -}, {"$id":"RecoveryDevice"}) - -export enum Enum_WordRequestType { WordRequestType_Plain = 0, WordRequestType_Matrix9 = 1, WordRequestType_Matrix6 = 2 } - -export type EnumEnum_WordRequestType = Static -export const EnumEnum_WordRequestType = Type.Enum(Enum_WordRequestType) - -export type WordRequestType = Static -export const WordRequestType = Type.KeyOfEnum(Enum_WordRequestType, {"$id":"WordRequestType"}) - -export type WordRequest = Static -export const WordRequest = Type.Object({ -type: WordRequestType -}, {"$id":"WordRequest"}) - -export type WordAck = Static -export const WordAck = Type.Object({ -word: Type.String() -}, {"$id":"WordAck"}) - -export type SetU2FCounter = Static -export const SetU2FCounter = Type.Object({ -u2f_counter: Type.Number() -}, {"$id":"SetU2FCounter"}) - -export type GetNextU2FCounter = Static -export const GetNextU2FCounter = Type.Object({ - -}, {"$id":"GetNextU2FCounter"}) - -export type NextU2FCounter = Static -export const NextU2FCounter = Type.Object({ -u2f_counter: Type.Number() -}, {"$id":"NextU2FCounter"}) - -export type DoPreauthorized = Static -export const DoPreauthorized = Type.Object({ - -}, {"$id":"DoPreauthorized"}) - -export type PreauthorizedRequest = Static -export const PreauthorizedRequest = Type.Object({ - -}, {"$id":"PreauthorizedRequest"}) - -export type CancelAuthorization = Static -export const CancelAuthorization = Type.Object({ - -}, {"$id":"CancelAuthorization"}) - -export type RebootToBootloader = Static -export const RebootToBootloader = Type.Object({ - -}, {"$id":"RebootToBootloader"}) - -export type GetNonce = Static -export const GetNonce = Type.Object({ - -}, {"$id":"GetNonce"}) - -export type Nonce = Static -export const Nonce = Type.Object({ -nonce: Type.String() -}, {"$id":"Nonce"}) - -export type UnlockPath = Static -export const UnlockPath = Type.Object({ -address_n: Type.Array(Type.Number()), -mac: Type.Optional(Type.String()) -}, {"$id":"UnlockPath"}) - -export type UnlockedPathRequest = Static -export const UnlockedPathRequest = Type.Object({ -mac: Type.Optional(Type.String()) -}, {"$id":"UnlockedPathRequest"}) - -export type ShowDeviceTutorial = Static -export const ShowDeviceTutorial = Type.Object({ - -}, {"$id":"ShowDeviceTutorial"}) - -export type UnlockBootloader = Static -export const UnlockBootloader = Type.Object({ - -}, {"$id":"UnlockBootloader"}) - -export enum MoneroNetworkType { MAINNET = 0, TESTNET = 1, STAGENET = 2, FAKECHAIN = 3 } - -export type EnumMoneroNetworkType = Static -export const EnumMoneroNetworkType = Type.Enum(MoneroNetworkType) - -export type NEMGetAddress = Static -export const NEMGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -network: Type.Optional(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"NEMGetAddress"}) - -export type NEMAddress = Static -export const NEMAddress = Type.Object({ -address: Type.String() -}, {"$id":"NEMAddress"}) - -export type NEMTransactionCommon = Static -export const NEMTransactionCommon = Type.Object({ -address_n: Type.Optional(Type.Array(Type.Number())), -network: Type.Optional(Type.Number()), -timestamp: Type.Number(), -fee: Type.Uint(), -deadline: Type.Number(), -signer: Type.Optional(Type.String()) -}, {"$id":"NEMTransactionCommon"}) - -export type NEMMosaic = Static -export const NEMMosaic = Type.Object({ -namespace: Type.String(), -mosaic: Type.String(), -quantity: Type.Number() -}, {"$id":"NEMMosaic"}) - -export type NEMTransfer = Static -export const NEMTransfer = Type.Object({ -recipient: Type.String(), -amount: Type.Uint(), -payload: Type.Optional(Type.String()), -public_key: Type.Optional(Type.String()), -mosaics: Type.Optional(Type.Array(NEMMosaic)) -}, {"$id":"NEMTransfer"}) - -export type NEMProvisionNamespace = Static -export const NEMProvisionNamespace = Type.Object({ -namespace: Type.String(), -parent: Type.Optional(Type.String()), -sink: Type.String(), -fee: Type.Uint() -}, {"$id":"NEMProvisionNamespace"}) - -export enum NEMMosaicLevy { MosaicLevy_Absolute = 1, MosaicLevy_Percentile = 2 } - -export type EnumNEMMosaicLevy = Static -export const EnumNEMMosaicLevy = Type.Enum(NEMMosaicLevy) - -export type NEMMosaicDefinition = Static -export const NEMMosaicDefinition = Type.Object({ -name: Type.Optional(Type.String()), -ticker: Type.Optional(Type.String()), -namespace: Type.String(), -mosaic: Type.String(), -divisibility: Type.Optional(Type.Number()), -levy: Type.Optional(EnumNEMMosaicLevy), -fee: Type.Optional(Type.Uint()), -levy_address: Type.Optional(Type.String()), -levy_namespace: Type.Optional(Type.String()), -levy_mosaic: Type.Optional(Type.String()), -supply: Type.Optional(Type.Number()), -mutable_supply: Type.Optional(Type.Boolean()), -transferable: Type.Optional(Type.Boolean()), -description: Type.String(), -networks: Type.Optional(Type.Array(Type.Number())) -}, {"$id":"NEMMosaicDefinition"}) - -export type NEMMosaicCreation = Static -export const NEMMosaicCreation = Type.Object({ -definition: NEMMosaicDefinition, -sink: Type.String(), -fee: Type.Uint() -}, {"$id":"NEMMosaicCreation"}) - -export enum NEMSupplyChangeType { SupplyChange_Increase = 1, SupplyChange_Decrease = 2 } - -export type EnumNEMSupplyChangeType = Static -export const EnumNEMSupplyChangeType = Type.Enum(NEMSupplyChangeType) - -export type NEMMosaicSupplyChange = Static -export const NEMMosaicSupplyChange = Type.Object({ -namespace: Type.String(), -mosaic: Type.String(), -type: EnumNEMSupplyChangeType, -delta: Type.Number() -}, {"$id":"NEMMosaicSupplyChange"}) - -export enum NEMModificationType { CosignatoryModification_Add = 1, CosignatoryModification_Delete = 2 } - -export type EnumNEMModificationType = Static -export const EnumNEMModificationType = Type.Enum(NEMModificationType) - -export type NEMCosignatoryModification = Static -export const NEMCosignatoryModification = Type.Object({ -type: EnumNEMModificationType, -public_key: Type.String() -}, {"$id":"NEMCosignatoryModification"}) - -export type NEMAggregateModification = Static -export const NEMAggregateModification = Type.Object({ -modifications: Type.Optional(Type.Array(NEMCosignatoryModification)), -relative_change: Type.Optional(Type.Number()) -}, {"$id":"NEMAggregateModification"}) - -export enum NEMImportanceTransferMode { ImportanceTransfer_Activate = 1, ImportanceTransfer_Deactivate = 2 } - -export type EnumNEMImportanceTransferMode = Static -export const EnumNEMImportanceTransferMode = Type.Enum(NEMImportanceTransferMode) - -export type NEMImportanceTransfer = Static -export const NEMImportanceTransfer = Type.Object({ -mode: EnumNEMImportanceTransferMode, -public_key: Type.String() -}, {"$id":"NEMImportanceTransfer"}) - -export type NEMSignTx = Static -export const NEMSignTx = Type.Object({ -transaction: NEMTransactionCommon, -multisig: Type.Optional(NEMTransactionCommon), -transfer: Type.Optional(NEMTransfer), -cosigning: Type.Optional(Type.Boolean()), -provision_namespace: Type.Optional(NEMProvisionNamespace), -mosaic_creation: Type.Optional(NEMMosaicCreation), -supply_change: Type.Optional(NEMMosaicSupplyChange), -aggregate_modification: Type.Optional(NEMAggregateModification), -importance_transfer: Type.Optional(NEMImportanceTransfer), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"NEMSignTx"}) - -export type NEMSignedTx = Static -export const NEMSignedTx = Type.Object({ -data: Type.String(), -signature: Type.String() -}, {"$id":"NEMSignedTx"}) - -export type NEMDecryptMessage = Static -export const NEMDecryptMessage = Type.Object({ -address_n: Type.Array(Type.Number()), -network: Type.Optional(Type.Number()), -public_key: Type.Optional(Type.String()), -payload: Type.Optional(Type.String()) -}, {"$id":"NEMDecryptMessage"}) - -export type NEMDecryptedMessage = Static -export const NEMDecryptedMessage = Type.Object({ -payload: Type.String() -}, {"$id":"NEMDecryptedMessage"}) - -export type RippleGetAddress = Static -export const RippleGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"RippleGetAddress"}) - -export type RippleAddress = Static -export const RippleAddress = Type.Object({ -address: Type.String() -}, {"$id":"RippleAddress"}) - -export type RipplePayment = Static -export const RipplePayment = Type.Object({ -amount: Type.Uint(), -destination: Type.String(), -destination_tag: Type.Optional(Type.Number()) -}, {"$id":"RipplePayment"}) - -export type RippleSignTx = Static -export const RippleSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -fee: Type.Uint(), -flags: Type.Optional(Type.Number()), -sequence: Type.Number(), -last_ledger_sequence: Type.Optional(Type.Number()), -payment: RipplePayment, -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"RippleSignTx"}) - -export type RippleSignedTx = Static -export const RippleSignedTx = Type.Object({ -signature: Type.String(), -serialized_tx: Type.String() -}, {"$id":"RippleSignedTx"}) - -export type SolanaGetPublicKey = Static -export const SolanaGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()) -}, {"$id":"SolanaGetPublicKey"}) - -export type SolanaPublicKey = Static -export const SolanaPublicKey = Type.Object({ -public_key: Type.String() -}, {"$id":"SolanaPublicKey"}) - -export type SolanaGetAddress = Static -export const SolanaGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()) -}, {"$id":"SolanaGetAddress"}) - -export type SolanaAddress = Static -export const SolanaAddress = Type.Object({ -address: Type.String() -}, {"$id":"SolanaAddress"}) - -export type SolanaSignTx = Static -export const SolanaSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -serialized_tx: Type.String() -}, {"$id":"SolanaSignTx"}) - -export type SolanaTxSignature = Static -export const SolanaTxSignature = Type.Object({ -signature: Type.String() -}, {"$id":"SolanaTxSignature"}) - -export enum StellarAssetType { NATIVE = 0, ALPHANUM4 = 1, ALPHANUM12 = 2 } - -export type EnumStellarAssetType = Static -export const EnumStellarAssetType = Type.Enum(StellarAssetType) - -export type StellarAsset = Static -export const StellarAsset = Type.Object({ -type: EnumStellarAssetType, -code: Type.Optional(Type.String()), -issuer: Type.Optional(Type.String()) -}, {"$id":"StellarAsset"}) - -export type StellarGetAddress = Static -export const StellarGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"StellarGetAddress"}) - -export type StellarAddress = Static -export const StellarAddress = Type.Object({ -address: Type.String() -}, {"$id":"StellarAddress"}) - -export enum StellarMemoType { NONE = 0, TEXT = 1, ID = 2, HASH = 3, RETURN = 4 } - -export type EnumStellarMemoType = Static -export const EnumStellarMemoType = Type.Enum(StellarMemoType) - -export type StellarSignTx = Static -export const StellarSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -network_passphrase: Type.String(), -source_account: Type.String(), -fee: Type.Uint(), -sequence_number: Type.Uint(), -timebounds_start: Type.Number(), -timebounds_end: Type.Number(), -memo_type: EnumStellarMemoType, -memo_text: Type.Optional(Type.String()), -memo_id: Type.Optional(Type.String()), -memo_hash: Type.Optional(Type.Union([ -Type.Buffer(), -Type.String() -])), -num_operations: Type.Number() -}, {"$id":"StellarSignTx"}) - -export type StellarTxOpRequest = Static -export const StellarTxOpRequest = Type.Object({ - -}, {"$id":"StellarTxOpRequest"}) - -export type StellarPaymentOp = Static -export const StellarPaymentOp = Type.Object({ -source_account: Type.Optional(Type.String()), -destination_account: Type.String(), -asset: StellarAsset, -amount: Type.Uint() -}, {"$id":"StellarPaymentOp"}) - -export type StellarCreateAccountOp = Static -export const StellarCreateAccountOp = Type.Object({ -source_account: Type.Optional(Type.String()), -new_account: Type.String(), -starting_balance: Type.Uint() -}, {"$id":"StellarCreateAccountOp"}) - -export type StellarPathPaymentStrictReceiveOp = Static -export const StellarPathPaymentStrictReceiveOp = Type.Object({ -source_account: Type.Optional(Type.String()), -send_asset: StellarAsset, -send_max: Type.Uint(), -destination_account: Type.String(), -destination_asset: StellarAsset, -destination_amount: Type.Uint(), -paths: Type.Optional(Type.Array(StellarAsset)) -}, {"$id":"StellarPathPaymentStrictReceiveOp"}) - -export type StellarPathPaymentStrictSendOp = Static -export const StellarPathPaymentStrictSendOp = Type.Object({ -source_account: Type.Optional(Type.String()), -send_asset: StellarAsset, -send_amount: Type.Uint(), -destination_account: Type.String(), -destination_asset: StellarAsset, -destination_min: Type.Uint(), -paths: Type.Optional(Type.Array(StellarAsset)) -}, {"$id":"StellarPathPaymentStrictSendOp"}) - -export type StellarManageSellOfferOp = Static -export const StellarManageSellOfferOp = Type.Object({ -source_account: Type.Optional(Type.String()), -selling_asset: StellarAsset, -buying_asset: StellarAsset, -amount: Type.Uint(), -price_n: Type.Number(), -price_d: Type.Number(), -offer_id: Type.Uint() -}, {"$id":"StellarManageSellOfferOp"}) - -export type StellarManageBuyOfferOp = Static -export const StellarManageBuyOfferOp = Type.Object({ -source_account: Type.Optional(Type.String()), -selling_asset: StellarAsset, -buying_asset: StellarAsset, -amount: Type.Uint(), -price_n: Type.Number(), -price_d: Type.Number(), -offer_id: Type.Uint() -}, {"$id":"StellarManageBuyOfferOp"}) - -export type StellarCreatePassiveSellOfferOp = Static -export const StellarCreatePassiveSellOfferOp = Type.Object({ -source_account: Type.Optional(Type.String()), -selling_asset: StellarAsset, -buying_asset: StellarAsset, -amount: Type.Uint(), -price_n: Type.Number(), -price_d: Type.Number() -}, {"$id":"StellarCreatePassiveSellOfferOp"}) - -export enum StellarSignerType { ACCOUNT = 0, PRE_AUTH = 1, HASH = 2 } - -export type EnumStellarSignerType = Static -export const EnumStellarSignerType = Type.Enum(StellarSignerType) - -export type StellarSetOptionsOp = Static -export const StellarSetOptionsOp = Type.Object({ -source_account: Type.Optional(Type.String()), -inflation_destination_account: Type.Optional(Type.String()), -clear_flags: Type.Optional(Type.Number()), -set_flags: Type.Optional(Type.Number()), -master_weight: Type.Optional(Type.Uint()), -low_threshold: Type.Optional(Type.Uint()), -medium_threshold: Type.Optional(Type.Uint()), -high_threshold: Type.Optional(Type.Uint()), -home_domain: Type.Optional(Type.String()), -signer_type: Type.Optional(EnumStellarSignerType), -signer_key: Type.Optional(Type.Union([ -Type.Buffer(), -Type.String() -])), -signer_weight: Type.Optional(Type.Number()) -}, {"$id":"StellarSetOptionsOp"}) - -export type StellarChangeTrustOp = Static -export const StellarChangeTrustOp = Type.Object({ -source_account: Type.Optional(Type.String()), -asset: StellarAsset, -limit: Type.Uint() -}, {"$id":"StellarChangeTrustOp"}) - -export type StellarAllowTrustOp = Static -export const StellarAllowTrustOp = Type.Object({ -source_account: Type.Optional(Type.String()), -trusted_account: Type.String(), -asset_type: EnumStellarAssetType, -asset_code: Type.Optional(Type.String()), -is_authorized: Type.Boolean() -}, {"$id":"StellarAllowTrustOp"}) - -export type StellarAccountMergeOp = Static -export const StellarAccountMergeOp = Type.Object({ -source_account: Type.Optional(Type.String()), -destination_account: Type.String() -}, {"$id":"StellarAccountMergeOp"}) - -export type StellarManageDataOp = Static -export const StellarManageDataOp = Type.Object({ -source_account: Type.Optional(Type.String()), -key: Type.String(), -value: Type.Optional(Type.Union([ -Type.Buffer(), -Type.String() -])) -}, {"$id":"StellarManageDataOp"}) - -export type StellarBumpSequenceOp = Static -export const StellarBumpSequenceOp = Type.Object({ -source_account: Type.Optional(Type.String()), -bump_to: Type.Uint() -}, {"$id":"StellarBumpSequenceOp"}) - -export type StellarClaimClaimableBalanceOp = Static -export const StellarClaimClaimableBalanceOp = Type.Object({ -source_account: Type.Optional(Type.String()), -balance_id: Type.String() -}, {"$id":"StellarClaimClaimableBalanceOp"}) - -export type StellarSignedTx = Static -export const StellarSignedTx = Type.Object({ -public_key: Type.String(), -signature: Type.String() -}, {"$id":"StellarSignedTx"}) - -export type TezosGetAddress = Static -export const TezosGetAddress = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"TezosGetAddress"}) - -export type TezosAddress = Static -export const TezosAddress = Type.Object({ -address: Type.String() -}, {"$id":"TezosAddress"}) - -export type TezosGetPublicKey = Static -export const TezosGetPublicKey = Type.Object({ -address_n: Type.Array(Type.Number()), -show_display: Type.Optional(Type.Boolean()), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"TezosGetPublicKey"}) - -export type TezosPublicKey = Static -export const TezosPublicKey = Type.Object({ -public_key: Type.String() -}, {"$id":"TezosPublicKey"}) - -export enum TezosContractType { Implicit = 0, Originated = 1 } - -export type EnumTezosContractType = Static -export const EnumTezosContractType = Type.Enum(TezosContractType) - -export type TezosContractID = Static -export const TezosContractID = Type.Object({ -tag: Type.Number(), -hash: Type.Uint8Array() -}, {"$id":"TezosContractID"}) - -export type TezosRevealOp = Static -export const TezosRevealOp = Type.Object({ -source: Type.Uint8Array(), -fee: Type.Uint(), -counter: Type.Number(), -gas_limit: Type.Number(), -storage_limit: Type.Number(), -public_key: Type.Uint8Array() -}, {"$id":"TezosRevealOp"}) - -export type TezosManagerTransfer = Static -export const TezosManagerTransfer = Type.Object({ -destination: TezosContractID, -amount: Type.Uint() -}, {"$id":"TezosManagerTransfer"}) - -export type TezosParametersManager = Static -export const TezosParametersManager = Type.Object({ -set_delegate: Type.Optional(Type.Uint8Array()), -cancel_delegate: Type.Optional(Type.Boolean()), -transfer: Type.Optional(TezosManagerTransfer) -}, {"$id":"TezosParametersManager"}) - -export type TezosTransactionOp = Static -export const TezosTransactionOp = Type.Object({ -source: Type.Uint8Array(), -fee: Type.Uint(), -counter: Type.Number(), -gas_limit: Type.Number(), -storage_limit: Type.Number(), -amount: Type.Uint(), -destination: TezosContractID, -parameters: Type.Optional(Type.Array(Type.Number())), -parameters_manager: Type.Optional(TezosParametersManager) -}, {"$id":"TezosTransactionOp"}) - -export type TezosOriginationOp = Static -export const TezosOriginationOp = Type.Object({ -source: Type.Uint8Array(), -fee: Type.Uint(), -counter: Type.Number(), -gas_limit: Type.Number(), -storage_limit: Type.Number(), -manager_pubkey: Type.Optional(Type.String()), -balance: Type.Number(), -spendable: Type.Optional(Type.Boolean()), -delegatable: Type.Optional(Type.Boolean()), -delegate: Type.Optional(Type.Uint8Array()), -script: Type.Union([ -Type.String(), -Type.Array(Type.Number()) -]) -}, {"$id":"TezosOriginationOp"}) - -export type TezosDelegationOp = Static -export const TezosDelegationOp = Type.Object({ -source: Type.Uint8Array(), -fee: Type.Uint(), -counter: Type.Number(), -gas_limit: Type.Number(), -storage_limit: Type.Number(), -delegate: Type.Uint8Array() -}, {"$id":"TezosDelegationOp"}) - -export type TezosProposalOp = Static -export const TezosProposalOp = Type.Object({ -source: Type.String(), -period: Type.Number(), -proposals: Type.Array(Type.String()) -}, {"$id":"TezosProposalOp"}) - -export enum TezosBallotType { Yay = 0, Nay = 1, Pass = 2 } - -export type EnumTezosBallotType = Static -export const EnumTezosBallotType = Type.Enum(TezosBallotType) - -export type TezosBallotOp = Static -export const TezosBallotOp = Type.Object({ -source: Type.String(), -period: Type.Number(), -proposal: Type.String(), -ballot: EnumTezosBallotType -}, {"$id":"TezosBallotOp"}) - -export type TezosSignTx = Static -export const TezosSignTx = Type.Object({ -address_n: Type.Array(Type.Number()), -branch: Type.Uint8Array(), -reveal: Type.Optional(TezosRevealOp), -transaction: Type.Optional(TezosTransactionOp), -origination: Type.Optional(TezosOriginationOp), -delegation: Type.Optional(TezosDelegationOp), -proposal: Type.Optional(TezosProposalOp), -ballot: Type.Optional(TezosBallotOp), -chunkify: Type.Optional(Type.Boolean()) -}, {"$id":"TezosSignTx"}) - -export type TezosSignedTx = Static -export const TezosSignedTx = Type.Object({ -signature: Type.String(), -sig_op_contents: Type.String(), -operation_hash: Type.String() -}, {"$id":"TezosSignedTx"}) - -export type experimental_message = Static -export const experimental_message = Type.Object({ - -}, {"$id":"experimental_message"}) - -export type experimental_field = Static -export const experimental_field = Type.Object({ - -}, {"$id":"experimental_field"}) - -export type MessageType = Static -export const MessageType = Type.Object({ -BinanceGetAddress: BinanceGetAddress, -BinanceAddress: BinanceAddress, -BinanceGetPublicKey: BinanceGetPublicKey, -BinancePublicKey: BinancePublicKey, -BinanceSignTx: BinanceSignTx, -BinanceTxRequest: BinanceTxRequest, -BinanceCoin: BinanceCoin, -BinanceInputOutput: BinanceInputOutput, -BinanceTransferMsg: BinanceTransferMsg, -BinanceOrderMsg: BinanceOrderMsg, -BinanceCancelMsg: BinanceCancelMsg, -BinanceSignedTx: BinanceSignedTx, -HDNodeType: HDNodeType, -HDNodePathType: HDNodePathType, -MultisigRedeemScriptType: MultisigRedeemScriptType, -GetPublicKey: GetPublicKey, -PublicKey: PublicKey, -GetAddress: GetAddress, -Address: Address, -GetOwnershipId: GetOwnershipId, -OwnershipId: OwnershipId, -SignMessage: SignMessage, -MessageSignature: MessageSignature, -VerifyMessage: VerifyMessage, -CoinJoinRequest: CoinJoinRequest, -SignTx: SignTx, -TxRequestDetailsType: TxRequestDetailsType, -TxRequestSerializedType: TxRequestSerializedType, -TxRequest: TxRequest, -TxInputType: TxInputType, -TxOutputBinType: TxOutputBinType, -TxOutputType: TxOutputType, -PrevTx: PrevTx, -PrevInput: PrevInput, -PrevOutput: PrevOutput, -TextMemo: TextMemo, -RefundMemo: RefundMemo, -CoinPurchaseMemo: CoinPurchaseMemo, -PaymentRequestMemo: PaymentRequestMemo, -TxAckPaymentRequest: TxAckPaymentRequest, -TxAck: TxAck, -TxAckInputWrapper: TxAckInputWrapper, -TxAckInput: TxAckInput, -TxAckOutputWrapper: TxAckOutputWrapper, -TxAckOutput: TxAckOutput, -TxAckPrevMeta: TxAckPrevMeta, -TxAckPrevInputWrapper: TxAckPrevInputWrapper, -TxAckPrevInput: TxAckPrevInput, -TxAckPrevOutputWrapper: TxAckPrevOutputWrapper, -TxAckPrevOutput: TxAckPrevOutput, -TxAckPrevExtraDataWrapper: TxAckPrevExtraDataWrapper, -TxAckPrevExtraData: TxAckPrevExtraData, -GetOwnershipProof: GetOwnershipProof, -OwnershipProof: OwnershipProof, -AuthorizeCoinJoin: AuthorizeCoinJoin, -FirmwareErase: FirmwareErase, -FirmwareRequest: FirmwareRequest, -FirmwareUpload: FirmwareUpload, -SelfTest: SelfTest, -CardanoBlockchainPointerType: CardanoBlockchainPointerType, -CardanoNativeScript: CardanoNativeScript, -CardanoGetNativeScriptHash: CardanoGetNativeScriptHash, -CardanoNativeScriptHash: CardanoNativeScriptHash, -CardanoAddressParametersType: CardanoAddressParametersType, -CardanoGetAddress: CardanoGetAddress, -CardanoAddress: CardanoAddress, -CardanoGetPublicKey: CardanoGetPublicKey, -CardanoPublicKey: CardanoPublicKey, -CardanoSignTxInit: CardanoSignTxInit, -CardanoTxInput: CardanoTxInput, -CardanoTxOutput: CardanoTxOutput, -CardanoAssetGroup: CardanoAssetGroup, -CardanoToken: CardanoToken, -CardanoTxInlineDatumChunk: CardanoTxInlineDatumChunk, -CardanoTxReferenceScriptChunk: CardanoTxReferenceScriptChunk, -CardanoPoolOwner: CardanoPoolOwner, -CardanoPoolRelayParameters: CardanoPoolRelayParameters, -CardanoPoolMetadataType: CardanoPoolMetadataType, -CardanoPoolParametersType: CardanoPoolParametersType, -CardanoTxCertificate: CardanoTxCertificate, -CardanoTxWithdrawal: CardanoTxWithdrawal, -CardanoCVoteRegistrationDelegation: CardanoCVoteRegistrationDelegation, -CardanoCVoteRegistrationParametersType: CardanoCVoteRegistrationParametersType, -CardanoTxAuxiliaryData: CardanoTxAuxiliaryData, -CardanoTxMint: CardanoTxMint, -CardanoTxCollateralInput: CardanoTxCollateralInput, -CardanoTxRequiredSigner: CardanoTxRequiredSigner, -CardanoTxReferenceInput: CardanoTxReferenceInput, -CardanoTxItemAck: CardanoTxItemAck, -CardanoTxAuxiliaryDataSupplement: CardanoTxAuxiliaryDataSupplement, -CardanoTxWitnessRequest: CardanoTxWitnessRequest, -CardanoTxWitnessResponse: CardanoTxWitnessResponse, -CardanoTxHostAck: CardanoTxHostAck, -CardanoTxBodyHash: CardanoTxBodyHash, -CardanoSignTxFinished: CardanoSignTxFinished, -Success: Success, -Failure: Failure, -ButtonRequest: ButtonRequest, -ButtonAck: ButtonAck, -PinMatrixRequest: PinMatrixRequest, -PinMatrixAck: PinMatrixAck, -PassphraseRequest: PassphraseRequest, -PassphraseAck: PassphraseAck, -Deprecated_PassphraseStateRequest: Deprecated_PassphraseStateRequest, -Deprecated_PassphraseStateAck: Deprecated_PassphraseStateAck, -CipherKeyValue: CipherKeyValue, -CipheredKeyValue: CipheredKeyValue, -IdentityType: IdentityType, -SignIdentity: SignIdentity, -SignedIdentity: SignedIdentity, -GetECDHSessionKey: GetECDHSessionKey, -ECDHSessionKey: ECDHSessionKey, -DebugLinkResetDebugEvents: DebugLinkResetDebugEvents, -EosGetPublicKey: EosGetPublicKey, -EosPublicKey: EosPublicKey, -EosTxHeader: EosTxHeader, -EosSignTx: EosSignTx, -EosTxActionRequest: EosTxActionRequest, -EosAsset: EosAsset, -EosPermissionLevel: EosPermissionLevel, -EosAuthorizationKey: EosAuthorizationKey, -EosAuthorizationAccount: EosAuthorizationAccount, -EosAuthorizationWait: EosAuthorizationWait, -EosAuthorization: EosAuthorization, -EosActionCommon: EosActionCommon, -EosActionTransfer: EosActionTransfer, -EosActionDelegate: EosActionDelegate, -EosActionUndelegate: EosActionUndelegate, -EosActionRefund: EosActionRefund, -EosActionBuyRam: EosActionBuyRam, -EosActionBuyRamBytes: EosActionBuyRamBytes, -EosActionSellRam: EosActionSellRam, -EosActionVoteProducer: EosActionVoteProducer, -EosActionUpdateAuth: EosActionUpdateAuth, -EosActionDeleteAuth: EosActionDeleteAuth, -EosActionLinkAuth: EosActionLinkAuth, -EosActionUnlinkAuth: EosActionUnlinkAuth, -EosActionNewAccount: EosActionNewAccount, -EosActionUnknown: EosActionUnknown, -EosTxActionAck: EosTxActionAck, -EosSignedTx: EosSignedTx, -EthereumNetworkInfo: EthereumNetworkInfo, -EthereumTokenInfo: EthereumTokenInfo, -EthereumDefinitions: EthereumDefinitions, -EthereumSignTypedData: EthereumSignTypedData, -EthereumTypedDataStructRequest: EthereumTypedDataStructRequest, -EthereumFieldType: EthereumFieldType, -EthereumStructMember: EthereumStructMember, -EthereumTypedDataStructAck: EthereumTypedDataStructAck, -EthereumTypedDataValueRequest: EthereumTypedDataValueRequest, -EthereumTypedDataValueAck: EthereumTypedDataValueAck, -EthereumGetPublicKey: EthereumGetPublicKey, -EthereumPublicKey: EthereumPublicKey, -EthereumGetAddress: EthereumGetAddress, -EthereumAddress: EthereumAddress, -EthereumSignTx: EthereumSignTx, -EthereumAccessList: EthereumAccessList, -EthereumSignTxEIP1559: EthereumSignTxEIP1559, -EthereumTxRequest: EthereumTxRequest, -EthereumTxAck: EthereumTxAck, -EthereumSignMessage: EthereumSignMessage, -EthereumMessageSignature: EthereumMessageSignature, -EthereumVerifyMessage: EthereumVerifyMessage, -EthereumSignTypedHash: EthereumSignTypedHash, -EthereumTypedDataSignature: EthereumTypedDataSignature, -Initialize: Initialize, -GetFeatures: GetFeatures, -Features: Features, -LockDevice: LockDevice, -SetBusy: SetBusy, -EndSession: EndSession, -ApplySettings: ApplySettings, -ApplyFlags: ApplyFlags, -ChangePin: ChangePin, -ChangeWipeCode: ChangeWipeCode, -SdProtect: SdProtect, -Ping: Ping, -Cancel: Cancel, -GetEntropy: GetEntropy, -Entropy: Entropy, -GetFirmwareHash: GetFirmwareHash, -FirmwareHash: FirmwareHash, -AuthenticateDevice: AuthenticateDevice, -AuthenticityProof: AuthenticityProof, -WipeDevice: WipeDevice, -ResetDevice: ResetDevice, -BackupDevice: BackupDevice, -EntropyRequest: EntropyRequest, -EntropyAck: EntropyAck, -RecoveryDevice: RecoveryDevice, -WordRequest: WordRequest, -WordAck: WordAck, -SetU2FCounter: SetU2FCounter, -GetNextU2FCounter: GetNextU2FCounter, -NextU2FCounter: NextU2FCounter, -DoPreauthorized: DoPreauthorized, -PreauthorizedRequest: PreauthorizedRequest, -CancelAuthorization: CancelAuthorization, -RebootToBootloader: RebootToBootloader, -GetNonce: GetNonce, -Nonce: Nonce, -UnlockPath: UnlockPath, -UnlockedPathRequest: UnlockedPathRequest, -ShowDeviceTutorial: ShowDeviceTutorial, -UnlockBootloader: UnlockBootloader, -NEMGetAddress: NEMGetAddress, -NEMAddress: NEMAddress, -NEMTransactionCommon: NEMTransactionCommon, -NEMMosaic: NEMMosaic, -NEMTransfer: NEMTransfer, -NEMProvisionNamespace: NEMProvisionNamespace, -NEMMosaicDefinition: NEMMosaicDefinition, -NEMMosaicCreation: NEMMosaicCreation, -NEMMosaicSupplyChange: NEMMosaicSupplyChange, -NEMCosignatoryModification: NEMCosignatoryModification, -NEMAggregateModification: NEMAggregateModification, -NEMImportanceTransfer: NEMImportanceTransfer, -NEMSignTx: NEMSignTx, -NEMSignedTx: NEMSignedTx, -NEMDecryptMessage: NEMDecryptMessage, -NEMDecryptedMessage: NEMDecryptedMessage, -RippleGetAddress: RippleGetAddress, -RippleAddress: RippleAddress, -RipplePayment: RipplePayment, -RippleSignTx: RippleSignTx, -RippleSignedTx: RippleSignedTx, -SolanaGetPublicKey: SolanaGetPublicKey, -SolanaPublicKey: SolanaPublicKey, -SolanaGetAddress: SolanaGetAddress, -SolanaAddress: SolanaAddress, -SolanaSignTx: SolanaSignTx, -SolanaTxSignature: SolanaTxSignature, -StellarAsset: StellarAsset, -StellarGetAddress: StellarGetAddress, -StellarAddress: StellarAddress, -StellarSignTx: StellarSignTx, -StellarTxOpRequest: StellarTxOpRequest, -StellarPaymentOp: StellarPaymentOp, -StellarCreateAccountOp: StellarCreateAccountOp, -StellarPathPaymentStrictReceiveOp: StellarPathPaymentStrictReceiveOp, -StellarPathPaymentStrictSendOp: StellarPathPaymentStrictSendOp, -StellarManageSellOfferOp: StellarManageSellOfferOp, -StellarManageBuyOfferOp: StellarManageBuyOfferOp, -StellarCreatePassiveSellOfferOp: StellarCreatePassiveSellOfferOp, -StellarSetOptionsOp: StellarSetOptionsOp, -StellarChangeTrustOp: StellarChangeTrustOp, -StellarAllowTrustOp: StellarAllowTrustOp, -StellarAccountMergeOp: StellarAccountMergeOp, -StellarManageDataOp: StellarManageDataOp, -StellarBumpSequenceOp: StellarBumpSequenceOp, -StellarClaimClaimableBalanceOp: StellarClaimClaimableBalanceOp, -StellarSignedTx: StellarSignedTx, -TezosGetAddress: TezosGetAddress, -TezosAddress: TezosAddress, -TezosGetPublicKey: TezosGetPublicKey, -TezosPublicKey: TezosPublicKey, -TezosContractID: TezosContractID, -TezosRevealOp: TezosRevealOp, -TezosManagerTransfer: TezosManagerTransfer, -TezosParametersManager: TezosParametersManager, -TezosTransactionOp: TezosTransactionOp, -TezosOriginationOp: TezosOriginationOp, -TezosDelegationOp: TezosDelegationOp, -TezosProposalOp: TezosProposalOp, -TezosBallotOp: TezosBallotOp, -TezosSignTx: TezosSignTx, -TezosSignedTx: TezosSignedTx, -experimental_message: experimental_message, -experimental_field: experimental_field -}, {"$id":"MessageType"}) - -// custom type uint32/64 may be represented as string -export type UintType = string | number; - -export type MessageKey = keyof MessageType; - -export type MessageResponse = { - type: T; - message: MessageType[T]; -}; - -export type TypedCall = ( - type: T, - resType: R, - message?: MessageType[T], -) => Promise>; -" -`; diff --git a/packages/schema-utils/tests/codegen.test.ts b/packages/schema-utils/tests/codegen.test.ts deleted file mode 100644 index 3e311afc9f..0000000000 --- a/packages/schema-utils/tests/codegen.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { generateForFile } from '../src/codegen'; - -describe('codegen', () => { - it('should generate code for protobuf messages example', () => { - const output = generateForFile(`${__dirname}/__snapshots__/codegen.input.ts`); - expect(output).toMatchSnapshot(); - }); -}); diff --git a/packages/suite-data/files/images/png/create-shamir-group.png b/packages/suite-data/files/images/png/create-shamir-group.png new file mode 100644 index 0000000000000000000000000000000000000000..6788429db23253fe66cc17ae3c0d67e1bff197d7 GIT binary patch literal 16481 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 literal 0 HcmV?d00001 diff --git a/packages/suite-data/files/images/png/shamir-shares.png b/packages/suite-data/files/images/png/shamir-shares.png new file mode 100644 index 0000000000000000000000000000000000000000..d315224553deb68bbb945ad49eb3fdf570be13dc GIT binary patch literal 5731 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 V6EV-kU2^~c002ovPDHLkV1nVCTDkxL literal 0 HcmV?d00001 diff --git a/packages/suite-data/files/images/png/shamir-shares@2x.png b/packages/suite-data/files/images/png/shamir-shares@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2f42a04789a71b3aa8e13385b7b4058d141e7552 GIT binary patch literal 12774 zcmb7KRZtvEkY3!~7I(LWK!Ow8-7PHc5;VBG`(lCM?(XiA;O-FIT`zytyo+NJWNk_gtDR(8Zr?w002Ofkrr140ARuY@CYKzzcK!|1quKFeXcC8F7aedJ0E8(6LKSxY{sn|6K!qy61Sy?AJ-@!b{#$x`e^>Au#PU)5j~1%%_V!Ql{_^q+ z6{@)0m;X=sPr{#`FCHG`ZRq})Pp_>4LKXi3xDX9Mh+r%6UWxSH9 zN9e|Qvyf%c^Yb&eZd~c(YsJ-N<@2jksB&|b8n4N(e=a=|2!HQ8J#`ey}rKuIobJ`U?)p5 z*}6H?t&IsAt`x}o@%ZvozdrdkM1Ql^(6_f})sl94dh(+?FKF{a+^NaB@BVKE(L*;? z!9w5pLKSPK-FZE!Tv?#2tLs32ze&f{_GHOTE7`%Himd{Itn4fS^P>B^yT|S3#pT7R zM1r=q*0(8P@3&iw7;TJb?Zr&|fiUcpsTQfw@}i=m$;nA;TbtWH{>xToF1@sxni^)M zu+*vMm+hGFi15Uu#OM8=+dJE>KA0Us-1ieYnfeG|E|Tb-kJqDiUtiz65bG)j)QPh2 zR2L0T0lJrE^OyVMw^@bPt0h3N{P*g)-KXWZi_&06{URQAe<@hQtkL(&;n~KtyE*TC z3pCZ(n*N%sIVpYz5LL=l^UtKfXm49O2Buh5xcIjt|Bj8@I=QHkqt=(z>F2qs1dl*H zv7=syC===1<`0ij#r)UZV@Q&H5c2n35eGW z<;r`i`Iokv7qq(fjg;02X13VgM`OLQIt6BH$gfXVWOb$^Sj)_dDnN1`f=eMNHfv)s&-XbvvC_ok@P^c> zljANJ+c|8Y#_-6UqihHstugp(4 z`AYRB+$wkw(@#lKiY2PIXv3JN``(}$H7zX7`*!HmikQ;~TYb^Y{YTpvo9uT70`}p_ zp?jLC%IGwcLO#O}ChDTP;#y~J@3fQLz?DDd(ov&_;)8j~nw{y_jVb&uk4u$b{7NqS z!6)XA-w5WJIbvKsjVvF!cyP=SRmk`)wKmN)1u!s4zgnIpwkbL?1Qc-bA7V=`Qkcph z(mcrlmkp^P{%Dld!Nsvt5`keX4bxYy^F5InbKKI@jmE(A&M!x zCx`v+)LNAGx6?kqtm@4!X*B;yL=8oYAj>-eo5LcbtmIpc+f>}=xW1SBqty>_F(jKO z&c;Hr4!Lh$%0DsobI@zu)$6L-RjOMz){B)lE~q|XAGcN5IFxcJ z9@kv+XoVUryc!=CUMld0iulMx=VRPXpO<~J`K3@RYf#u-C6J{K=t<~Gz85dmujyYB z?g43q8=4XxsH(xoC^}a|-bs(Lgo>9|%1EJyE0}e<*f7Kj|Ccz-I>7FPn*Te(>9`P4 z%GCKe?SQby1^jexaM*UfZm{W8ifeujMerKBfnk;m8%T0!@ViyVO3)C!}fci^huC#tgwI^Lz^8Tk8T97!YqQHmxDLe?P@>*w1g_LU;7} z&*^7@oNNz?`DvoSKe_{$AIz(F2NKU0y_w47cD`UIMDyk=>kS1*rTf5hkhFIXKj8BA zr_IY0E-Z)IUOIe(g6eKoiliQOz}=RcHMv_gw*(pn>7EfzoKd_8Q&B3KJszhFDMQfE+1|$U>Md;^s^tcbs8fzbijYQQ#rsvp4wIfT4%{>9qh9Cm6g?K_&a|SZd?5 zXkH@5sn8lU@`7Fv-wo!YkS-H*fu!F34pUlr->!1e881!G^nPH;AZQqHnPn18^%5Yrq$%>{vhsr@tPKhV?I}~ib!8LwE5@hU-;3h_Fv4c zr6ENAwAb)G$scXX6R1CscA@oukDtjQbeKNNUyqlxhyo(L-Rc;?6ReUWhx;5yVs3RZ z7oz6;px)OI-JL-Oa0tY;ow-Z{`80m*v|>5I!1>gf9eyya4op_^l@$Ie%G>!{iqOO; z{kyEtE0-viMKJQpPoFH(^L~_{)4xk zci=ax=4Wg|9V;MCAibJ^YYl)!tdB^@7MHiUl-m=tndCyHNY&pZx*%9e6kR5+g)(tF zUxsT){7{_mRvXzDJ3@#Z``D zHw0zI6rxRQLc{mW_rYagx?nK%_PSI)WR;=)x(`m|pZ+}FuW-pl7K8tAwaaOQ8$EcU zlsE$zO4MYr=lt!nH9c9}#T-ht0ozoN`?-dO{^@&_F{@29X9{$I2@RgW42Pmi05R1a zidKT7`L5bc2igEb?~ew2#_@T_4c0z=`J1?gZsZP#+M4Y?v1QS(sj4N(O5TxcioI_4 zTS3*7?^|W9h<%(hOk1=VgfKZlU!;{i`|^6o%B9^7;02W12T89gwcVUKNZ81CUk1-C zKchnrg^ry3wDv=4ao6mK3?jCSB`U-WP{?s6(268&7ulpXxJWA9GArP5j~-y~sTje~ zr-CBNlL%n-noqSm?G`2~$>Pt0cm++j+rZ-3E9A!kv9o+K^e22D8T&b|KtH)3xP!iL9{ zWzMqe>H54+Q~c6qMKEWF{8V~l_g&?k4>5GeFU`>^3(Wv^O*D8T>BTuz96Uihg$gYu z4<~%^j=Hf8v81$1T+yc@_sqcwXV*)2+R8|mmQYZ`WCM37^)ht zwt0iH2(^^wL|Y+gy}jGM3f~xaW7zl9!lr~VX;y7rXFnW{@7Fcxd|SgXkg1hhd(JBK zcQ!g#*(Ou)J(#hK9)kbcO}lkiMx&9>bF6=YN$CE;x{}6VprAEcv5mhP;iSO&@T0ak zQOsI|CUn4n-;ye1u$o1MN2<3qh=!5as_Q2RQ+2?pxVF^#w1-72ddJeKvcWk%K2zDr zRCTZd%&$^as%PxBq{dhu5zu2)KtgE~$Rl?=|AEC8{LZ;ZR3wzhB~z07ixG%nm7cPin`~o^VZ!xi&2I>ms1xW|>JfnC zY(B$E$I~eb0gLlvGGhxaG>j9!Hir#+VNZW>Eb`GvI)7~tLls46JWHnevU7pr9)1A5 z*H!JuhaS`J77x~xaj5Z(Fz{z?$-?e!h~>2pjuck{4eh`Kvy|SQs~V%+G6}@_59lx< zxU}ATl)WYSt(J_HO*|x0?RvqY$FVr54RhcNxdK|dW|Y7r=r)GY*L37QfOHa!p0jAE zS99xrx;|y=N4(7--74J-Q3RGeB8`$Xxj`%q?P|nj0>aDm+@G~IctuuF%Z|3!%e%kP z#H!3!(ASU1hIMQXOBo1w#r5RjQW#Di9kHM;j+_X-&h0Yzoo`XLlM-r^-Kl`D?X)|w z3OJGXA_?8=A2U#DX5#Tsord*g@OJ(l|5y+v_#wY{H+YxoN5ndul^D-@pt^05kwhKV zFtHvIT`$s5w92Gl0gW`-di-vpL1JJbIlo$00zTL45A`#xzY zGN(P`?~K*t29h?uh}aWGlqOx)Lf>==||H(I?}w|3AYZIU_yUIQ(}XN6=U0}VuKHB?MSE3KI< zV88YjrEim!1-2x_bDX!@19bC6G$l>;2<5d?VOi%nwya2sT5n^%cj_{@;3J0w=u$TR ztQ|*+)2%W%IXNlUEKfPZlUl<3G{Mpzjjx2jmHk}_MoJs?9Xqx+x)DG;7Upvwzu-MC z=kcY-r2r|g_fNNhUxJO@KFN&EwE^&euUNIH zQ_UB4W9o%volAAqXEqapDb}~sYSfgo)lX9xeTlC1I*+5TkPwk zY(5IaI?!z zgq`B~D)h%Z=r4P=CNG2X+Q{!SXIHUV#&CHRW4#py)CyAAR1kA5Qmj-Q%c>u+sI-9z z*48de?u=S?qd31*cA`*eh>>jeV9`xNrauq+=l->AKb5uX!RIDuSF1-CUsfv z;9mWH)K7urz(7yZxynm#5;GJmU65(hi#(|XoC$N)ll|%%y*Nmyu%8v0Q@^TDXJ zx%mP7xpAFR4D_0ac=h9U8IE^|*%svVl`BHXyr@tDI?pxoyS19T`ZUfVENxtQ2Ywfd zbLHe%@*8pjFSH9cxBYTV^&DGpZTn8fi=UJmWLR8|n=b5YpiBqj{*A?E4O5Xi%N<$A zgySXH!J!l~Y5wrHzBFJ{jaBj~L`tH6r@&4%xk{R&g)+-B+NSJIsb|=}rzn*fxK`KR zAi>D8-iKq^q8Rcpb4p2(P>?~yALO|dRpFMaIS}0pEp~t?MFXicWaIE|O;h~a-u|hS zjx+t-g>Su6ICJHsIXg7nzAyT56050`3w93!*95^H(cOxnAmN=1Vj>kQ-|ei2<%2|_ zmKDo|*^qYCj3-HT=lNy5ZoiCO?&I7vBXkq}>=(Pz}Z& zU#MKIH5qPOOh5PLJLo^T8ZxdxNwRyC`t?1K@a$pJ?%vT>F05n(lo>vC9Q(=|cTTeP zV-QYh`Hv&2d*vd{mOcju6UFAUf2-yq+J{WlynVi>g=+hjs6H>=`)WZp+H0Qw)3*!p z!vDN&RO>ZI8?Cp65ypY}{C+KYU2eT=wFZ^fIz2+BJJH{jaAq=%$=Q;$T6^* zfn@jKH%@V&d0C(23@BP0#Q)8-{z$v1p?i)7;#~_-Dpo6Oe>bb^k9Nq;7?M?;s~Q&W z@_u<*sBF%$SpRsoo75!c=ip)JG5lC29ilv5WiA$26ZjaLt^A8Y((-I(BX`loir(*1 zkkGy;=@E!X8~48Ovj3jY#rgG)tw5S1H-W;c*uS#eP}(k;gjdl*+qlBrg1I+~#oV}X z7UAJ9Kd*7RI^PiR@AlXF)jd2AJOljV!YX#Rcz3t={ps@R^l3A_gJ53z9Tz1i+OB-y zdw5@2=;)67^+^&1t$EDPMU-%eQkiZ8<++vTMe z!W<1nyA^11lJNDG^E$j z9~w1%kRZkWciOPi<*4W%n96QzP|=hwf7+iDKuA(klp=C0HOe3|ExlfNQHE$0*750n zuXthv8koS%1n zFqQu*uguc4kO%b%?8%+Cmi(1Qn+r%0AHK6CyA{rl*@CwJ*MF2fE=MvjJRF)fbtO*t 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 vj^90?7G9E1?F async (dispatch: Dispatch, getState: GetState) => { } const response = await TrezorConnect.recoveryDevice({ - dry_run: true, - type: advancedRecovery ? 1 : 0, + type: device.features.recovery_type ?? 'DryRun', // For old firmware, we assume DryRun as it was the only option before + input_method: advancedRecovery + ? PROTO.RecoveryDeviceInputMethod.Matrix + : PROTO.RecoveryDeviceInputMethod.ScrambledWords, word_count: wordsCount, enforce_wordlist: true, device: { @@ -105,7 +108,10 @@ const recoverDevice = () => async (dispatch: Dispatch, getState: GetState) => { } const params: RecoveryDevice = { - type: advancedRecovery ? 1 : 0, + type: device.features.recovery_type ?? 'NormalRecovery', // For old firmware, we assume NormalRecovery as it was the only option before + input_method: advancedRecovery + ? PROTO.RecoveryDeviceInputMethod.Matrix + : PROTO.RecoveryDeviceInputMethod.ScrambledWords, word_count: wordsCount, passphrase_protection: DEFAULT_PASSPHRASE_PROTECTION, enforce_wordlist: true, @@ -167,7 +173,7 @@ const rerun = () => async (dispatch: Dispatch, getState: GetState) => { const features = response.payload; - if (!features.recovery_mode) { + if (!isRecoveryInProgress(features)) { return; } diff --git a/packages/suite/src/components/firmware/CheckSeedStep.tsx b/packages/suite/src/components/firmware/CheckSeedStep.tsx index 45690c96c1..cedd088c32 100644 --- a/packages/suite/src/components/firmware/CheckSeedStep.tsx +++ b/packages/suite/src/components/firmware/CheckSeedStep.tsx @@ -49,7 +49,9 @@ export const CheckSeedStep = ({ onClose, onSuccess, willBeWiped }: CheckSeedStep const handleCheckboxClick = () => setIsChecked(prev => !prev); const getContent = () => { - const isBackedUp = !device?.features?.needs_backup && !device?.features?.unfinished_backup; + const isBackedUp = + device?.features?.backup_availability !== 'Required' && + !device?.features?.unfinished_backup; const noBackupHeading = ( { export const LearnMoreButton = ({ children, - url, className, + size = 'tiny', + url, ...buttonProps }: LearnMoreButtonProps) => ( + + + ), + }; + + case 'second-info': + const enterBackup = async () => { + setStep('verify-ownership'); + + const response = await TrezorConnect.recoveryDevice({ + type: 'UnlockRepeatedBackup', + input_method: PROTO.RecoveryDeviceInputMethod.Matrix, + enforce_wordlist: true, + device: { + path: device.path, + }, + }); + + if (response.success) { + setStep('backup-seed'); + TrezorConnect.backupDevice().then(response => { + if (response.success) { + setStep('done'); + } else { + onCancel(); + } + }); + } else { + onCancel(); + } + }; + + return { + heading: , + children: , + bottomBarComponents: ( + <> + + + + + + ), + onBackClick: () => setStep('first-info'), + }; + + case 'verify-ownership': + return { + children: , + heading: , + onCancel: closeWithCancelOnDevice, + }; + + case 'backup-seed': + return { + children: , + heading: , + onCancel: closeWithCancelOnDevice, + }; + + case 'done': + return { + heading: , + children: , + bottomBarComponents: ( + <> + + + + + + ), + }; + } + }; + + return ; +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep1FirstInfo.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep1FirstInfo.tsx new file mode 100644 index 0000000000..acd268531c --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep1FirstInfo.tsx @@ -0,0 +1,76 @@ +import { Dispatch, SetStateAction } from 'react'; +import styled from 'styled-components'; + +import { Checkbox, Image, Paragraph } from '@trezor/components'; +import { spacingsPx } from '@trezor/theme'; + +import { Translation } from 'src/components/suite'; +import { Body, Section } from './multiShareModalLayout'; + +const StyledImage = styled(Image)` + margin-bottom: ${spacingsPx.md}; +`; + +type MultiShareBackupStep1Props = { + isChecked1: boolean; + isChecked2: boolean; + isSubmitted: boolean; + setIsChecked1: Dispatch>; + setIsChecked2: Dispatch>; +}; + +export const MultiShareBackupStep1FirstInfo = ({ + isChecked1, + isChecked2, + isSubmitted, + setIsChecked1, + setIsChecked2, +}: MultiShareBackupStep1Props) => { + const getCheckboxVariant = (isChecked: boolean) => + isSubmitted && !isChecked ? 'destructive' : undefined; + + const checkboxVariant1 = getCheckboxVariant(isChecked1); + const checkboxVariant2 = getCheckboxVariant(isChecked2); + + const toggleCheckbox1 = () => setIsChecked1(prev => !prev); + const toggleCheckbox2 = () => setIsChecked2(prev => !prev); + + return ( + <> + + +
+ + + + +
+
+ + + + +
+
+ + + + + + + + + +
+ + + ); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep2SecondInfo.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep2SecondInfo.tsx new file mode 100644 index 0000000000..c46cdd7307 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep2SecondInfo.tsx @@ -0,0 +1,22 @@ +import { BackupInstructionsStep } from './BackupInstructionsStep'; +import { + InstructionBaseConfig, + createSharesInstruction, + verifyTrezorOwnershipInstruction, +} from './instructionSteps'; + +export const MultiShareBackupStep2SecondInfo = () => { + const instructions: InstructionBaseConfig[] = [ + verifyTrezorOwnershipInstruction, + createSharesInstruction, + ]; + + return instructions.map((content, i) => ( + + )); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep3VerifyOwnership.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep3VerifyOwnership.tsx new file mode 100644 index 0000000000..3da2364a1e --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep3VerifyOwnership.tsx @@ -0,0 +1,27 @@ +import { BackupInstructionsStep } from './BackupInstructionsStep'; +import { + InstructionBaseConfig, + createSharesInstruction, + verifyTrezorOwnershipInstruction, +} from './instructionSteps'; + +export const MultiShareBackupStep3VerifyOwnership = () => { + const instructions: InstructionBaseConfig[] = [ + verifyTrezorOwnershipInstruction, + { + ...createSharesInstruction, + description: undefined, + children: null, + completeness: 'todo', + }, + ]; + + return instructions.map((content, i) => ( + + )); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep4BackupSeed.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep4BackupSeed.tsx new file mode 100644 index 0000000000..a1695a7a1b --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep4BackupSeed.tsx @@ -0,0 +1,27 @@ +import { BackupInstructionsStep } from './BackupInstructionsStep'; +import { + InstructionBaseConfig, + createSharesInstruction, + verifyTrezorOwnershipInstruction, +} from './instructionSteps'; + +export const MultiShareBackupStep4BackupSeed = () => { + const instructions: InstructionBaseConfig[] = [ + { + ...verifyTrezorOwnershipInstruction, + description: undefined, + children: null, + completeness: 'done', + }, + createSharesInstruction, + ]; + + return instructions.map((content, i) => ( + + )); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep5Done.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep5Done.tsx new file mode 100644 index 0000000000..3a66deee90 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupStep5Done.tsx @@ -0,0 +1,135 @@ +import { Card, Row, Icon, Column, Text } from '@trezor/components'; + +import { Translation } from 'src/components/suite'; +import { Body, Section } from './multiShareModalLayout'; +import { borders, spacings, spacingsPx } from '@trezor/theme'; +import { ReactNode } from 'react'; +import { TranslationKey } from '@suite-common/intl-types'; +import styled from 'styled-components'; + +const GradientCallout = styled.div` + background-image: linear-gradient( + to right, + ${({ theme }) => theme.backgroundPrimarySubtleOnElevation1}, + ${({ theme }) => theme.backgroundAlertYellowSubtleOnElevation1} + ); + + border-radius: ${borders.radii.xxs}; + width: 100%; +`; + +const GradientCalloutCard = styled.div` + flex: 1; + padding: ${spacingsPx.lg} ${spacingsPx.md}; +`; + +const IconQuestionMarkWrapper = styled.div` + position: relative; + margin-bottom: ${spacingsPx.xxxl}; +`; + +const IconQuestionMark = styled(Icon)` + position: absolute; + top: -7px; + left: 25px; +`; + +const TextDiv = styled(Text)` + display: block; +`; + +const Callout = ({ items, header }: { items: ReactNode[]; header: TranslationKey }) => ( + + + + + + {items.map((item, i) => ( + + {item} + + ))} + + +); + +export const MultiShareBackupStep5Done = () => ( + +
+ + + + +
+ +
+ + + + + + + + , + <> + + + , + ]} + /> + + + + , + <> + + + , + ]} + /> + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +); diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx new file mode 100644 index 0000000000..73a2e85b0c --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/instructionSteps.tsx @@ -0,0 +1,87 @@ +import { Row } from '@trezor/components'; +import styled from 'styled-components'; + +import { Image, Text } from '@trezor/components'; +import { borders, spacings, spacingsPx } from '@trezor/theme'; +import { ESHOP_KEEP_METAL_URL, HELP_CENTER_SEED_CARD_URL } from '@trezor/urls'; + +import { Translation, TrezorLink } from 'src/components/suite'; +import { BackupInstructionsCard } from './BackupInstructionsCard'; +import { BackupInstructionsStepProps } from './BackupInstructionsStep'; + +const CardWrapper = styled.div` + display: grid; + gap: ${spacingsPx.sm}; + grid-template-columns: repeat(3, 1fr); +`; + +const Illustration = styled.div` + display: flex; + align-items: center; + flex-direction: column; + border: ${borders.widths.small} solid ${({ theme }) => theme.borderElevation0}; + border-radius: ${borders.radii.md}; + padding-bottom: ${spacingsPx.lg}; +`; + +export type InstructionBaseConfig = Pick< + BackupInstructionsStepProps, + 'children' | 'description' | 'heading' | 'time' | 'completeness' +>; + +export const verifyTrezorOwnershipInstruction: InstructionBaseConfig = { + heading: 'TR_VERIFY_TREZOR_OWNERSHIP', + time: 2, + description: 'TR_VERIFY_TREZOR_OWNERSHIP_EXPLANATION', + children: ( + + + + + + + + + ), +}; + +export const createSharesInstruction: InstructionBaseConfig = { + heading: 'TR_CREATE_SHARES', + time: 10, + description: 'TR_CREATE_SHARES_EXPLANATION', + children: ( + <> + + + + + + + + + ( + + {chunks} + + ), + keepLink: chunks => ( + + {chunks} + + ), + }} + /> + + + + + + + + + + ), +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/multiShareModalLayout.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/multiShareModalLayout.tsx new file mode 100644 index 0000000000..573882a1ef --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/MultiShareBackupModal/multiShareModalLayout.tsx @@ -0,0 +1,15 @@ +import { Column } from '@trezor/components'; +import { spacings } from '@trezor/theme'; +import { ReactNode } from 'react'; + +export const Body = ({ children }: { children: ReactNode }) => ( + + {children} + +); + +export const Section = ({ children }: { children: ReactNode }) => ( + + {children} + +); diff --git a/packages/suite/src/components/suite/modals/index.tsx b/packages/suite/src/components/suite/modals/index.tsx index fb653597b1..3d867b1375 100644 --- a/packages/suite/src/components/suite/modals/index.tsx +++ b/packages/suite/src/components/suite/modals/index.tsx @@ -46,3 +46,4 @@ export { StakeEthInANutshellModal } from './ReduxModal/UserContextModal/StakeEth export { StakeModal } from './ReduxModal/UserContextModal/StakeModal/StakeModal'; export { UnstakeModal } from './ReduxModal/UserContextModal/UnstakeModal/UnstakeModal'; export { ClaimModal } from './ReduxModal/UserContextModal/ClaimModal/ClaimModal'; +export { MultiShareBackupModal } from './ReduxModal/UserContextModal/MultiShareBackupModal/MultiShareBackupModal'; diff --git a/packages/suite/src/hooks/suite/usePreferredModal.ts b/packages/suite/src/hooks/suite/usePreferredModal.ts index c8d02d7b6e..6cd37b033b 100644 --- a/packages/suite/src/hooks/suite/usePreferredModal.ts +++ b/packages/suite/src/hooks/suite/usePreferredModal.ts @@ -8,22 +8,26 @@ import { ModalAppParams } from 'src/utils/suite/router'; const isForegroundApp = (route: Route): route is ForegroundAppRoute => !route.isFullscreenApp && !!route.isForegroundApp; -// Firmware, FirmwareCustom, Bridge, Udev, Version - always beats redux modals -// Backup, SwitchDevice - always get beaten by redux modals -// Recovery - beats redux modals with some exceptions (raw-rendered) const hasPriority = (route: ForegroundAppRoute) => { - switch (route.app) { - case 'bridge': - case 'firmware': - case 'firmware-type': - case 'firmware-custom': - case 'recovery': - case 'udev': - case 'version': - return true; - default: - return false; - } + const map: Record = { + // Firmware, FirmwareCustom, Bridge, Udev, Version, Create New Multi-share Backup - always beats redux modals + firmware: true, + 'firmware-type': true, + 'firmware-custom': true, + bridge: true, + udev: true, + version: true, + 'create-multi-share-backup': true, + + // Recovery - beats redux modals with some exceptions (raw-rendered) + recovery: true, + + // Backup, SwitchDevice - always get beaten by redux modals + 'switch-device': false, + backup: false, + }; + + return map[route.app]; }; const getForegroundAppAction = (route: ForegroundAppRoute, params: Partial) => diff --git a/packages/suite/src/middlewares/recovery/recoveryMiddleware.ts b/packages/suite/src/middlewares/recovery/recoveryMiddleware.ts index 16ff0d5fc7..6435f23b62 100644 --- a/packages/suite/src/middlewares/recovery/recoveryMiddleware.ts +++ b/packages/suite/src/middlewares/recovery/recoveryMiddleware.ts @@ -7,6 +7,7 @@ import { SUITE } from 'src/actions/suite/constants'; import * as recoveryActions from 'src/actions/recovery/recoveryActions'; import * as onboardingActions from 'src/actions/onboarding/onboardingActions'; import { AppState, Action, Dispatch } from 'src/types/suite'; +import { isRecoveryInProgress } from '../../utils/device/isRecoveryInProgress'; const recovery = (api: MiddlewareAPI) => @@ -31,7 +32,8 @@ const recovery = if ( deviceActions.updateSelectedDevice.match(action) && - action.payload?.features?.recovery_mode && + action.payload?.features !== undefined && + isRecoveryInProgress(action.payload?.features) && recovery.status !== 'in-progress' ) { api.dispatch( @@ -41,7 +43,7 @@ const recovery = }), ); if (!analytics.confirmed) { - // If you connect T2T1 in recovery mode to fresh Suite, you should see analytics optout option first. + // If you connect T2T1 in recovery mode to fresh Suite, you should see analytics opt-out option first. api.dispatch(recoveryActions.setStatus('in-progress')); } else { api.dispatch(recoveryActions.rerun()); diff --git a/packages/suite/src/support/messages.ts b/packages/suite/src/support/messages.ts index de13a0166c..a0198595f5 100644 --- a/packages/suite/src/support/messages.ts +++ b/packages/suite/src/support/messages.ts @@ -2100,7 +2100,7 @@ export default defineMessages({ }, TR_BACKUP_SUBHEADING_1: { defaultMessage: - "A wallet backup is a series of randomly generated words created by your Trezor. It’s important to write down your wallet backup and keep it safe, as it's the only way to recover and access your funds.", + "A wallet backup is a series of randomly generated words created by your Trezor. It's important to write down your wallet backup and keep it safe, as it's the only way to recover and access your funds.", description: 'Explanation what recovery seed is', id: 'TR_BACKUP_SUBHEADING_1', }, @@ -2123,6 +2123,189 @@ export default defineMessages({ description: 'Enter words on your computer, recovery takes about 2 minutes.', id: 'TR_BASIC_RECOVERY_OPTION', }, + TR_MULTI_SHARE_BACKUP: { + defaultMessage: 'Multi-share Backup', + id: 'TR_MULTI_SHARE_BACKUP', + }, + TR_MULTI_SHARE_BACKUP_DESCRIPTION: { + defaultMessage: + 'Generate multiple shares, each containing 20 words. These shares are used collectively to recover your funds.', + id: 'TR_MULTI_SHARE_BACKUP_DESCRIPTION', + }, + + TR_MULTI_SHARE_BACKUP_IN_PROGRESS: { + defaultMessage: 'Multi-share Backup creation in progress', + id: 'TR_MULTI_SHARE_BACKUP_IN_PROGRESS', + }, + TR_MULTI_SHARE_BACKUP_IN_PROGRESS_HEADING: { + defaultMessage: 'Please continue creating shares on your Trezor', + id: 'TR_MULTI_SHARE_BACKUP_IN_PROGRESS_HEADING', + }, + TR_MULTI_SHARE_BACKUP_IN_PROGRESS_DESCRIPTION: { + defaultMessage: + 'After successfully creating a Multi-share Backup, you will be able to continue using your device with Trezor Suite.', + id: 'TR_MULTI_SHARE_BACKUP_IN_PROGRESS_DESCRIPTION', + }, + + TR_CREATE_MULTI_SHARE_BACKUP: { + defaultMessage: 'Create multi-share backup', + id: 'TR_CREATE_MULTI_SHARE_BACKUP', + }, + TR_MULTI_SHARE_BACKUP_CALLOUT_1: { + defaultMessage: 'What does it do?', + id: 'TR_MULTI_SHARE_BACKUP_CALLOUT_1', + }, + TR_MULTI_SHARE_BACKUP_CALLOUT_2: { + defaultMessage: 'What about my current backup?', + id: 'TR_MULTI_SHARE_BACKUP_CALLOUT_2', + }, + TR_MULTI_SHARE_BACKUP_CALLOUT_3: { + defaultMessage: 'Please note', + id: 'TR_MULTI_SHARE_BACKUP_CALLOUT_3', + }, + TR_MULTI_SHARE_BACKUP_EXPLANATION_1: { + defaultMessage: + 'Multi backup creates multiple 20 word shares that will be needed for recovering your Trezor. You can distribute these among your family, friends, or hide them in different places. If the time comes to recover your Trezor, multiple shares must be used collectively to regain access to your funds.', + id: 'TR_MULTI_SHARE_BACKUP_EXPLANATION_1', + }, + TR_MULTI_SHARE_BACKUP_EXPLANATION_2: { + defaultMessage: + 'You existing backup will still allow you to recover your funds. You should hide it well, ideally away from the new backup shares.', + id: 'TR_MULTI_SHARE_BACKUP_EXPLANATION_2', + }, + TR_MULTI_SHARE_BACKUP_CHECKBOX_1: { + defaultMessage: 'This is an advanced feature, and I understand the extra responsibility', + id: 'TR_MULTI_SHARE_BACKUP_CHECKBOX_1', + }, + TR_MULTI_SHARE_BACKUP_CHECKBOX_2: { + defaultMessage: 'My current backup will still be able to recover my wallet', + id: 'TR_MULTI_SHARE_BACKUP_CHECKBOX_2', + }, + TR_MULTI_SHARE_TIPS_ON_STORING_BACKUP: { + defaultMessage: 'Tips on storing backup', + id: 'TR_MULTI_SHARE_TIPS_ON_STORING_BACKUP', + }, + TR_CREATE_MULTI_SHARE_BACKUP_CREATED: { + defaultMessage: 'Multi-share Backup created', + id: 'TR_CREATE_MULTI_SHARE_BACKUP_CREATED', + }, + TR_MULTI_SHARE_BACKUP_GREAT: { + defaultMessage: 'Great!', + id: 'TR_MULTI_SHARE_BACKUP_GREAT', + }, + TR_CREATE_MULTI_SHARE_BACKUP_CREATED_INFO_TEXT: { + defaultMessage: + 'You’ve done a huge step for improving your security. Don’t forget to hide and distribute your backup well.', + id: 'TR_CREATE_MULTI_SHARE_BACKUP_CREATED_INFO_TEXT', + }, + TR_MULTI_SHARE_BACKUP_BACKUPS: { + defaultMessage: 'Backups', + id: 'TR_MULTI_SHARE_BACKUP_BACKUPS', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT_HEADER: { + defaultMessage: 'My previous backup', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT_LINE1: { + defaultMessage: 'Still recovers you funds', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT_LINE1', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT_LINE2: { + defaultMessage: 'Hide it well', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_LEFT_LINE2', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT_HEADER: { + defaultMessage: 'My new Multi-share Backup', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT_LINE1: { + defaultMessage: 'Collect the number of shares set as the threshold to recover your funds', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT_LINE1', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT_LINE2: { + defaultMessage: 'Hide them well. Can be different places, different people', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_RIGHT_LINE2', + }, + TR_MULTI_SHARE_BACKUP_SUCCESS_WHY_IS_BACKUP_IMPORTANT: { + defaultMessage: 'Why is backup important', + id: 'TR_MULTI_SHARE_BACKUP_SUCCESS_WHY_IS_BACKUP_IMPORTANT', + }, + TR_MULTI_SHARE_BACKUP_LOST_YOUR_TREZOR: { + defaultMessage: 'Lost your Trezor?', + id: 'TR_MULTI_SHARE_BACKUP_LOST_YOUR_TREZOR', + }, + TR_MULTI_SHARE_BACKUP_LOST_YOUR_TREZOR_INFO_TEXT: { + defaultMessage: 'Not a problem, recover your coins with Backup!', + id: 'TR_MULTI_SHARE_BACKUP_LOST_YOUR_TREZOR_INFO_TEXT', + }, + TR_MULTI_SHARE_BACKUP_LOST_YOUR_BACKUP: { + defaultMessage: 'Lost your Backup?', + id: 'TR_MULTI_SHARE_BACKUP_LOST_YOUR_BACKUP', + }, + TR_MULTI_SHARE_BACKUP_LOST_YOUR_BACKUP_INFO_TEXT: { + defaultMessage: + 'That could be very bad if you also lost your Trezor. Contact support if that happens.', + id: 'TR_MULTI_SHARE_BACKUP_LOST_YOUR_BACKUP_INFO_TEXT', + }, + TR_NEXT_UP: { + defaultMessage: 'Next up', + id: 'TR_NEXT_UP', + }, + TR_N_MIN: { + defaultMessage: '{n} min', + id: 'TR_N_MIN', + }, + TR_VERIFY_TREZOR_OWNERSHIP: { + defaultMessage: 'Verify Trezor ownership', + id: 'TR_VERIFY_TREZOR_OWNERSHIP', + }, + TR_VERIFY_TREZOR_OWNERSHIP_EXPLANATION: { + defaultMessage: + 'We need you to prove you own this wallet by entering your existing wallet backup.', + id: 'TR_VERIFY_TREZOR_OWNERSHIP_EXPLANATION', + }, + TR_VERIFY_TREZOR_OWNERSHIP_CARD_1: { + defaultMessage: 'Grab your existing wallet backup', + id: 'TR_VERIFY_TREZOR_OWNERSHIP_CARD_1', + }, + TR_VERIFY_TREZOR_OWNERSHIP_CARD_2: { + defaultMessage: "Don't take photos, or digital copies of backup", + id: 'TR_VERIFY_TREZOR_OWNERSHIP_CARD_2', + }, + TR_CREATE_SHARES: { + defaultMessage: 'Create shares on Trezor', + id: 'TR_CREATE_SHARES', + }, + TR_CREATE_SHARES_EXPLANATION: { + defaultMessage: + "Now, you'll be selecting amount of shares, and minimum of shares required to recover your Trezor.", + id: 'TR_CREATE_SHARES_EXPLANATION', + }, + TR_CREATE_SHARES_EXAMPLE: { + defaultMessage: 'e.g. 5 shares total, at least any 3 for recovery', + id: 'TR_CREATE_SHARES_EXAMPLE', + }, + TR_CREATE_SHARES_CARD_1: { + defaultMessage: + 'Grab pen and paper. Or print Trezor cards, or use Trezor Keep', + id: 'TR_CREATE_SHARES_CARD_1', + }, + TR_CREATE_SHARES_CARD_2: { + defaultMessage: "Don't take photos, or digital copies of backup", + id: 'TR_CREATE_SHARES_CARD_2', + }, + TR_CREATE_SHARES_CARD_3: { + defaultMessage: "Make sure it's just you, no curious onlookers", + id: 'TR_CREATE_SHARES_CARD_3', + }, + TR_ENTER_EXISTING_BACKUP: { + defaultMessage: 'Enter existing backup on Trezor', + id: 'TR_ENTER_EXISTING_BACKUP', + }, + TR_DONT_HAVE_BACKUP: { + defaultMessage: "I don't have a backup", + id: 'TR_DONT_HAVE_BACKUP', + }, TR_BCH_ADDRESS_INFO: { defaultMessage: 'Bitcoin Cash changed the address format to cashaddr. Find more info about how to convert your address on our blog. {TR_LEARN_MORE}', @@ -8969,8 +9152,8 @@ export default defineMessages({ id: 'TR_VIEW_ONLY_TOOLTIP_CHANGE_INFO', defaultMessage: 'You can change it here', }, - TR_VIEW_ONLY_TOOLTIP_BUTTON: { - id: 'TR_VIEW_ONLY_TOOLTIP_BUTTON', + TR_GOT_IT_BUTTON: { + id: 'TR_GOT_IT_BUTTON', defaultMessage: 'Got it', }, TR_VIEW_ONLY_ENABLED: { diff --git a/packages/suite/src/utils/device/isRecoveryInProgress.ts b/packages/suite/src/utils/device/isRecoveryInProgress.ts new file mode 100644 index 0000000000..0b2b82c809 --- /dev/null +++ b/packages/suite/src/utils/device/isRecoveryInProgress.ts @@ -0,0 +1,27 @@ +import { PROTO } from '@trezor/connect'; + +export const isAdditionalShamirBackupInProgress = (features: PROTO.Features) => + features.recovery_status === 'Backup' && + features.recovery_type === undefined && + features.backup_availability === 'Available'; + +export const isRecoveryInProgress = (features: PROTO.Features) => { + const { recovery_status, backup_availability } = features; + + if (recovery_status === undefined) { + return false; + } + + if (recovery_status === 'Recovery') { + return true; + } + + const isShamirAdditionalBackupRecovery = + recovery_status === 'Backup' && backup_availability === 'NotAvailable'; + + if (isShamirAdditionalBackupRecovery) { + return true; + } + + return false; +}; diff --git a/packages/suite/src/utils/suite/prerequisites.ts b/packages/suite/src/utils/suite/prerequisites.ts index 1932e7d993..ff5ce7f555 100644 --- a/packages/suite/src/utils/suite/prerequisites.ts +++ b/packages/suite/src/utils/suite/prerequisites.ts @@ -2,6 +2,10 @@ import type { TransportInfo } from '@trezor/connect'; import { DefinedUnionMember } from '@trezor/type-utils'; import { RouterState } from 'src/reducers/suite/routerReducer'; import type { TrezorDevice, AppState } from 'src/types/suite'; +import { + isAdditionalShamirBackupInProgress, + isRecoveryInProgress, +} from '../device/isRecoveryInProgress'; type GetPrerequisiteNameParams = { router: AppState['router']; @@ -38,7 +42,13 @@ export const getPrerequisiteName = ({ router, device, transport }: GetPrerequisi // similar to initialize, there is no seed in device // difference is it is in recovery mode. // todo: this could be added to @trezor/connect to device.mode I think. - if (device.features.recovery_mode) return 'device-recovery-mode'; + if (isRecoveryInProgress(device.features)) { + return 'device-recovery-mode'; + } + + if (isAdditionalShamirBackupInProgress(device.features)) { + return 'multi-share-backup-in-progress'; + } // device is not initialized // todo: should not happen and redirect to onboarding instead? @@ -66,6 +76,7 @@ export const getExcludedPrerequisites = (router: RouterState): PrerequisiteType[ 'device-bootloader', 'firmware-missing', 'firmware-required', + 'multi-share-backup-in-progress', ]; } diff --git a/packages/suite/src/views/backup/index.tsx b/packages/suite/src/views/backup/index.tsx index ac61c0e08b..cd1396fd97 100644 --- a/packages/suite/src/views/backup/index.tsx +++ b/packages/suite/src/views/backup/index.tsx @@ -1,7 +1,7 @@ import styled from 'styled-components'; import { Paragraph, Button, Image, Row } from '@trezor/components'; -import { HELP_CENTER_FAILED_BACKUP_URL } from '@trezor/urls'; +import { HELP_CENTER_RECOVERY_ISSUES_URL } from '@trezor/urls'; import { selectDevice } from '@suite-common/wallet-core'; import { useDispatch, useSelector } from 'src/hooks/suite'; @@ -112,7 +112,7 @@ export const Backup = ({ cancelable, onCancel }: ForegroundAppProps) => { if ( backup.status !== 'finished' && !backup.error && - device.features.needs_backup === false && + device.features.backup_availability !== 'Required' && device.features.unfinished_backup !== null ) { return ( @@ -127,7 +127,7 @@ export const Backup = ({ cancelable, onCancel }: ForegroundAppProps) => { - + diff --git a/packages/suite/src/views/dashboard/components/SecurityFeatures/index.tsx b/packages/suite/src/views/dashboard/components/SecurityFeatures/index.tsx index ac09b8823d..248d98cbee 100644 --- a/packages/suite/src/views/dashboard/components/SecurityFeatures/index.tsx +++ b/packages/suite/src/views/dashboard/components/SecurityFeatures/index.tsx @@ -51,7 +51,8 @@ const SecurityFeatures = () => { if (device && device.features) { // TODO: add "error - backup failed" instead of needsBackup // TODO: add "enable passphrase" instead of hiddenWalletCreated - needsBackup = device.features.needs_backup || device.features.unfinished_backup; + needsBackup = + device.features.backup_availability === 'Required' || device.features.unfinished_backup; pinEnabled = device.features.pin_protection; hiddenWalletCreated = device.features.passphrase_protection; backupFailed = device.features.unfinished_backup; diff --git a/packages/suite/src/views/settings/SettingsDevice/BackupFailed.tsx b/packages/suite/src/views/settings/SettingsDevice/BackupFailed.tsx index 2beb0c4a36..286cfc1582 100644 --- a/packages/suite/src/views/settings/SettingsDevice/BackupFailed.tsx +++ b/packages/suite/src/views/settings/SettingsDevice/BackupFailed.tsx @@ -1,4 +1,4 @@ -import { HELP_CENTER_FAILED_BACKUP_URL } from '@trezor/urls'; +import { HELP_CENTER_RECOVERY_ISSUES_URL } from '@trezor/urls'; import { SettingsSectionItem } from 'src/components/settings'; import { ActionButton, ActionColumn, TextColumn, Translation } from 'src/components/suite'; @@ -10,7 +10,7 @@ export const BackupFailed = () => { } description={} - buttonLink={HELP_CENTER_FAILED_BACKUP_URL} + buttonLink={HELP_CENTER_RECOVERY_ISSUES_URL} /> diff --git a/packages/suite/src/views/settings/SettingsDevice/BackupRecoverySeed.tsx b/packages/suite/src/views/settings/SettingsDevice/BackupRecoverySeed.tsx index d69234d749..58364832b2 100644 --- a/packages/suite/src/views/settings/SettingsDevice/BackupRecoverySeed.tsx +++ b/packages/suite/src/views/settings/SettingsDevice/BackupRecoverySeed.tsx @@ -14,7 +14,7 @@ export const BackupRecoverySeed = ({ isDeviceLocked }: BackupRecoverySeedProps) const dispatch = useDispatch(); const { device } = useDevice(); - const needsBackup = !!device?.features?.needs_backup; + const needsBackup = device?.features?.backup_availability === 'Required'; const handleClick = () => dispatch(goto('backup-index', { params: { cancelable: true } })); diff --git a/packages/suite/src/views/settings/SettingsDevice/CheckRecoverySeed.tsx b/packages/suite/src/views/settings/SettingsDevice/CheckRecoverySeed.tsx index 856597274c..c1f79aaf80 100644 --- a/packages/suite/src/views/settings/SettingsDevice/CheckRecoverySeed.tsx +++ b/packages/suite/src/views/settings/SettingsDevice/CheckRecoverySeed.tsx @@ -14,7 +14,7 @@ export const CheckRecoverySeed = ({ isDeviceLocked }: CheckRecoverySeedProps) => const dispatch = useDispatch(); const { device } = useDevice(); - const needsBackup = !!device?.features?.needs_backup; + const needsBackup = device?.features?.backup_availability === 'Required'; const learnMoreUrl = getCheckBackupUrl(device); const handleClick = () => dispatch(goto('recovery-index', { params: { cancelable: true } })); diff --git a/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx b/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx new file mode 100644 index 0000000000..8cba5abb4d --- /dev/null +++ b/packages/suite/src/views/settings/SettingsDevice/MultiShareBackup.tsx @@ -0,0 +1,61 @@ +import { HELP_CENTER_SEED_CARD_URL } from '@trezor/urls'; +import { + ActionButton, + ActionColumn, + SectionItem, + TextColumn, + Translation, +} from 'src/components/suite'; +import { useDispatch, useSelector } from 'src/hooks/suite'; +import { selectDevice } from '@suite-common/wallet-core'; +import { TrezorDevice } from '@suite-common/suite-types'; +import { goto } from '../../../actions/suite/routerActions'; + +const doesSupportMultiShare = (device: TrezorDevice | undefined): boolean => { + if (device?.features === undefined) { + return false; + } + + if (!device.features.capabilities?.includes('Capability_Shamir')) { + return false; + } + + return ( + device.features.backup_type !== null && + [ + 'Slip39_Single_Extendable', + 'Slip39_Basic_Extendable', + 'Slip39_Advanced_Extendable', + ].includes(device.features.backup_type) + ); +}; + +export const MultiShareBackup = () => { + const device = useSelector(selectDevice); + const dispatch = useDispatch(); + + if (!doesSupportMultiShare(device)) { + return; + } + + const handleClick = () => dispatch(goto('create-multi-share-backup')); + + return ( + + } + description={} + buttonLink={HELP_CENTER_SEED_CARD_URL} + /> + + + + + + + ); +}; diff --git a/packages/suite/src/views/settings/SettingsDevice/SettingsDevice.tsx b/packages/suite/src/views/settings/SettingsDevice/SettingsDevice.tsx index a97d4f9cc8..3bb703433b 100644 --- a/packages/suite/src/views/settings/SettingsDevice/SettingsDevice.tsx +++ b/packages/suite/src/views/settings/SettingsDevice/SettingsDevice.tsx @@ -20,6 +20,7 @@ import { DisplayRotation } from './DisplayRotation'; import { FirmwareTypeChange } from './FirmwareTypeChange'; import { FirmwareVersion } from './FirmwareVersion'; import { Homescreen } from './Homescreen'; +import { MultiShareBackup } from './MultiShareBackup'; import { Passphrase } from './Passphrase'; import { PinProtection } from './PinProtection'; import { SafetyChecks } from './SafetyChecks'; @@ -28,12 +29,14 @@ import { WipeDevice } from './WipeDevice'; import { ChangeLanguage } from './ChangeLanguage'; import { EnableViewOnly } from './EnableViewOnly'; import { selectSuiteFlags } from 'src/reducers/suite/suiteReducer'; +import { isRecoveryInProgress } from '../../../utils/device/isRecoveryInProgress'; const deviceSettingsUnavailable = (device?: TrezorDevice, transport?: Partial) => { const noTransportAvailable = transport && !transport.type; const wrongDeviceType = device?.type && ['unacquired', 'unreadable'].includes(device.type); const wrongDeviceMode = - (device?.mode && ['seedless'].includes(device.mode)) || device?.features?.recovery_mode; + (device?.mode && ['seedless'].includes(device.mode)) || + (device?.features !== undefined && isRecoveryInProgress(device?.features)); const firmwareUpdateRequired = device?.firmware === 'required'; return noTransportAvailable || wrongDeviceType || wrongDeviceMode || firmwareUpdateRequired; @@ -120,6 +123,7 @@ export const SettingsDevice = () => { ) : ( <> + )} diff --git a/packages/suite/src/views/view-only/ViewOnlyTooltip.tsx b/packages/suite/src/views/view-only/ViewOnlyTooltip.tsx index dd554deaac..2dcf34aa48 100644 --- a/packages/suite/src/views/view-only/ViewOnlyTooltip.tsx +++ b/packages/suite/src/views/view-only/ViewOnlyTooltip.tsx @@ -52,7 +52,7 @@ export const ViewOnlyTooltip = ({ children }: ViewOnlyTooltipProps) => { } diff --git a/packages/urls/src/urls.ts b/packages/urls/src/urls.ts index 549e01c313..40d0c8c1af 100644 --- a/packages/urls/src/urls.ts +++ b/packages/urls/src/urls.ts @@ -56,7 +56,7 @@ export const HELP_CENTER_FW_DOWNGRADE_T2B1_URL = 'https://trezor.io/learn/a/downgrade-firmware-trezor-safe-3'; export const HELP_CENTER_FW_DOWNGRADE_T3T1_URL = 'https://trezor.io/learn/a/downgrade-firmware-trezor-safe-5'; -export const HELP_CENTER_FAILED_BACKUP_URL = 'https://trezor.io/support/a/trezor-recovery-issues'; +export const HELP_CENTER_RECOVERY_ISSUES_URL = 'https://trezor.io/support/a/trezor-recovery-issues'; export const HELP_CENTER_ADVANCED_RECOVERY_URL = 'https://trezor.io/learn/a/advanced-recovery-on-trezor-model-one'; export const HELP_CENTER_XPUB_URL = 'https://trezor.io/learn/a/trezor-suite-app-public-keys-xpub'; @@ -71,6 +71,11 @@ export const HELP_CENTER_DEVICE_AUTHENTICATION = 'https://trezor.io/learn/a/trezor-safe-3-authentication-check'; export const HELP_CENTER_ETH_STAKING = 'https://trezor.io/learn/a/stake-ethereum-eth-in-trezor-suite'; +export const HELP_CENTER_SEED_CARD_URL = 'https://trezor.io/learn/a/recovery-seed-card'; +export const HELP_CENTER_MULTI_SHARE_BACKUP_URL = + 'https://trezor.io/learn/a/introducing-multi-share-backup'; +export const HELP_CENTER_KEEPING_SEED_SAFE_URL = + 'https://trezor.io/learn/a/keeping-your-recovery-seed-safe'; export const INVITY_URL = 'https://invity.io/'; export const INVITY_SCHEDULE_OF_FEES = 'https://blog.invity.io/schedule-of-fees'; @@ -95,5 +100,4 @@ export const ZKSNACKS_TERMS_URL = 'https://github.com/zkSNACKs/WalletWasabi/blob/master/WalletWasabi/Legal/Assets/LegalDocumentsWw2.txt'; export const CROWDIN_URL = 'https://crowdin.com/project/trezor-suite'; -export const HELP_CENTER_MULTI_SHARE_BACKUP_URL = - 'https://trezor.io/learn/a/introducing-multi-share-backup'; +export const ESHOP_KEEP_METAL_URL = 'https://trezor.io/trezor-keep-metal'; diff --git a/suite-common/suite-config/src/routes.ts b/suite-common/suite-config/src/routes.ts index 0893468d53..49e09b4039 100644 --- a/suite-common/suite-config/src/routes.ts +++ b/suite-common/suite-config/src/routes.ts @@ -113,6 +113,13 @@ export const routes = [ isForegroundApp: true, params: modalAppParams, }, + { + name: 'create-multi-share-backup', + pattern: '/create-multi-share-backup', + app: 'create-multi-share-backup', + isForegroundApp: true, + params: modalAppParams, + }, { name: 'wallet-index', pattern: '/accounts', diff --git a/suite-common/test-utils/src/mocks.ts b/suite-common/test-utils/src/mocks.ts index 63420bc3cd..fc684ef811 100644 --- a/suite-common/test-utils/src/mocks.ts +++ b/suite-common/test-utils/src/mocks.ts @@ -113,7 +113,7 @@ const getDeviceFeatures = (feat?: Partial): Features => ({ imported: null, unlocked: true, firmware_present: null, - needs_backup: false, + backup_availability: 'NotAvailable', flags: 0, model: 'T', internal_model: DeviceModelInternal.T2T1, @@ -123,7 +123,7 @@ const getDeviceFeatures = (feat?: Partial): Features => ({ fw_vendor: null, unfinished_backup: false, no_backup: false, - recovery_mode: false, + recovery_status: 'Nothing', capabilities: [], backup_type: 'Bip39', sd_card_present: false, diff --git a/suite-common/wallet-core/src/device/deviceConstants.ts b/suite-common/wallet-core/src/device/deviceConstants.ts index 852601c6e0..d8c4cbd553 100644 --- a/suite-common/wallet-core/src/device/deviceConstants.ts +++ b/suite-common/wallet-core/src/device/deviceConstants.ts @@ -35,7 +35,7 @@ export const portfolioTrackerDevice: TrezorDevice = { imported: null, unlocked: true, firmware_present: null, - needs_backup: false, + backup_availability: 'NotAvailable', flags: 0, model: 'T', internal_model: DeviceModelInternal.T2T1, @@ -45,7 +45,7 @@ export const portfolioTrackerDevice: TrezorDevice = { fw_vendor: null, unfinished_backup: false, no_backup: false, - recovery_mode: false, + recovery_status: 'Nothing', capabilities: [], backup_type: 'Bip39', sd_card_present: false,