Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Oct 21, 2025

Description

Update: confirmed working 🎉
Note: This is by no means intended to be a fully working flow, nor the final flow - it's mostly a PoC, hacked under the WC "Pair" button (under flag!) for beard to make it look pretty and UX - core functionality is there!

Probably nothing - just vibing around with an ugly red div to see how we can push the limits of escape-hatching WC (wallet) modal.

TODO:

  • fix logic so that connection is handled proper and closes modal (needs to be closed atm), also buggy loading states
  • add a third one because why not
  • cleanup. seriously, clean that bad boy up it's disgusting
  • leave it in a clean state, and add buttons under flag for @reallybeard to wire up and make not ugly
  • document how to add a specific wallet (it's not really a one-size fits all here, the "hack" here is finding out what's the deep link format for the wallet you attempt to wire up,
  • spike if we can detect installed wallets like Zapper does, detecting wallets who declare wc: intent follow-up spike
  • spike if we can have the app redirect to the wallet when using WC and having a sign Tx req (not introduced by this PR, but super annoying tbh) follow-up spike

Issue (if applicable)

closes #10877

Risk

High Risk PRs Require 2 approvals

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Low - under flag and temp work for @reallybeard to wire design ups in

Testing

  • Do a quick sanity pass of wc things (WC dApps, WC wallet)

Engineering

  • Note: deployed in gome - you will need to test there to test the bits under flag, as well as well, deep linking, since deep linking doesn't work on local IPs (tl;dr of that means, you can only test mobile deep linking things in a mobile env, hence gome deep linking)
  • Go to https://gome.shapeshift.com and confirm the three buttons (MM, Trust, Zerion) do work
  • Ensure you can connect to said wallets using those buttons, and sign

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)
  • No testing of this specifically required - dis under flag

Screenshots (if applicable)

Regression test

https://jam.dev/c/a2202c9b-90a3-4c28-8bb2-b114013c80fe

Direction connection buttons test

wc.direct.mov

Summary by CodeRabbit

  • New Features

    • Added direct wallet connection feature supporting MetaMask, Trust Wallet, and Zerion for streamlined wallet connection.
    • Implemented new connection interface as an alternative to existing wallet pairing methods.
  • Documentation

    • Added comprehensive WalletConnect v2 integration documentation covering architecture, configuration, state management, and usage workflows.

gomesalexandre and others added 7 commits October 21, 2025 23:20
- Add UGLY red button below WalletConnect pair button
- Create useDirectConnect hook for UGLY direct wallet connections
- Implement UGLY direct MetaMask connection without modal
- Uses display_uri event to capture UGLY WalletConnect URI
- Deep links directly to wallets (UGLY but works!)
- Desktop shows UGLY alert with URI (QR code POC)

This is an intentionally UGLY proof of concept to demonstrate
programmatic wallet connection via WalletConnect without the modal.

🚨 WARNING: This is UGLY test code - DO NOT use in production! 🚨

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@gomesalexandre gomesalexandre changed the title wip: ugly red POC div wip: ugly red div POC Oct 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 21, 2025

📝 Walkthrough

Walkthrough

Introduces WalletConnect V2 direct connection feature allowing users to connect to specific wallets (MetaMask, Trust, Zerion) without showing the modal. Adds feature flag configuration, new components for wallet buttons, connection hook with deep-linking support, and comprehensive documentation.

Changes

Cohort / File(s) Summary
Environment Configuration
.env, .env.development
Added new feature flag VITE_FEATURE_WC_DIRECT_CONNECTION with production default false and development default true.
Core Config & State
src/config.ts, src/state/slices/preferencesSlice/preferencesSlice.ts, src/test/mocks/store.ts
Integrated VITE_FEATURE_WC_DIRECT_CONNECTION into config validator, Redux feature flags, and mock store state.
WalletConnect V2 Configuration
src/context/WalletProvider/WalletConnectV2/config.ts, src/context/WalletProvider/WalletConnectV2/constants.ts
Added walletConnectV2DirectProviderConfig with QR modal disabled and WALLET_CONFIGS array with MetaMask, Trust, and Zerion wallet metadata including icons.
Direct Connection Hook
src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts
New hook managing direct WalletConnect connections, handling provider initialization, deep-link URI subscription, wallet state setup, error handling, and connection lifecycle.
UI Components
src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx, src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
Created WalletConnectDirectRow component with DirectWalletButton subcomponent for rendering wallet options with loading states; integrated into WalletConnectV2Routes behind feature flag.
Documentation
src/context/WalletProvider/WalletConnectV2/README.md
Added comprehensive guide covering architecture, direct connection feature, configuration, state management, wallet metadata handling, and integration workflows.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as WalletConnectDirectRow
    participant Hook as useDirectWalletConnect
    participant Provider as WalletConnect V2<br/>EthereumProvider
    participant Wallet as Wallet App
    participant State as Redux State

    User->>UI: Click wallet button
    activate UI
    UI->>UI: Set loading state
    UI->>Hook: connect(walletId)
    deactivate UI
    
    activate Hook
    Hook->>Provider: Create provider<br/>(showQrModal: false)
    activate Provider
    Hook->>Provider: Subscribe to display_uri
    Provider-->>Hook: Emit display_uri event
    Hook->>Wallet: Open deep link
    deactivate Provider
    
    Wallet->>Wallet: User approves connection
    Wallet->>Provider: Respond to connection request
    activate Provider
    Provider-->>Hook: Connection established
    deactivate Provider
    
    Hook->>State: setWallet() - Update<br/>wallet state
    Hook->>State: Store deviceId &<br/>persist wallet
    Hook->>State: Close modal
    Hook-->>UI: Connection complete
    deactivate Hook
    
    UI->>UI: Clear loading state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Multiple new components and hooks with state management integration, feature flag wiring across config/state layers, and new control flow logic for provider initialization and deep-linking. Changes are additive and follow established patterns but span several concerns and introduce non-trivial wallet connection orchestration.

Suggested reviewers

  • NeOMakinG
  • premiumjibles

Poem

🐰✨ A hop, a skip, through wallets we click—
Direct connections, no modal trick!
MetaMask, Trust, and Zerion align,
Deep-linked wallets work just fine!
Bounces away with feature flag pride 🎉

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly summarizes the introduction of a direct programmatic WalletConnect feature that allows connecting to specific wallets, which aligns with the primary objective of the changeset.
Linked Issues Check ✅ Passed The changes introduce a feature-flagged direct-connect UI with buttons for MetaMask, Trust, and Zerion that bypass the standard modal while retaining “View All Wallets” fallback, implement a direct provider configuration and hook to integrate with the HDWallet abstraction, and thus fulfill the core objectives of the spike issue #10877 even though installed-wallet detection remains as a follow-on exploration.
Out of Scope Changes Check ✅ Passed All changes—including environment variable additions, feature flag wiring, provider and hook implementations, mock updates, and documentation—directly support the programmatic WalletConnect direct-connect feature and adhere to the objectives without introducing unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat_wc_ugly_red_div

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

gomesalexandre and others added 21 commits October 22, 2025 00:49
Improvements to direct WalletConnect connection POC:
- Add third wallet button for Zerion (zerion://wc?uri=)
- Implement separate loading states per wallet button
- Auto-close modal on successful connection
- Remove toast notifications for cleaner UX
- Add comprehensive documentation explaining the hack
- Fix type naming to avoid confusion (WalletConnectWalletId)
- Document deep link references with sources

The hack: We bypass the WalletConnect modal by setting showQrModal: false
and manually constructing deep links, while maintaining full WalletConnect
v2 functionality through the relay servers.

See docs/walletconnect-direct-connection.md for detailed explanation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The modal was closing before the deep link even opened the wallet app.
Fixed by removing all manual SET_WALLET_MODAL dispatches and letting
the parent component handle modal lifecycle.

Now the flow is:
1. Click UGLY button
2. Deep link opens wallet app (modal stays open)
3. User approves in wallet
4. Connection completes
5. Modal closes via parent component logic

This matches the standard WalletConnect flow timing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- MetaMask: Just UGLY (baseline ugliness)
- Trust: SUPER UGLY (elevated ugliness)
- Zerion: F**KING UGLY (maximum ugliness achieved)

Updated button labels and badges to reflect the proper UGLY hierarchy as requested.
The ugliness now escalates appropriately from wallet to wallet.

UGLY POC continues to be UGLY, but now with proper gradation!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Button text changes:
- Removed "POC: Connect WC" prefix
- Now just show wallet names: METAMASK, TRUST, ZERION

Badge improvements:
- All badges positioned on the right (was broken on Trust)
- Maintain UGLY hierarchy: UGLY! → SUPER UGLY! → FUCKING UGLY!
- Removed censorship: F**KING → FUCKING (it's Australian!)

Removed features:
- Attempted spinning animation (didn't work, fuck it)

Updated docs with all latest changes and complete implementation journey.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Changed "FUCKING UGLY!" to "FUARKIN UGLY!" in the Zerion badge.

FUARKIN means thick, solid, tight - not a bad word, trust me bro.

Updated docs to reflect proper aesthetic terminology.

We're all gonna make it! 💪

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Check provider.session and provider.accounts instead of non-existent provider.connected
- Remove premature modal closes from useDirectConnect
- Let button polling be single source of truth for modal closing
- Loading state now persists until wallet is actually connected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove "(UGLY DIRECT)" suffix from wallet name
- Now shows as just "WalletConnect" like regular connection
- Better UX - users don't see implementation details

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove all UGLY references from comments and code
- Remove all console.log statements
- Clean up variable names (uglyProvider -> walletConnectProvider, etc)
- Keep the visual joke with button badges intact (UGLY!, SUPER UGLY!, FUARKIN UGLY!)
- Simplify component documentation
- The joke has lasted long enough in the code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unnecessary empty event listeners (disconnect, session_event)
- Extract shared wallet registration logic to reduce duplication
- Remove unused currentUri state
- Add constants for polling interval and timeout values
- Cleaner, more maintainable code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace loud UGLY styling with clean icon + name layout
- Use Flex layout with 3 buttons horizontally
- Show wallet icons from WalletConnect Explorer API
- Add small WalletConnect badge in corner
- Icons: MetaMask (custom SVG), Trust & Zerion (from WC API)
- Update docs with WalletConnect Explorer API instructions for adding new wallets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Move WC icon from corner to next to wallet name (aligned horizontally)
- Style WC icon with blue circle background and white icon
- Increase icon size to 64px for better visibility
- Rename "Trust Wallet" to "Trust"
- Add minHeight and justify='center' for better alignment
- Use WalletConnectCurrentColorIcon for proper color control

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace icon with spinner when loading (same 64px size for alignment)
- Use isDisabled instead of isLoading on button for cleaner state
- Spinner matches icon size exactly to prevent layout shifts
- Remove unused spinnerElement memoization
- Clean up unused imports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Wrap MetaMask SVG icon in Flex container for consistent sizing
- Ensures all icons occupy same 64px space with centered content
- Fixes vertical alignment discrepancy between SVG and image icons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Document that we're using WalletConnect provider directly without modal - this is the key insight that makes the whole feature work

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@gomesalexandre gomesalexandre changed the title wip: walletconnect connect to specific wallet programatically feat: walletconnect connect to specific wallet programatically Oct 22, 2025
gomesalexandre and others added 3 commits October 22, 2025 20:09
Auto-fixed by eslint

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Add VITE_FEATURE_WC_DIRECT_CONNECTION flag to control direct wallet connection buttons:
- OFF by default (.env)
- ON in development environments (.env.development)
- Wired up in config validator and FeatureFlags type
- WalletConnectDirectRow only renders when flag is enabled

Confirmed: gome.shapeshift.com uses BUILD_MODE=development, so flag will be ON there

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
gomesalexandre and others added 3 commits October 22, 2025 22:36
Move from docs/ to src/context/WalletProvider/WalletConnectV2/README.md for better discoverability.

Cleaned up to be concise and actionable:
- Removed UGLY POC narrative and outdated content
- Updated code examples to match current implementation
- Documented feature flag (VITE_FEATURE_WC_DIRECT_CONNECTION)
- Focused on protocol basics, app implementation, and how to extend
- Serves as comprehensive docs for entire WalletConnectV2 module

Now covers: protocol basics, app implementation, direct connection feature, and adding new wallets.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Use cleaner pattern with base type and never types for better type safety:
- Extract common properties (id, name) to WalletConfigBase
- Use intersection with union for discriminating properties
- Add runtime check for IconComponent to satisfy TypeScript

Also clarify ShapeShift vs wallet app terminology in README.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
localhost works fine for desktop WalletConnect (QR codes).

Deep links are mobile-only and require:
- Real mobile device with wallet apps
- Deployed environment (local IPs rejected by WalletConnect relay)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (8)
src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx (1)

79-91: Render the direct row via PairBody.secondaryContent for cohesion.

Keeps layout/theming consistent and avoids extra fragment wrappers.

-  return (
-    <>
-      <PairBody
+  return (
+    <PairBody
       icon={icon}
       headerTranslation='walletProvider.walletConnect.connect.header'
       bodyTranslation='walletProvider.walletConnect.connect.body'
       buttonTranslation='walletProvider.walletConnect.connect.button'
       isLoading={loading}
       error={error}
       onPairDeviceClick={pairDevice}
-      />
-      {isWcDirectConnectionEnabled && <WalletConnectDirectRow />}
-    </>
+      secondaryContent={isWcDirectConnectionEnabled ? <WalletConnectDirectRow /> : null}
+    />
src/context/WalletProvider/WalletConnectV2/constants.ts (1)

165-171: Use a string enum for wallet IDs per guidelines.

Improves discoverability and avoids typos across callers.

-export type WalletConnectWalletId = 'metamask' | 'trust' | 'zerion'
+export enum WalletConnectWalletId {
+  MetaMask = 'metamask',
+  Trust = 'trust',
+  Zerion = 'zerion',
+}
 
-type WalletConfigBase = {
-  id: WalletConnectWalletId
+type WalletConfigBase = {
+  id: WalletConnectWalletId
   name: string
 }
 
 export const WALLET_CONFIGS: WalletConfig[] = [
   {
-    id: 'metamask',
+    id: WalletConnectWalletId.MetaMask,
     name: 'MetaMask',
     IconComponent: MetaMaskIcon,
   },
   {
-    id: 'trust',
+    id: WalletConnectWalletId.Trust,
     name: 'Trust',
     imageUrl: TrustWalletIcon,
   },
   {
-    id: 'zerion',
+    id: WalletConnectWalletId.Zerion,
     name: 'Zerion',
     imageUrl: ZerionWalletIcon,
   },
 ]

Also applies to: 178-194

src/context/WalletProvider/WalletConnectV2/README.md (1)

18-31: Docs are solid; fix fenced-code languages and a small grammar nit.

Adds language tags for lint, and clarifies the mobile testing note. Optional: mention universal link fallbacks for better iOS UX.

-```
+```text
 ShapeShift (dApp) → WalletConnect SDK → Relay Server ← User's Wallet App

- +text
wc:94caa59c77dae0dd234b5818fb7292540d017b27d41f7f387ee75b22b9738c94@2?relay-protocol=irn&symKey=...


-```
+```text
src/context/WalletProvider/WalletConnectV2/
├── README.md                           # This file
├── config.ts                           # Provider configs
├── constants.ts                        # Wallet configs, types
├── useDirectConnect.ts                 # Direct connection hook
├── useWalletConnectV2EventHandler.ts  # Provider event handlers
└── components/
    ├── Connect.tsx                     # Standard modal flow
    └── WalletConnectDirectRow.tsx      # Direct connection buttons

-typescript +ts
// Create provider without modal
const provider = await EthereumProvider.init({
...walletConnectV2DirectProviderConfig, // showQrModal: false
})

// Intercept URI and build custom deep link
provider.on('display_uri', (uri: string) => {
const deepLink = ${walletId}://wc?uri=${encodeURIComponent(uri)}
window.open(deepLink, '_blank')
})

// Wait for connection (promise survives app switch!)
await provider.enable()

// Register wallet in ShapeShift state
await setWallet(provider, dispatch, localWallet)


-```bash
+```bash
curl "https://explorer-api.walletconnect.com/v3/wallets?projectId=YOUR_PROJECT_ID&search=rainbow"

-typescript +ts
// Add to type
export type WalletConnectWalletId = 'metamask' | 'trust' | 'zerion' | 'rainbow'

// Import icon
import RainbowWalletIcon from '@/assets/rainbow-wallet.png'

// Add to configs
export const WALLET_CONFIGS: WalletConfig[] = [
// ... existing wallets
{
id: 'rainbow',
name: 'Rainbow',
imageUrl: RainbowWalletIcon,
},
]


-Deep links require actual mobile devices with wallet apps installed. Testing requires:
-- ✅ Deploy to remote domain (`*.shapeshift.com`)
-- ❌ Local IP addresses (`192.168.x.x`) - WalletConnect relay rejects them
-- Must use ephemeral environment (gome, private, etc.) to test on phone
+Deep links require actual mobile devices with wallet apps installed. Testing requires:
+- ✅ Deploy to remote domain (`*.shapeshift.com`)
+- ❌ Local IP addresses (`192.168.x.x`) — WalletConnect relay rejects them
+- ✅ Use an ephemeral environment (e.g., gome, private) to test on a phone
+
+Optional:
+- Use universal-link fallbacks when available (e.g., MetaMask `https://metamask.app.link/wc?uri=...`) to improve iOS behavior.

Also applies to: 38-49, 92-111, 154-190, 208-213

src/context/WalletProvider/WalletConnectV2/config.ts (1)

118-122: Type the config with provider’s options and drop redundant property.

Looks good. Two small tweaks:

  • Omit qrModalOptions since showQrModal is false.
  • Re-export this object typed to @walletconnect/ethereum-provider’s EthereumProviderOptions so we can remove the as any cast at init.

Apply locally here:

-import type { EthereumProviderOptions } from './constants'
+import type { EthereumProviderOptions as WcEthereumProviderOptions } from '@walletconnect/ethereum-provider'-export const walletConnectV2DirectProviderConfig: EthereumProviderOptions = {
+export const walletConnectV2DirectProviderConfig: WcEthereumProviderOptions = {
   ...walletConnectV2ProviderConfig,
   showQrModal: false,
-  qrModalOptions: undefined,
 }

And in useDirectConnect.ts replace the cast:

-const provider = await EthereumProvider.init(walletConnectV2DirectProviderConfig as any)
+const provider = await EthereumProvider.init(walletConnectV2DirectProviderConfig)

Also ensure VITE_WALLET_CONNECT_WALLET_PROJECT_ID is required at config load (fail fast). Based on learnings.

src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts (2)

81-87: Avoid as any; pass properly typed options.

Once config exports WcEthereumProviderOptions, this cast can be removed.

-const provider = await EthereumProvider.init(walletConnectV2DirectProviderConfig as any)
+const provider = await EthereumProvider.init(walletConnectV2DirectProviderConfig)

83-87: Use a one-time listener and clean up to prevent duplicate deep links.

Switch to once() if available, or unregister after first fire.

-// Intercept the URI and open the wallet directly via deep link
-provider.on('display_uri', (uri: string) => openDeepLink(walletId, uri))
+const onDisplayUri = (uri: string) => {
+  openDeepLink(walletId, uri)
+  provider.off?.('display_uri', onDisplayUri)
+}
+provider.once ? provider.once('display_uri', onDisplayUri) : provider.on('display_uri', onDisplayUri)
src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx (2)

22-37: Memoize button and add alt text for accessibility.

  • Wrap DirectWalletButton with React.memo to avoid unnecessary re-renders.
  • Provide alt text on Image.
-import { useCallback, useMemo, useState } from 'react'
+import { memo, useCallback, useMemo, useState } from 'react'-const DirectWalletButton = ({ wallet, isLoading, onConnect }: DirectWalletButtonProps) => {
+const DirectWalletButton = memo(({ wallet, isLoading, onConnect }: DirectWalletButtonProps) => {-    return <Image src={wallet.imageUrl} boxSize='64px' borderRadius='lg' />
+    return <Image src={wallet.imageUrl} alt={`${wallet.name} logo`} boxSize='64px' borderRadius='lg' />
   }, [isLoading, wallet])
…
-}
+})

75-77: Use structured logging and user-facing error toast.

Replace console.error with app logger and show a translated toast via useErrorToast.

Happy to wire this with your project’s logger and useErrorToast; confirm the import path you prefer.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f4367e4 and 11d89ba.

⛔ Files ignored due to path filters (2)
  • src/assets/trust-wallet.png is excluded by !**/*.png
  • src/assets/zerion-wallet.png is excluded by !**/*.png
📒 Files selected for processing (11)
  • .env (1 hunks)
  • .env.development (1 hunks)
  • src/config.ts (1 hunks)
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx (3 hunks)
  • src/context/WalletProvider/WalletConnectV2/README.md (1 hunks)
  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx (1 hunks)
  • src/context/WalletProvider/WalletConnectV2/config.ts (1 hunks)
  • src/context/WalletProvider/WalletConnectV2/constants.ts (2 hunks)
  • src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts (1 hunks)
  • src/state/slices/preferencesSlice/preferencesSlice.ts (2 hunks)
  • src/test/mocks/store.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

**/*.{ts,tsx}: ALWAYS use Result<T, E> pattern for error handling in swappers and APIs
ALWAYS use Ok() and Err() from @sniptt/monads for monadic error handling
ALWAYS use custom error classes from @shapeshiftoss/errors
ALWAYS provide meaningful error codes for internationalization
ALWAYS include relevant details in error objects
ALWAYS wrap async operations in try-catch blocks
ALWAYS use AsyncResultOf utility for converting promises to Results
ALWAYS provide fallback error handling
ALWAYS use timeoutMonadic for API calls
ALWAYS provide appropriate timeout values for API calls
ALWAYS handle timeout errors gracefully
ALWAYS validate inputs before processing
ALWAYS provide clear validation error messages
ALWAYS use early returns for validation failures
ALWAYS log errors for debugging
ALWAYS use structured logging for errors
ALWAYS include relevant context in error logs
Throwing errors instead of using monadic patterns is an anti-pattern
Missing try-catch blocks for async operations is an anti-pattern
Generic error messages without context are an anti-pattern
Not handling specific error types is an anti-pattern
Missing timeout handling is an anti-pattern
No input validation is an anti-pattern
Poor error logging is an anti-pattern
Using any for error types is an anti-pattern
Missing error codes for internationalization is an anti-pattern
No fallback error handling is an anti-pattern
Console.error without structured logging is an anti-pattern

**/*.{ts,tsx}: ALWAYS use camelCase for variables, functions, and methods
ALWAYS use descriptive names that explain the purpose for variables and functions
ALWAYS use verb prefixes for functions that perform actions
ALWAYS use PascalCase for types, interfaces, and enums
ALWAYS use descriptive names that indicate the structure for types, interfaces, and enums
ALWAYS use suffixes like Props, State, Config, Type when appropriate for types and interfaces
ALWAYS use UPPER_SNAKE_CASE for constants and configuration values
ALWAYS use d...

Files:

  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/config.ts
  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx
  • src/test/mocks/store.ts
  • src/context/WalletProvider/WalletConnectV2/constants.ts
  • src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts
  • src/state/slices/preferencesSlice/preferencesSlice.ts
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case

Files:

  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/context/WalletProvider/WalletConnectV2/README.md
  • src/config.ts
  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx
  • src/test/mocks/store.ts
  • src/context/WalletProvider/WalletConnectV2/constants.ts
  • src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts
  • src/state/slices/preferencesSlice/preferencesSlice.ts
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

USE Redux only for global state shared across multiple places

Files:

  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/config.ts
  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx
  • src/test/mocks/store.ts
  • src/context/WalletProvider/WalletConnectV2/constants.ts
  • src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts
  • src/state/slices/preferencesSlice/preferencesSlice.ts
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

**/*.tsx: ALWAYS wrap components in error boundaries
ALWAYS provide user-friendly fallback components in error boundaries
ALWAYS log errors for debugging in error boundaries
ALWAYS use useErrorToast hook for displaying errors
ALWAYS provide translated error messages in error toasts
ALWAYS handle different error types appropriately in error toasts
Missing error boundaries in React components is an anti-pattern

**/*.tsx: ALWAYS use PascalCase for React component names
ALWAYS use descriptive names that indicate the component's purpose
ALWAYS match the component name to the file name
Flag components without PascalCase
Flag default exports for components

Files:

  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{tsx,jsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless absolutely necessary
ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components
NEVER use default exports for components
KEEP component files under 200 lines when possible
BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
USE local state for component-level state
LIFT state up when needed across multiple components
USE Context for avoiding prop drilling
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly
ALWAYS provide user-friendly error messages
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components
ALWAYS use React.lazy for code splitting
Components receiving props are wrapped with memo

Files:

  • src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx
  • src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx
**/use*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/use*.{ts,tsx}: ALWAYS use use prefix for custom hooks
ALWAYS use descriptive names that indicate the hook's purpose
ALWAYS use camelCase after the use prefix for custom hooks

Files:

  • src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
PR: shapeshift/web#10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
PR: shapeshift/web#10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
PR: shapeshift/web#10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
🧬 Code graph analysis (5)
src/context/WalletProvider/WalletConnectV2/config.ts (1)
src/context/WalletProvider/WalletConnectV2/constants.ts (1)
  • EthereumProviderOptions (150-163)
src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx (2)
src/context/WalletProvider/WalletConnectV2/constants.ts (3)
  • WalletConfig (172-176)
  • WalletConnectWalletId (165-165)
  • WALLET_CONFIGS (178-194)
src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts (1)
  • useDirectWalletConnect (62-104)
src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts (4)
src/context/WalletProvider/WalletConnectV2/constants.ts (1)
  • WalletConnectWalletId (165-165)
src/context/WalletProvider/actions.ts (1)
  • ActionTypes (36-119)
src/context/WalletProvider/local-wallet.ts (1)
  • useLocalWallet (12-47)
src/context/WalletProvider/WalletConnectV2/config.ts (2)
  • WalletConnectV2Config (24-35)
  • walletConnectV2DirectProviderConfig (118-122)
src/state/slices/preferencesSlice/preferencesSlice.ts (1)
src/config.ts (1)
  • getConfig (209-211)
src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx (2)
src/context/WalletProvider/NewWalletViews/components/PairBody.tsx (1)
  • PairBody (22-64)
src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx (1)
  • WalletConnectDirectRow (64-95)
🪛 LanguageTool
src/context/WalletProvider/WalletConnectV2/README.md

[grammar] ~212-~212: Ensure spelling is correct
Context: ... them - Must use ephemeral environment (gome, private, etc.) to test on phone ## Re...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
src/context/WalletProvider/WalletConnectV2/README.md

9-9: Link fragments should be valid

(MD051, link-fragments)


18-18: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


28-28: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


38-38: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (7)
.env (1)

21-21: Flag added consistently; LGTM.

Matches config validator and preferences initialization. No action.

.env.development (1)

76-76: Dev override enabled; LGTM.

Correctly gates direct-connect to dev only.

src/config.ts (1)

97-97: Validator added; LGTM.

VITE_FEATURE_WC_DIRECT_CONNECTION default false aligns with feature-flag pattern here.

src/test/mocks/store.ts (1)

119-121: Mocks updated; LGTM.

New WcDirectConnection flag present in mock store so tests won’t crash on selector reads.

src/context/WalletProvider/NewWalletViews/routes/WalletConnectV2Routes.tsx (1)

27-27: Flag gate looks correct; confirm modal closes on direct-connect success.

Ensure WalletConnectDirectRow path dispatches SET_WALLET_MODAL false after success to mirror pairDevice().

src/state/slices/preferencesSlice/preferencesSlice.ts (1)

47-48: Feature flag thread complete; LGTM.

Type added and initial state wired from getConfig(). No gaps.

Also applies to: 172-173

src/context/WalletProvider/WalletConnectV2/constants.ts (1)

1-4: Verify image module declarations exist.

Ensure a global.d.ts (e.g., declare module '*.png') is present so TS recognizes these imports.

Copy link
Collaborator

@NeOMakinG NeOMakinG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirming it works super well on mobile

I've been able to connect to MM, zerion and trust on my mobile using my browser!

@gomesalexandre gomesalexandre enabled auto-merge (squash) October 24, 2025 13:24
@gomesalexandre gomesalexandre merged commit 281cf29 into develop Oct 24, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_wc_ugly_red_div branch October 24, 2025 15:04
@coderabbitai coderabbitai bot mentioned this pull request Oct 24, 2025
1 task
gomesalexandre added a commit that referenced this pull request Oct 27, 2025
- Fix terminology: "Deep Link via WalletConnect Modal" for mobile web
- Clarify mobile app supports both paste link and deep link
- Add PR #10879 as initial direct connection implementation
- Note iOS wallet detection is a spike in progress
- Add demo video link for direct connection feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
premiumjibles pushed a commit that referenced this pull request Oct 27, 2025
* wip: wc docs

* [skip ci] feat: kiss

* docs: add comprehensive WalletConnect feature documentation

Add simplified documentation for WalletConnect features:

- WalletConnect Wallet: Connect external wallets to ShapeShift
  - Current: QR code connection
  - Coming: Direct connection (mobile web) - PR #10912
  - Future: iOS wallet detection - #10893

- WalletConnect to dApps: Connect ShapeShift wallet to DApps
  - Paste connection links
  - Deep link support (app.shapeshift.com/wc)
  - Works across desktop, mobile web, and mobile app

Docs focused on what we support and how it works, with minimal
fluff and clear platform support matrices.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: clarify WalletConnect modal already has wallet buttons on mobile

The WalletConnect modal already shows wallet buttons on mobile web
that deep link to wallet apps - this is already live. The "Direct
Connection" feature is about skipping the WalletConnect modal entirely
by showing wallet buttons directly in ShapeShift's UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: fix WalletConnect to dApps details

- Use "Connect dApp" button (not Settings menu)
- Note: only works with native wallet currently
- Remove fluff "What You Can Do" section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: remove session management fluff from WalletConnect to dApps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: fix mobile app WalletConnect to dApps support

Mobile app supports both paste link and deep link methods,
not just deep link only.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: final WalletConnect documentation updates

- Fix terminology: "Deep Link via WalletConnect Modal" for mobile web
- Clarify mobile app supports both paste link and deep link
- Add PR #10879 as initial direct connection implementation
- Note iOS wallet detection is a spike in progress
- Add demo video link for direct connection feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: use shorter GitHub URL for direct connection demo video

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update

* feat: update

* feat: clarify deep link methods in WalletConnect DApps docs

Updated the WalletConnect DApps documentation to clarify deep linking methods for both desktop and mobile applications, including notes on the status of the apps.

* feat: revise WalletConnect feature documentation

Updated WalletConnect documentation for clarity and added links for further details.

* feat: revise WalletConnect documentation overview section

Updated the WalletConnect documentation to improve clarity and structure.

* feat: update

---------

Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spike: WalletConnect to specific wallet

3 participants