Skip to content

Commit e419028

Browse files
committed
fix: clean up
1 parent 5766407 commit e419028

File tree

2 files changed

+67
-71
lines changed

2 files changed

+67
-71
lines changed

app/components/Views/QRScanner/index.test.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,63 @@ describe('QrScanner', () => {
678678
});
679679
});
680680
});
681+
682+
it('tracks QR_SCANNED with unrecognized_qr_code result and scan_success false for arbitrary content', async () => {
683+
const validatorsModule = jest.requireMock('../../../util/validators');
684+
(validatorsModule.isValidMnemonic as jest.Mock).mockReturnValue(false);
685+
(
686+
validatorsModule.failedSeedPhraseRequirements as jest.Mock
687+
).mockReturnValue(true);
688+
689+
const ethereumjsUtilModule = jest.requireMock('ethereumjs-util');
690+
(ethereumjsUtilModule.isValidAddress as jest.Mock).mockReturnValue(
691+
false,
692+
);
693+
694+
const generalUtilsModule = jest.requireMock('../../../util/general');
695+
(generalUtilsModule.getURLProtocol as jest.Mock).mockReturnValue('');
696+
697+
const SDKConnectV2Module = jest.requireMock(
698+
'../../../core/SDKConnectV2',
699+
);
700+
(
701+
SDKConnectV2Module.default.isConnectDeeplink as jest.Mock
702+
).mockReturnValue(false);
703+
704+
const SharedDeeplinkManagerModule = jest.requireMock(
705+
'../../../core/DeeplinkManager/SharedDeeplinkManager',
706+
);
707+
(
708+
SharedDeeplinkManagerModule.default.parse as jest.Mock
709+
).mockResolvedValue(false);
710+
711+
const mockOnScanSuccess = jest.fn();
712+
renderWithProvider(<QrScanner onScanSuccess={mockOnScanSuccess} />, {
713+
state: initialState,
714+
});
715+
716+
await waitFor(() => {
717+
expect(onCodeScannedCallback).toBeDefined();
718+
});
719+
720+
await act(async () => {
721+
// Arbitrary content that doesn't match any known pattern
722+
onCodeScannedCallback?.([{ value: 'arbitrary-unknown-content-123' }]);
723+
});
724+
725+
await waitFor(() => {
726+
expect(mockAddProperties).toHaveBeenCalledWith({
727+
[QRScannerEventProperties.SCAN_SUCCESS]: false,
728+
[QRScannerEventProperties.QR_TYPE]: QRType.DEEPLINK, // getQRType returns DEEPLINK as default
729+
[QRScannerEventProperties.SCAN_RESULT]:
730+
ScanResult.UNRECOGNIZED_QR_CODE,
731+
});
732+
expect(mockOnScanSuccess).toHaveBeenCalledWith(
733+
'arbitrary-unknown-content-123',
734+
'arbitrary-unknown-content-123',
735+
);
736+
});
737+
});
681738
});
682739
});
683740
});

app/components/Views/QRScanner/index.tsx

Lines changed: 10 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,6 @@ const QRScanner = ({
172172
return;
173173
}
174174

175-
// ============================================================
176-
// CONDITION 1: Address Validation for Send Flow & Contact Form
177-
// ============================================================
178-
// Handles QR codes scanned from:
179-
// - Send token flow (Routes.SEND_FLOW.SEND_TO)
180-
// - Contact form (Routes.SETTINGS.CONTACT_FORM)
181-
// Validates that the scanned content is a valid address
182175
if (
183176
origin === Routes.SEND_FLOW.SEND_TO ||
184177
origin === Routes.SETTINGS.CONTACT_FORM
@@ -199,12 +192,6 @@ const QRScanner = ({
199192
return;
200193
}
201194
}
202-
203-
// ============================================================
204-
// CONDITION 2: SDK Connect V2 Deeplink
205-
// ============================================================
206-
// Handles SDK connection deeplinks (metamask-sdk://)
207-
// Establishes WebSocket connection and handles internally
208195
if (SDKConnectV2.isConnectDeeplink(response.data)) {
209196
// SDKConnectV2 handles the connection entirely internally (establishes WebSocket, etc.)
210197
// and bypasses the standard deeplink saga flow. We don't call onScanSuccess here because
@@ -226,12 +213,6 @@ const QRScanner = ({
226213
return;
227214
}
228215

229-
// ============================================================
230-
// CONDITION 3: Regular URLs (HTTP/HTTPS/DAPP)
231-
// ============================================================
232-
// Handles standard web URLs and dapp:// protocol
233-
// Prompts user for confirmation before opening external URLs
234-
// Excludes WalletConnect and SDK deeplinks
235216
const contentProtocol = getURLProtocol(content);
236217
const isWalletConnect = content.startsWith(MM_WALLETCONNECT_DEEPLINK);
237218
const isSDK = content.startsWith(MM_SDK_DEEPLINK);
@@ -281,11 +262,6 @@ const QRScanner = ({
281262

282263
let data = {};
283264

284-
// ============================================================
285-
// CONDITION 4: MetaMask Sync Protocol
286-
// ============================================================
287-
// Handles wallet sync QR codes (metamask-sync:)
288-
// Used for syncing data between MetaMask instances
289265
if (content.split('metamask-sync:').length > 1) {
290266
shouldReadBarCodeRef.current = false;
291267
data = { content };
@@ -322,10 +298,6 @@ const QRScanner = ({
322298
mountedRef.current = false;
323299
}
324300
} else {
325-
// ============================================================
326-
// CONDITION 5: Seed Phrase/Mnemonic
327-
// ============================================================
328-
// Handles 12/24 word seed phrases for wallet import
329301
if (
330302
!failedSeedPhraseRequirements(content) &&
331303
isValidMnemonic(content)
@@ -371,12 +343,6 @@ const QRScanner = ({
371343
return;
372344
}
373345

374-
// ============================================================
375-
// CONDITION 6: Ethereum Address (EIP-681)
376-
// ============================================================
377-
// Handles ethereum: protocol addresses or plain 0x addresses
378-
// Examples: ethereum:0x123... or 0x123...
379-
// Initiates send flow for the scanned address
380346
if (
381347
(content.split(`${PROTOCOLS.ETHEREUM}:`).length > 1 &&
382348
!parse(content).function_name) ||
@@ -403,17 +369,14 @@ const QRScanner = ({
403369
return;
404370
}
405371

406-
// ============================================================
407-
// CONDITION 7: Generic Deeplinks
408-
// ============================================================
409-
// Attempts to handle content through SharedDeeplinkManager
410-
// Handles metamask:// deeplinks and other registered protocols
411372
const handledByDeeplink = await SharedDeeplinkManager.parse(content, {
412373
origin: AppConstants.DEEPLINKS.ORIGIN_QR_CODE,
413-
// TODO: Check is pop is still valid.
414-
// TODO: Replace "any" with type
415-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
416-
onHandled: () => (navigation as any).pop(2),
374+
onHandled: () => {
375+
const stackNavigation = navigation as {
376+
pop?: (count: number) => void;
377+
};
378+
stackNavigation.pop?.(2);
379+
},
417380
});
418381

419382
if (handledByDeeplink) {
@@ -431,11 +394,6 @@ const QRScanner = ({
431394
return;
432395
}
433396

434-
// ============================================================
435-
// CONDITION 8: Private Key Import
436-
// ============================================================
437-
// Handles private keys for account import
438-
// Accepts 64 char hex or 66 char hex (with 0x prefix)
439397
if (
440398
content.length === 64 ||
441399
(content.substring(0, 2).toLowerCase() === '0x' &&
@@ -454,13 +412,7 @@ const QRScanner = ({
454412
})
455413
.build(),
456414
);
457-
}
458-
// ============================================================
459-
// CONDITION 9: Ethereum Address (0x prefix, fallback)
460-
// ============================================================
461-
// Fallback handler for 0x addresses that didn't match earlier checks
462-
// Initiates send flow for the address
463-
else if (content.substring(0, 2).toLowerCase() === '0x') {
415+
} else if (content.substring(0, 2).toLowerCase() === '0x') {
464416
shouldReadBarCodeRef.current = false;
465417
data = { target_address: content, action: 'send-eth' };
466418
trackEvent(
@@ -472,13 +424,7 @@ const QRScanner = ({
472424
})
473425
.build(),
474426
);
475-
}
476-
// ============================================================
477-
// CONDITION 10: WalletConnect URI
478-
// ============================================================
479-
// Handles WalletConnect v1/v2 connection URIs (wc:)
480-
// Initiates WalletConnect pairing
481-
else if (content.split('wc:').length > 1) {
427+
} else if (content.split('wc:').length > 1) {
482428
shouldReadBarCodeRef.current = false;
483429
data = { walletConnectURI: content };
484430
trackEvent(
@@ -490,20 +436,13 @@ const QRScanner = ({
490436
})
491437
.build(),
492438
);
493-
}
494-
// ============================================================
495-
// CONDITION 11: Arbitrary Data (EIP-945)
496-
// ============================================================
497-
// Fallback for any other QR code content
498-
// Allows scanning arbitrary data as per EIP-945
499-
// Note: Parent component may show "Unrecognized QR Code" dialog
500-
else {
439+
} else {
501440
data = content;
502441
const qrType = getQRType(content, origin, data as ScanSuccess);
503442
trackEvent(
504443
createEventBuilder(MetaMetricsEvents.QR_SCANNED)
505444
.addProperties({
506-
[QRScannerEventProperties.SCAN_SUCCESS]: true,
445+
[QRScannerEventProperties.SCAN_SUCCESS]: false,
507446
[QRScannerEventProperties.QR_TYPE]: qrType,
508447
[QRScannerEventProperties.SCAN_RESULT]:
509448
ScanResult.UNRECOGNIZED_QR_CODE,

0 commit comments

Comments
 (0)