From 497f871e0dba322c0489ef544072febea705e98d Mon Sep 17 00:00:00 2001 From: 0xEdouard <15703023+0xEdouardEth@users.noreply.github.com> Date: Wed, 24 Jun 2026 16:56:23 +0200 Subject: [PATCH] fix: handle non-url origins --- packages/snap/CHANGELOG.md | 4 ++ packages/snap/src/utils/formatOrigin.test.ts | 24 +++++------- packages/snap/src/utils/formatOrigin.ts | 40 ++++++++++++++++---- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/packages/snap/CHANGELOG.md b/packages/snap/CHANGELOG.md index 88898447..bcbb6151 100644 --- a/packages/snap/CHANGELOG.md +++ b/packages/snap/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Display known non-URL origins in confirmations without throwing on invalid origin values ([#340](https://github.com/MetaMask/snap-tron-wallet/pull/340)) + ## [1.28.0] ### Added diff --git a/packages/snap/src/utils/formatOrigin.test.ts b/packages/snap/src/utils/formatOrigin.test.ts index a38bd86e..65756878 100644 --- a/packages/snap/src/utils/formatOrigin.test.ts +++ b/packages/snap/src/utils/formatOrigin.test.ts @@ -1,20 +1,17 @@ import { formatOrigin } from './formatOrigin'; describe('formatOrigin', () => { - it('formats "metamask" as "MetaMask"', () => { + it('maps "metamask" to "MetaMask" (case-insensitive)', () => { expect(formatOrigin('metamask')).toBe('MetaMask'); - }); - - it('formats "METAMASK" as "MetaMask"', () => { expect(formatOrigin('METAMASK')).toBe('MetaMask'); - }); - - it('formats "MetaMask" as "MetaMask"', () => { expect(formatOrigin('MetaMask')).toBe('MetaMask'); + expect(formatOrigin('MeTaMaSk')).toBe('MetaMask'); }); - it('formats "MeTaMaSk" (mixed case) as "MetaMask"', () => { - expect(formatOrigin('MeTaMaSk')).toBe('MetaMask'); + it('maps "wallet-connect" to "WalletConnect" (case-insensitive)', () => { + expect(formatOrigin('wallet-connect')).toBe('WalletConnect'); + expect(formatOrigin('WALLET-CONNECT')).toBe('WalletConnect'); + expect(formatOrigin('Wallet-Connect')).toBe('WalletConnect'); }); it('extracts hostname from valid URLs', () => { @@ -29,11 +26,10 @@ describe('formatOrigin', () => { ); }); - it('returns original value for invalid URLs', () => { - // Note: These should be rejected by validation, but formatOrigin is lenient - expect(formatOrigin('example.com')).toBe('example.com'); - expect(formatOrigin('not-a-url')).toBe('not-a-url'); - expect(formatOrigin('just some text')).toBe('just some text'); + it('returns an empty string for non-URL / invalid origins', () => { + expect(formatOrigin('example.com')).toBe(''); + expect(formatOrigin('not-a-url')).toBe(''); + expect(formatOrigin('just some text')).toBe(''); }); it('returns "Unknown" for undefined', () => { diff --git a/packages/snap/src/utils/formatOrigin.ts b/packages/snap/src/utils/formatOrigin.ts index 316b05c4..6a602cc4 100644 --- a/packages/snap/src/utils/formatOrigin.ts +++ b/packages/snap/src/utils/formatOrigin.ts @@ -1,25 +1,49 @@ +/** + * Maps known non-URL origins to their display labels (case-insensitive lookup). + * In-app requests use 'MetaMask' (capitalized), so the lookup is case-insensitive. + */ +const KNOWN_ORIGIN_LABELS: Record = { + metamask: 'MetaMask', + 'wallet-connect': 'WalletConnect', +}; + /** * Formats an origin for display purposes. * + * Returns 'Unknown' for undefined/empty origins. Returns a friendly label for + * known origins ('metamask' to 'MetaMask', 'wallet-connect' to 'WalletConnect'), + * matched case-insensitively. Returns the hostname for http(s) URLs. Returns an + * empty string for everything else (channelIds, non-http URLs, invalid strings) + * so display guards `{origin ? (...) : null}` hide the row. + * * @param origin - The origin string to format (e.g., 'metamask', 'https://example.com'). - * @returns The formatted origin string (e.g., 'MetaMask', 'example.com'). + * @returns The formatted origin string (e.g., 'MetaMask', 'example.com', ''). */ export function formatOrigin(origin: string | undefined): string { if (!origin) { return 'Unknown'; } - // Special case: format 'metamask' as 'MetaMask' (case-insensitive) - if (origin.toLowerCase() === 'metamask') { - return 'MetaMask'; + const knownLabel = KNOWN_ORIGIN_LABELS[origin.toLowerCase()]; + if (knownLabel) { + return knownLabel; } // Try to extract hostname from URL try { - return new URL(origin).hostname; + const url = new URL(origin); + return isHttpOrHttpsUrl(url) ? url.hostname : ''; } catch { - // If not a valid URL, return the original value - // This shouldn't happen if validation is working correctly - return origin; + return ''; } } + +/** + * Checks whether a parsed URL uses an HTTP(S) protocol. + * + * @param url - The parsed URL to check. + * @returns Whether the URL uses HTTP or HTTPS. + */ +function isHttpOrHttpsUrl(url: URL): boolean { + return url.protocol === 'http:' || url.protocol === 'https:'; +}