Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ linkStyle default opacity:0.5
eth_qr_keyring --> account_api;
eth_simple_keyring --> keyring_api;
eth_simple_keyring --> keyring_utils;
eth_trezor_keyring --> hw_wallet_sdk;
eth_trezor_keyring --> keyring_api;
eth_trezor_keyring --> keyring_utils;
eth_trezor_keyring --> account_api;
Expand Down
4 changes: 4 additions & 0 deletions packages/hw-wallet-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `TREZOR_ERROR_MAPPINGS` static error data for Trezor hardware wallets ([#471](https://github.com/MetaMask/accounts/pull/471))

## [0.5.0]

### Added
Expand Down
41 changes: 41 additions & 0 deletions packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
LEDGER_ERROR_MAPPINGS,
BLE_ERROR_MAPPINGS,
MOBILE_ERROR_MAPPINGS,
TREZOR_ERROR_MAPPINGS,
} from './hardware-error-mappings';
import type { ErrorMapping } from './hardware-error-mappings';
import { ErrorCode, Severity, Category } from './hardware-errors-enums';
Expand Down Expand Up @@ -244,4 +245,44 @@ describe('HARDWARE_ERROR_MAPPINGS', () => {
});
});
});

describe('Trezor mappings', () => {
it('has TREZOR_ERROR_MAPPINGS object', () => {
expect(TREZOR_ERROR_MAPPINGS).toBeDefined();
expect(typeof TREZOR_ERROR_MAPPINGS).toBe('object');
});

it('has valid structure for all mappings', () => {
Object.values(TREZOR_ERROR_MAPPINGS).forEach((mapping) => {
expect(mapping).toHaveProperty('code');
expect(mapping).toHaveProperty('message');
expect(mapping).toHaveProperty('severity');
expect(mapping).toHaveProperty('category');

const numericErrorCodes = Object.values(ErrorCode).filter(
(value): value is number => typeof value === 'number',
);
expect(numericErrorCodes).toContain(mapping.code);
expect(Object.values(Severity)).toContain(mapping.severity);
expect(Object.values(Category)).toContain(mapping.category);
expect(typeof mapping.message).toBe('string');
});
});

it('maps Init_IframeTimeout to ConnectionTimeout', () => {
expect(TREZOR_ERROR_MAPPINGS.Init_IframeTimeout).toMatchObject({
code: ErrorCode.ConnectionTimeout,
severity: Severity.Err,
category: Category.Connection,
});
});

it('maps Transport_Missing to ConnectionTransportMissing', () => {
expect(TREZOR_ERROR_MAPPINGS.Transport_Missing).toMatchObject({
code: ErrorCode.ConnectionTransportMissing,
severity: Severity.Err,
category: Category.Connection,
});
});
});
});
216 changes: 216 additions & 0 deletions packages/hw-wallet-sdk/src/hardware-error-mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,219 @@ export const MOBILE_ERROR_MAPPINGS = {
userMessage: 'This operation is not supported on mobile devices.',
},
};

/* eslint-disable @typescript-eslint/naming-convention */
/**
* Trezor error mappings - static error data for Trezor hardware wallets.
* These mappings provide consistent error classification across Trezor integrations.
*/
export const TREZOR_ERROR_MAPPINGS: Record<string, ErrorMapping> = {
Transport_Missing: {
code: ErrorCode.ConnectionTransportMissing,
message: 'Trezor transport is unavailable',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Unable to connect to your Trezor device. Please reconnect and try again.',
},
Device_Disconnected: {
code: ErrorCode.DeviceDisconnected,
message: 'Trezor device disconnected',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Your Trezor device was disconnected. Please reconnect and try again.',
},
Popup_ConnectionMissing: {
code: ErrorCode.ConnectionClosed,
message: 'Trezor popup connection unavailable',
severity: Severity.Err,
category: Category.Connection,
userMessage: 'Connection to your Trezor device popup failed. Please retry.',
},
Desktop_ConnectionMissing: {
code: ErrorCode.ConnectionClosed,
message: 'Trezor desktop connection unavailable',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Connection to Trezor Suite failed. Please retry with your device connected.',
},
Method_Interrupted: {
code: ErrorCode.ConnectionClosed,
message: 'Trezor action was interrupted',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Connection to your Trezor device was closed. Please reconnect and try again.',
},
Method_Cancel: {
code: ErrorCode.UserCancelled,
message: 'User cancelled action on Trezor device',
severity: Severity.Warning,
category: Category.UserAction,
userMessage: 'Action was cancelled on your Trezor device.',
},
Method_PermissionsNotGranted: {
code: ErrorCode.UserRejected,
message: 'Permission not granted on Trezor device',
severity: Severity.Warning,
category: Category.UserAction,
userMessage: 'Permission was rejected on your Trezor device.',
},
Failure_ActionCancelled: {
code: ErrorCode.UserCancelled,
message: 'User cancelled action on Trezor device',
severity: Severity.Warning,
category: Category.UserAction,
userMessage: 'Action was cancelled on your Trezor device.',
},
Device_InvalidState: {
code: ErrorCode.AuthenticationFailed,
message: 'Trezor device authentication failed',
severity: Severity.Err,
category: Category.Authentication,
userMessage:
'Authentication failed on your Trezor device. Check your passphrase and retry.',
},
Device_CallInProgress: {
code: ErrorCode.DeviceCallInProgress,
message: 'Trezor device call already in progress',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Your Trezor device is busy. Finish the current action and retry.',
},
Init_IframeTimeout: {
code: ErrorCode.ConnectionTimeout,
message: 'Trezor connection timed out',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Connection to your Trezor device timed out. Please try again.',
},
Init_IframeBlocked: {
code: ErrorCode.ConnectionBlocked,
message: 'Trezor iframe blocked',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Trezor connection popup was blocked. Please allow popups and try again.',
},
Init_ManifestMissing: {
code: ErrorCode.Unknown,
message: 'Trezor manifest is missing',
severity: Severity.Err,
category: Category.Configuration,
userMessage:
'Trezor integration is not configured correctly. Please retry later.',
},
Device_NotFound: {
code: ErrorCode.DeviceNotFound,
message: 'Trezor device not found',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'No Trezor device found. Please connect your device and try again.',
},
Device_UsedElsewhere: {
code: ErrorCode.DeviceUsedElsewhere,
message: 'Trezor device is used elsewhere',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Your Trezor device is busy in another window. Close the other flow and try again.',
},
Device_MultipleNotSupported: {
code: ErrorCode.DeviceMultipleConnected,
message: 'Multiple Trezor devices are not supported',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Multiple Trezor devices are connected. Keep one connected and retry.',
},
Device_MissingCapability: {
code: ErrorCode.DeviceMissingCapability,
message: 'Trezor device is missing capability',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Your Trezor firmware does not support this action. Please update and retry.',
},
Device_MissingCapabilityBtcOnly: {
code: ErrorCode.DeviceBtcOnlyFirmware,
message: 'Trezor device firmware only supports BTC',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Your Trezor firmware currently supports BTC only. Update firmware and retry.',
},
Failure_PinCancelled: {
code: ErrorCode.AuthenticationPinCancelled,
message: 'Trezor PIN entry cancelled',
severity: Severity.Warning,
category: Category.Authentication,
userMessage: 'PIN entry was cancelled on your Trezor device.',
},
Failure_PinInvalid: {
code: ErrorCode.AuthenticationIncorrectPin,
message: 'Trezor PIN is invalid',
severity: Severity.Err,
category: Category.Authentication,
userMessage: 'The PIN is incorrect. Please try again.',
},
Failure_PinMismatch: {
code: ErrorCode.AuthenticationIncorrectPin,
message: 'Trezor PIN mismatch',
severity: Severity.Err,
category: Category.Authentication,
userMessage: 'The PIN does not match. Please try again.',
},
Failure_WipeCodeMismatch: {
code: ErrorCode.AuthenticationWipeCodeMismatch,
message: 'Trezor wipe code mismatch',
severity: Severity.Err,
category: Category.Authentication,
userMessage: 'The wipe code does not match. Please verify and try again.',
},
Device_ModeException: {
code: ErrorCode.DeviceIncompatibleMode,
message: 'Trezor device mode is incompatible',
severity: Severity.Err,
category: Category.DeviceState,
userMessage:
'Your Trezor is in an incompatible mode for this action. Check the device and retry.',
},
Device_ThpPairingTagInvalid: {
code: ErrorCode.AuthenticationSecurityCondition,
message: 'Trezor pairing security check failed',
severity: Severity.Err,
category: Category.Authentication,
userMessage:
'A security check failed on your Trezor device. Reconnect and try again.',
},
Backend_Disconnected: {
code: ErrorCode.ConnectionClosed,
message: 'Trezor backend disconnected',
severity: Severity.Err,
category: Category.Connection,
userMessage: 'Trezor backend disconnected. Please retry.',
},
Method_NoResponse: {
code: ErrorCode.ConnectionClosed,
message: 'Trezor call returned no response',
severity: Severity.Err,
category: Category.Connection,
userMessage:
'Trezor did not return a response. Reconnect your device and try again.',
},
Device_InitializeFailed: {
code: ErrorCode.AuthenticationDeviceLocked,
message: 'Trezor device initialization failed',
severity: Severity.Err,
category: Category.Authentication,
userMessage:
'Your Trezor device failed to initialize. Please unlock it and try again.',
},
};
/* eslint-enable @typescript-eslint/naming-convention */
7 changes: 7 additions & 0 deletions packages/keyring-eth-trezor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Wraps legacy `TrezorKeyring` and `OneKeyKeyring` to expose accounts via the unified `KeyringV2` API and the `KeyringAccount` type.
- Extends `EthKeyringWrapper` for common Ethereum logic.

### Changed

- Integrate `@metamask/hw-wallet-sdk` for standardized Trezor error handling ([#471](https://github.com/MetaMask/accounts/pull/471))
- Replace custom transport and user-action error handling with typed `HardwareWalletError` instances.
- Move Trezor error mappings and utilities to `@metamask/hw-wallet-sdk` for reuse across packages.
- Import `createTrezorError` and `getTrezorErrorIdentifier` from `@metamask/hw-wallet-sdk`.

## [9.0.0]

### Changed
Expand Down
8 changes: 4 additions & 4 deletions packages/keyring-eth-trezor/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ module.exports = merge(baseConfig, {
// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
global: {
branches: 62.65,
functions: 93.15,
lines: 93.57,
statements: 93.66,
branches: 86.66,
functions: 97.14,
lines: 98.42,
statements: 98.44,
},
},
});
1 change: 1 addition & 0 deletions packages/keyring-eth-trezor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@ethereumjs/tx": "^5.4.0",
"@ethereumjs/util": "^9.1.0",
"@metamask/eth-sig-util": "^8.2.0",
"@metamask/hw-wallet-sdk": "workspace:^",
"@metamask/keyring-api": "workspace:^",
"@metamask/keyring-utils": "workspace:^",
"@metamask/utils": "^11.1.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/keyring-eth-trezor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ export * from './trezor-keyring';
export * from './trezor-keyring-v2';
export * from './onekey-keyring';
export * from './onekey-keyring-v2';
export * from './trezor-error-handler';
export * from './trezor-errors';
export type * from './trezor-bridge';
export * from './trezor-connect-bridge';
Loading
Loading