Skip to content

Conversation

@drichar
Copy link
Collaborator

@drichar drichar commented Jan 9, 2026

Description

This PR introduces "WalletConnect Skins" - a pattern that allows multiple WalletConnect-based wallets to coexist in the same application with distinct branding and isolated session state.

Instead of creating separate wallet implementations for each WalletConnect-based wallet (like Biatec, Voi Wallet, etc.), developers can now configure a single WalletId.WALLETCONNECT with a skin option that provides custom name/icon metadata. Built-in skins are still documented in the library's Supported Wallets page for discoverability.

Details

Composite Key Architecture

Each skinned wallet instance gets a unique walletKey (e.g., walletconnect:biatec) derived from the skin ID. This key is used for:

  • State isolation in the store
  • Session storage separation
  • Wallet lookup via manager.getWallet()

Skin Configuration

const manager = new WalletManager({
  wallets: [
    // Generic WalletConnect
    { id: WalletId.WALLETCONNECT, options: { projectId: '...' } },

    // Built-in skin (string ID)
    { id: WalletId.WALLETCONNECT, options: { projectId: '...', skin: 'biatec' } },

    // Custom skin (inline object)
    {
      id: WalletId.WALLETCONNECT,
      options: {
        projectId: '...',
        skin: { id: 'mywallet', name: 'My Wallet', icon: 'data:image/...' }
      }
    }
  ]
})

// Access by unique key
const biatec = manager.getWallet('walletconnect:biatec')

Changes

Core Library

  • Add WalletConnectSkin type and skin registry (skins.ts)
  • Add walletKey property to BaseWallet for state isolation
  • Update store to key wallet state by walletKey instead of id
  • Update WalletManager to derive composite keys and prevent duplicates
  • Deprecate WalletId.BIATEC in favor of skin: 'biatec'

Framework Adapters

  • Add walletKey to the Wallet interface in React, Vue, Solid, and Svelte adapters
  • Update state lookups to use walletKey

Examples

  • Update all example projects to use the new skinned approach

Documentation

  • Document the skins feature with usage examples
  • Add deprecation notice for WalletId.BIATEC

cc @scholtz @xarmian - I'd appreciate your feedback on this approach. This was inspired by #407 (Voi Wallet) which follows the same pattern as Biatec. Rather than continuing to add separate wallet IDs for each WalletConnect-based wallet, this skins pattern allows them to be configured as branded WalletConnect instances while maintaining full backward compatibility.

The WalletId.BIATEC enum value is deprecated but will continue to work until v5. The built-in 'biatec' skin uses the same icon and metadata, so existing users can migrate at their convenience.

WalletId.VOIWALLET can be added to the built-in skins registry and documentation similarly.

Enable multiple WalletConnect-based wallets to coexist with distinct branding
using a composite key architecture. Wallets can now specify a `skin` option
that provides custom name/icon metadata and derives a unique `walletKey`
(e.g., `walletconnect:biatec`), allowing separate state isolation.

Core changes:
- Add WalletConnectSkin type and skin registry with built-in Biatec skin
- Add `walletKey` property to BaseWallet for state isolation
- Update store to use `walletKey` instead of `id` for wallet state keys
- Update WalletManager to derive composite keys and prevent duplicates
- Deprecate WalletId.BIATEC in favor of WalletConnect with `skin: 'biatec'`

Framework adapter updates:
- use-wallet-react: Add walletKey to Wallet interface, use for state lookups
- use-wallet-vue: Add walletKey to Wallet interface, use for state lookups
- use-wallet-solid: Update state lookups to use walletKey
- use-wallet-svelte: Add walletKey to Wallet interface, use for state lookups
Add documentation for the WalletConnect skins feature including:
- `skin` option in WalletConnect configuration
- Built-in skin usage example
- Custom skin definition at runtime
- Multiple WalletConnect instances with isolated sessions
- Accessing wallets by composite key (e.g., 'walletconnect:biatec')

Add deprecation notice for `WalletId.BIATEC` with migration guidance.
Replace deprecated `WalletId.BIATEC` with WalletConnect using `skin: 'biatec'`
option across all example projects.

- nextjs
- nuxt
- react-ts
- solid-ts
- svelte-ts
- vanilla-ts
- vue-ts
@xarmian
Copy link

xarmian commented Jan 9, 2026

@drichar I agree this is a great approach

@gabrielkuettel
Copy link
Contributor

@drichar looks great! I love the idea. I think the only question I would have is the performance/memory overhead of opening separate WC sessions / websockets for each wallet? This might be a problem for low-end mobile devices if you add too many of them. If so, maybe just document that and recommend using generic WC skins if that's a concern for the developer.

@drichar
Copy link
Collaborator Author

drichar commented Jan 9, 2026

@drichar looks great! I love the idea. I think the only question I would have is the performance/memory overhead of opening separate WC sessions / websockets for each wallet? This might be a problem for low-end mobile devices if you add too many of them. If so, maybe just document that and recommend using generic WC skins if that's a concern for the developer.

Thanks! The sessions are only created when a user actually connects a wallet, not when WalletManager initializes. Having multiple skins configured doesn't establish any connections until the user chooses to connect. Most users connect a single wallet, and most apps present a binary connected/disconnected state. If an app supports multiple simultaneous connections (like NFDomains), you'd have parallel WC sessions - but that's already how generic WC and Biatec work today.

This feature just makes them easier to manage, avoiding separate implementations when all you're really doing is presenting a WalletConnect provider instance as a unique list item with a name and logo.

@gabrielkuettel
Copy link
Contributor

@drichar looks great! I love the idea. I think the only question I would have is the performance/memory overhead of opening separate WC sessions / websockets for each wallet? This might be a problem for low-end mobile devices if you add too many of them. If so, maybe just document that and recommend using generic WC skins if that's a concern for the developer.

Thanks! The sessions are only created when a user actually connects a wallet, not when WalletManager initializes. Having multiple skins configured doesn't establish any connections until the user chooses to connect. Most users connect a single wallet, and most apps present a binary connected/disconnected state. If an app supports multiple simultaneous connections (like NFDomains), you'd have parallel WC sessions - but that's already how generic WC and Biatec work today.

This feature just makes them easier to manage, avoiding separate implementations when all you're really doing is presenting a WalletConnect provider instance as a unique list item with a name and logo.

makes sense.

@drichar drichar merged commit fc70097 into main Jan 15, 2026
1 check passed
@drichar drichar deleted the feat/walletconnect-skins branch January 15, 2026 07:42
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.

4 participants