Skip to content

Conversation

@DrJesseGlass
Copy link

PR: Add Legacy Wallet Adapter for SIWS Support

Summary

Adds automatic patching for Solana wallets that support signMessage but lack native SIWS signIn, enabling legacy wallets like Glow to authenticate without requiring wallet developer updates.

Problem

There exist popular Solana wallets that only implement signMessage and lack the newer signIn method required for Sign-In With Solana (SIWS), preventing users from authenticating with IC applications.

Solution

Lightweight adapter pattern that wraps legacy wallets and synthesizes a signIn method using their existing signMessage functionality. The patching is automatic, transparent, and never overwrites native implementations.

Minimal:

  • One self-contained file with all patching logic
  • Two small integration points in existing code

Safe:

  • Never overwrites native implementations
  • Returns original adapter unchanged if patching impossible
  • No changes to authentication flow logic

Non-Breaking:

  • Network parameter is optional with sensible default
  • All existing functionality preserved
  • Backward compatible with existing integrations

Core Changes

1. New File: src/siws-legacy-adapter.ts

Single-purpose utility that:

  • Detects if wallet has native signIn support
  • For legacy wallets: constructs proper SIWS message → calls signMessage → returns result in signIn format
  • Tracks patch state with Symbols to prevent double-patching
  • Supports network switching via re-patching

2. Modified: src/index.ts (SiwsManager)

  • Added network parameter
  • Updated setAdapter to patch before storing

3. Modified: src/react/index.tsx

  • Added network?: string prop to SiwsIdentityProvider and passed it through to SiwsManager.

4. Modified: src/delegation.ts - ~3 lines

  • Added @ts-ignore comments for dfinity v2.4.1 ArrayBuffer type strictness issues. Unrelated to SIWS functionality but necessary for builds to succeed.

Demo Updates

The demo's provider needed proper state management to handle wallet connection lifecycle:

Before:

const { wallet } = useWallet();
return (
  <SiwsIdentityProvider canisterId={canisterId} adapter={wallet?.adapter}>
    {children}
  </SiwsIdentityProvider>
);

Issues:

  • Provider only renders when wallet exists → "must be used within provider" errors
  • No handling of wallet connect/disconnect/switch events
  • Adapter can be undefined causing runtime issues

After:

const wallet = useWallet();
const [currentAdapter, setCurrentAdapter] = useState<Adapter | undefined>(undefined);

useEffect(() => {
  if (wallet.connected && wallet.wallet?.adapter) {
    setCurrentAdapter(wallet.wallet.adapter);
  } else {
    setCurrentAdapter(undefined);
  }
}, [wallet.connected, wallet.wallet?.adapter]);

return (
  <SiwsIdentityProvider 
    canisterId={canisterId} 
    adapter={currentAdapter} 
    network="devnet"
  >
    {children}
  </SiwsIdentityProvider>
);

Improvements:

  • Provider always renders (even with undefined adapter) → no context errors
  • Proper state tracking of wallet connection
  • Handles wallet switching and disconnection
  • Explicit network configuration

Testing

Verified Wallets:

  • Phantom - Has native signIn support, no patching needed. Console: "Phantom already has native signIn; leaving as-is"
  • Backpack - Has native signIn support, no patching needed.
  • Solflare - Successfully patched! Console: "Patching Solflare to add SIWS signIn support (network: devnet)"
  • Glow - Expected to work with patching (needs testing)

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.

1 participant