From 9423d2f43ae5353497cb0a19f6af22ff77745348 Mon Sep 17 00:00:00 2001
From: moscowchill
Date: Fri, 25 Sep 2026 10:18:53 +0200
Subject: [PATCH 1/2] feat(wallet-picker): show MyQRLWallet as a single row
MyQRLWallet announces itself twice over EIP-6963: com.qrlwallet.extension
from the browser extension and com.qrlwallet.connect from the connect SDK,
which covers the phone, web and desktop wallets. The picker listed both, so
the user had to know which of two MyQRLWallet rows matched the wallet they
actually have.
groupMyQrlWallet() from @qrlwallet/connect-ui folds the pair into one row
named MyQRLWallet, carrying the 3A mark. Clicking the row connects through
the extension when it is installed, and a separate "Use phone or desktop
app" button under it starts relay pairing. Without the extension the row
itself starts relay pairing and there is no second button. The rdns line is
replaced on that row by plain text naming the path a click takes.
Every other announced wallet keeps its own row, its own icon and its own
rdns line. The store's connect path is unchanged: both buttons hand a uuid
to connectWallet(), which still resolves the transport from the rdns.
The store imports the dependency-free @qrlwallet/connect-ui/wallets subpath
because the store tests load this module in plain Node, where the package
index would pull in the DOM pairing modal.
Gates: npm run lint (zero warnings), npm run typecheck, npm test (42 pass),
npm run build. Validated locally against a packed connect-ui 0.3.0.
Claude-Session: https://claude.ai/code/session_01LWKZ1b4FBetebjo1kcNHJ8
---
frontend/package.json | 2 +-
frontend/src/components/WalletPickerModal.tsx | 75 +++++++++++++------
frontend/src/stores/poolStore.ts | 68 +++++++++++++----
3 files changed, 105 insertions(+), 40 deletions(-)
diff --git a/frontend/package.json b/frontend/package.json
index 0848d72..ca0c306 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -21,7 +21,7 @@
"@fontsource-variable/sora": "^5.2.8",
"@noble/hashes": "^2.4.0",
"@qrlwallet/connect": "4.0.0",
- "@qrlwallet/connect-ui": "0.2.3",
+ "@qrlwallet/connect-ui": "0.3.0",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.1",
"@theqrl/web3": "^1.0.3",
diff --git a/frontend/src/components/WalletPickerModal.tsx b/frontend/src/components/WalletPickerModal.tsx
index 359390f..16a0663 100644
--- a/frontend/src/components/WalletPickerModal.tsx
+++ b/frontend/src/components/WalletPickerModal.tsx
@@ -5,8 +5,12 @@ import { useStore } from "@/stores/store";
/**
* EIP-6963 wallet picker. Lists the QRL-capable wallets the store discovered
- * (the QRL browser extension and MyQRLWallet via the connect relay) and hands
- * a click back to the store to run the right connect path.
+ * and hands a click back to the store to run the right connect path.
+ *
+ * MyQRLWallet announces once per transport (browser extension and connect
+ * relay), so the store folds the pair into a single row. Clicking that row
+ * uses the extension when it is installed, and the "Use phone or desktop app"
+ * button under it always starts relay pairing.
*/
export const WalletPickerModal = observer(() => {
const { poolStore } = useStore();
@@ -42,29 +46,52 @@ export const WalletPickerModal = observer(() => {
mobile or desktop.