From 23ba0238b1fdcf1ade4d082ae7608d5ec57c1fc9 Mon Sep 17 00:00:00 2001 From: david0xd Date: Mon, 30 Mar 2026 15:09:33 +0200 Subject: [PATCH 1/4] Add QR hardware wallet error mappings for extension --- packages/hw-wallet-sdk/CHANGELOG.md | 4 +++ .../src/hardware-error-mappings.test.ts | 26 +++++++++++++++++++ .../src/hardware-error-mappings.ts | 21 +++++++++++++++ .../src/hardware-errors-enums.ts | 1 + 4 files changed, 52 insertions(+) diff --git a/packages/hw-wallet-sdk/CHANGELOG.md b/packages/hw-wallet-sdk/CHANGELOG.md index 9cc962f7..b6227e89 100644 --- a/packages/hw-wallet-sdk/CHANGELOG.md +++ b/packages/hw-wallet-sdk/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `PermissionCameraPromptDismissed` error code and `QR_WALLET_ERROR_MAPPINGS` used for extension QR hardware wallet camera flows. + ## [0.7.0] ### Added diff --git a/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts b/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts index cb309531..52c0cd62 100644 --- a/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts +++ b/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts @@ -2,6 +2,7 @@ import { LEDGER_ERROR_MAPPINGS, BLE_ERROR_MAPPINGS, MOBILE_ERROR_MAPPINGS, + QR_WALLET_ERROR_MAPPINGS, TREZOR_ERROR_MAPPINGS, } from './hardware-error-mappings'; import type { ErrorMapping } from './hardware-error-mappings'; @@ -235,6 +236,31 @@ describe('HARDWARE_ERROR_MAPPINGS', () => { expect(mapping.category).toBe(Category.Configuration); expect(mapping.userMessage).toContain('Camera'); }); + }); + + describe('QR wallet mappings', () => { + const errorMappings = QR_WALLET_ERROR_MAPPINGS; + + it('has errorMappings object', () => { + expect(errorMappings).toBeDefined(); + expect(typeof errorMappings).toBe('object'); + }); + + it('maps CAMERA_PERMISSION_PROMPT_DISMISSED for State 1 (dialog dismissed)', () => { + const mapping = errorMappings.CAMERA_PERMISSION_PROMPT_DISMISSED; + expect(mapping).toBeDefined(); + expect(mapping?.code).toBe(ErrorCode.PermissionCameraPromptDismissed); + expect(mapping?.severity).toBe(Severity.Warning); + expect(mapping?.userMessage).toContain('QR code'); + }); + + it('maps CAMERA_PERMISSION_BLOCKED for State 2 (persistent block)', () => { + const mapping = errorMappings.CAMERA_PERMISSION_BLOCKED; + expect(mapping).toBeDefined(); + expect(mapping?.code).toBe(ErrorCode.PermissionCameraDenied); + expect(mapping?.severity).toBe(Severity.Err); + expect(mapping?.userMessage).toContain('browser settings'); + }); it('has valid structure for all mappings', () => { Object.values(errorMappings).forEach((mapping) => { diff --git a/packages/hw-wallet-sdk/src/hardware-error-mappings.ts b/packages/hw-wallet-sdk/src/hardware-error-mappings.ts index ca999a4d..13061d52 100644 --- a/packages/hw-wallet-sdk/src/hardware-error-mappings.ts +++ b/packages/hw-wallet-sdk/src/hardware-error-mappings.ts @@ -229,6 +229,27 @@ export const MOBILE_ERROR_MAPPINGS = { }, }; +/** + * QR hardware wallet flows in the browser. + */ +export const QR_WALLET_ERROR_MAPPINGS: Record = { + CAMERA_PERMISSION_PROMPT_DISMISSED: { + code: ErrorCode.PermissionCameraPromptDismissed, + message: 'Camera permission prompt dismissed without granting access', + severity: Severity.Warning, + category: Category.Configuration, + userMessage: + 'MetaMask needs camera access to scan the QR code on your device.', + }, + CAMERA_PERMISSION_BLOCKED: { + code: ErrorCode.PermissionCameraDenied, + message: 'Camera permission blocked by the browser', + severity: Severity.Err, + category: Category.Configuration, + userMessage: 'To continue, allow camera access in your browser settings.', + }, +}; + /* eslint-disable @typescript-eslint/naming-convention */ /** * Trezor error mappings - static error data for Trezor hardware wallets. diff --git a/packages/hw-wallet-sdk/src/hardware-errors-enums.ts b/packages/hw-wallet-sdk/src/hardware-errors-enums.ts index 042e9261..38235e9c 100644 --- a/packages/hw-wallet-sdk/src/hardware-errors-enums.ts +++ b/packages/hw-wallet-sdk/src/hardware-errors-enums.ts @@ -58,6 +58,7 @@ export enum ErrorCode { BluetoothConnectionFailed = 7102, MobileNotSupported = 7300, PermissionCameraDenied = 7301, + PermissionCameraPromptDismissed = 7302, // Transaction TxInsufficientFunds = 10000, From 9e4c47adbd203ee8fee9d57afeee87be683c5ea9 Mon Sep 17 00:00:00 2001 From: david0xd Date: Mon, 30 Mar 2026 15:13:00 +0200 Subject: [PATCH 2/4] Update changelog --- packages/hw-wallet-sdk/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hw-wallet-sdk/CHANGELOG.md b/packages/hw-wallet-sdk/CHANGELOG.md index b6227e89..86a98024 100644 --- a/packages/hw-wallet-sdk/CHANGELOG.md +++ b/packages/hw-wallet-sdk/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add `PermissionCameraPromptDismissed` error code and `QR_WALLET_ERROR_MAPPINGS` used for extension QR hardware wallet camera flows. +- Add `PermissionCameraPromptDismissed` error code and `QR_WALLET_ERROR_MAPPINGS` used for extension QR hardware wallet camera flows ([#490](https://github.com/MetaMask/accounts/pull/490)) ## [0.7.0] From 2acef20cc61e49fb90cc8001bcc79c9c95f3d069 Mon Sep 17 00:00:00 2001 From: david0xd Date: Mon, 30 Mar 2026 15:14:54 +0200 Subject: [PATCH 3/4] Update docstring --- packages/hw-wallet-sdk/src/hardware-error-mappings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hw-wallet-sdk/src/hardware-error-mappings.ts b/packages/hw-wallet-sdk/src/hardware-error-mappings.ts index 13061d52..a295f237 100644 --- a/packages/hw-wallet-sdk/src/hardware-error-mappings.ts +++ b/packages/hw-wallet-sdk/src/hardware-error-mappings.ts @@ -230,7 +230,7 @@ export const MOBILE_ERROR_MAPPINGS = { }; /** - * QR hardware wallet flows in the browser. + * QR error mappings - static error data for QR hardware wallets and their related flows. */ export const QR_WALLET_ERROR_MAPPINGS: Record = { CAMERA_PERMISSION_PROMPT_DISMISSED: { From a0902aac24717ccede52021a81915208eabe2fb9 Mon Sep 17 00:00:00 2001 From: david0xd Date: Mon, 30 Mar 2026 15:24:31 +0200 Subject: [PATCH 4/4] Refine unit tests --- .../src/hardware-error-mappings.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts b/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts index 52c0cd62..bed20196 100644 --- a/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts +++ b/packages/hw-wallet-sdk/src/hardware-error-mappings.test.ts @@ -236,6 +236,23 @@ describe('HARDWARE_ERROR_MAPPINGS', () => { expect(mapping.category).toBe(Category.Configuration); expect(mapping.userMessage).toContain('Camera'); }); + + it('has valid structure for all mappings', () => { + Object.values(errorMappings).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'); + }); + }); }); describe('QR wallet mappings', () => {