feat(web): wallet picker for the implemented adapters (Freighter, LOBSTR) - #627
Conversation
|
@Mamavee001 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
@Mamavee001 is attempting to deploy a commit to the Collins' projects Team on Vercel. A member of the Team first needs to authorize it. |
collinsezedike
left a comment
There was a problem hiding this comment.
This PR breaks its own CI:
- Commit Messages: the header is 73 characters, over the 72-char limit (
✖ header must not be longer than 72 characters, current length is 73). - Lint & Typecheck:
prettier --check .fails onapps/docs/architecture/frontend.md,apps/web/src/__tests__/components/WalletConnect.test.tsx, andapps/web/src/hooks/useWalletConnect.ts.
The design itself reads correctly: getSelectedWalletId/setSelectedWalletId staying in wallet.ts to avoid the circular import with store/wallet.ts is the right call, the selection is only persisted on a successful connect (verified this holds in useWalletConnect.ts), and the wallet singleton's dispatch-per-call means useSignAndSubmit and the store's revalidate() correctly follow whichever wallet is actually connected without needing changes themselves.
|
@Mamavee001 checking in, this has been sitting on REQUEST_CHANGES for over two days with no update. Let me know if you're still working through the feedback or need any help. |
a4d484c to
24d32cb
Compare
closes #611
Summary
wallet.tshardcoded a singlewallet: WalletAdapterinstance toFreighterWallet, soLobstrWallet(merged in #537) was fully implemented and tested but never actually reachable from the app. This adds a wallet picker so users can choose between every implemented adapter and reconnect through the same one automatically next time.Changes
apps/web/src/lib/wallet.tsWALLETS: WalletMeta[]registry —{ id, name, installUrl, adapter }for each implemented wallet (Freighter, LOBSTR). Adding xBull once feat(wallet): add XBullWallet adapter #598 merges is one new entry here, nothing else.getSelectedWalletId()/setSelectedWalletId(), backed by a dedicatedlocalStoragekey (meridian-selected-wallet), default to Freighter. Kept inwallet.tsitself rather than the Zustand wallet store, sincestore/wallet.tsalready imports fromwallet.tsand putting it the other way round would create a circular import.wallet: WalletAdaptersingleton is now a dispatcher that resolves togetWalletAdapter(getSelectedWalletId())on every call, instead of being pinned toFreighterWallet. This meansuseSignAndSubmit'ssign()and the store'srevalidate()/isAuthorized()check automatically follow whichever wallet the user actually connected through — zero changes needed to those files or their tests.apps/web/src/hooks/useWalletConnect.tshandleConnect(walletId?)now accepts an explicit wallet, defaulting to the persisted selection when omitted (this is what keeps the plain "Connect Wallet" click unaffected — see acceptance criteria below).setSelectedWalletId) on a successful connect, so a failed or cancelled attempt never silently switches which wallet later sign/reconnect calls dispatch to.attemptedWalletIdso the no-extension fallback UI knows which wallet's install link to show.apps/web/src/components/onboarding/WalletConnect.tsxisInstalled()on open, so it reflects the extension state even without a reload).Install {name}→ that wallet's owninstallUrl) instead of hardcoded tofreighter.app.apps/web/src/components/dashboard/VaultPanel.tsxonClick={handleConnect}would have passed the raw click event ashandleConnect's newwalletIdparameter.Acceptance criteria
localStorage, only on a successful connect)WalletConnect.tsx's no-extension fallback is wallet-aware, not hardcoded to freighter.appgetByRole("button", { name: "Connect Wallet" })scoped to<main>) still resolve to the same element with the same text, and the "Install Freighter" e2e assertion still passes because the interpolated string (Install {{name}}→ "Install Freighter") renders identically for the default wallet.Test plan
apps/webunit tests: 108 passing (11 new/updated acrosslib/wallet.test.ts,useWalletConnect.test.ts, and a newWalletConnect.test.tsx).eslintandtsc && vite buildboth clean.freighter.app/lobstr.co), and confirmed the selection is not persisted tolocalStorageafter a failed connect attempt (no extension present in the sandbox).webServerconfig invokes a barepnpmbinary not onPATHhere, unrelated to this change), so verified by inspection that everygetByRole("button", { name: "Connect Wallet" })in the e2e specs is scoped to.locator("main"), which targetsVaultPanel's own button — untouched in shape/behavior by this PR.Caveats
WALLETS.installUrlpoints athttps://lobstr.co(its general site), matching howfreighter.appwas already used here — there's no official Chrome Web Store deep link in the LOBSTR package metadata to use instead.