npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@solutiofi/connectorkit-svelte

v0.2.1

Published

Solana wallet connection library for Svelte 5, powered by @solana/connector headless API

Readme

connectorkit-svelte

The ultimate Solana wallet connection library for Svelte 5. Powered by @solana/connector headless API and built with Svelte Runes.

npm version License: MIT

Features

  • Zero-Config Polyfills - Works with Vite/SvelteKit out of the box (no vite-plugin-node-polyfills needed!)
  • 🎨 Fully Themeable - Customize every color with CSS variables
  • 📱 Mobile-First - Deep links to wallet apps + WalletConnect QR codes
  • 🔧 Svelte 5 Runes - Built from the ground up for the new reactivity model
  • 🌐 Wallet Standard - Supports all modern Solana wallets (Phantom, Solflare, Backpack, etc.)
  • ✍️ Signing - Sign messages and transactions with full TypeScript support
  • 💰 Balances - Auto-fetching for SOL and SPL tokens
  • 🎯 Filtering - precise control over which wallets are shown, hidden, or featured
  • 👥 Multi-Account - seamless switching between multiple accounts in a single wallet

Installation

npm install connectorkit-svelte @solana/connector @solana/web3.js
# or
pnpm add connectorkit-svelte @solana/connector @solana/web3.js

Quick Start

  1. Wrap your application with SvelteConnectorProvider:
<!-- +layout.svelte -->
<script lang="ts">
  import { SvelteConnectorProvider, WalletButton } from 'connectorkit-svelte';

  const config = {
    appName: 'My Solana App',
    network: 'mainnet',
    projectId: 'YOUR_WALLETCONNECT_ID' // Optional
  };
</script>

<SvelteConnectorProvider {config}>
  <nav>
    <WalletButton />
  </nav>
  <slot />
</SvelteConnectorProvider>
  1. Use the context in valid child components:
<!-- +page.svelte -->
<script lang="ts">
  import { getConnectorContext, TokenList } from 'connectorkit-svelte';
  
  const ctx = getConnectorContext();
</script>

{#if ctx.state.isConnected}
  <h1>Welcome, {ctx.state.publicKey}</h1>
  <TokenList />
{/if}

Configuration

Detailed configuration reference for SvelteConnectorConfig:

interface SvelteConnectorConfig {
  // --- Basic ---
  appName: string;              // Name shown in wallet connection prompts
  appUrl?: string;              // URL of your app (for wallet metadata)
  network?: 'mainnet' | 'devnet' | 'testnet' | 'localnet'; // Default: 'mainnet'
  
  // --- Connection ---
  autoConnect?: boolean;        // Attempt to auto-connect on load (default: false)
  rpcUrl?: string;              // Custom RPC URL (defaults to public Alchemy endpoint)
  debug?: boolean;              // Enable verbose logging
  
  // --- UI/UX ---
  walletOrder?: string[];       // Sort wallets by name: ['Phantom', 'Backpack']
  walletLimit?: number;         // Max wallets to show before "More" (default: 4)
  imageProxy?: string;          // Proxy URL for wallet icons to avoid CORS issues
  
  // --- Filtering ---
  wallets?: {
    allowList?: string[];       // Strict list: ONLY show these wallets
    denyList?: string[];        // Blacklist: NEVER show these wallets
    featured?: string[];        // Highlight these wallets at the top with a badge
  };

  // --- Network Switching ---
  clusters?: {                  // Custom networks for ClusterSelector
    name: string;
    id: string;
    rpcUrl: string;
    wsUrl?: string;
  }[];

  // --- WalletConnect (Optional) ---
  walletConnect?: {
    projectId: string;          // Get from https://cloud.walletconnect.com
    metadata?: {
      name: string;
      description: string;
      url: string;
      icons: string[];
    };
  };
}

Component Reference

<WalletButton />

The primary connect button. Automatically handles "Connect", "Disconnect", "Copy Address", and "Change Wallet".

| Prop | Type | Default | Description | |------|------|---------|-------------| | size | 'sm' \| 'md' \| 'lg' | 'md' | Scaling of the button | | showIcon | boolean | true | Show wallet icon when connected | | class | string | '' | Custom classes |

<WalletModal />

A standalone modal component. Use this if you want to create your own trigger button.

<script>
  let isOpen = $state(false);
</script>
<button onclick={() => isOpen = true}>Connect Custom</button>
<WalletModal bind:open={isOpen} />

| Prop | Type | Default | Description | |------|------|---------|-------------| | open | boolean | false | Control modal visibility | | title | string | 'Connect Wallet' | Modal title text | | onclose | () => void | - | Called when modal closes | | footer | Snippet | - | Custom footer content (see below) |

Custom Footer Slot

You can pass a custom footer to add additional functionality like Ledger or hardware wallet connections:

<WalletModal bind:open={isOpen}>
  {#snippet footer()}
    <button onclick={handleLedgerConnect}>
      🔒 Connect Ledger
    </button>
  {/snippet}
</WalletModal>

<ClusterSelector />

A dropdown to switch between networks (Mainnet/Devnet/Testnet) or custom clusters.

Multi-Account Support

If a connected wallet provides multiple accounts, connectorkit-svelte automatically handles them. The <WalletButton /> and <WalletDropdown /> include a built-in UI for switching accounts.

The selected account is persisted per-wallet, so users don't need to re-select when they reconnect.

<TokenList />

Displays a list of SPL tokens held by the connected wallet.

  • Auto-fetches from RPC
  • Shows token icons, symbols, and formatted balances
  • Filters out zero-balance tokens

<AddressDisplay />

Displays a truncated wallet address with click-to-copy.

| Prop | Type | Default | Description | |------|------|---------|-------------| | address | string | required | The address to display | | chars | number | 4 | Chars to show (e.g. ABCD...WXYZ) | | copyable | boolean | false | Enable copy-to-clipboard |

Hooks & API

Access the connector state reactively anywhere in your app:

import { getConnectorContext } from 'connectorkit-svelte';

const ctx = getConnectorContext();

State Properties

  • ctx.state.isConnected: boolean
  • ctx.state.publicKey: string | null
  • ctx.state.allAccounts: WalletAccount[] (All available accounts)
  • ctx.state.isConnecting: boolean
  • ctx.state.error: WalletError | null
  • ctx.currentCluster: ClusterConfig used for network switching
  • ctx.currentRpcUrl: string current RPC endpoint

Methods

  • ctx.connect(walletId): Connect to a specific wallet
  • ctx.disconnect(): Disconnect current wallet
  • ctx.signMessage(message): Sign a byte array
  • ctx.signTransaction(tx): Sign a serialized transaction
  • ctx.signAndSendTransaction(tx, options): Sign and submit to network
  • ctx.selectCluster(id): Switch network
  • ctx.selectAccount(address): Switch active account

Theming

All styles are defined as CSS custom properties. Light mode is the default; add .dark class to body for dark mode.

Complete CSS Variable Reference

| Variable | Light Mode | Dark Mode | Description | |----------|------------|-----------|-------------| | Brand Colors |||| | --sck-primary | #008AFF | #3DA6FF | Main action color | | --sck-primary-hover | #0075D9 | #008AFF | Hover state | | Backgrounds |||| | --sck-bg | #FBFCFD | #191C21 | Modal/dropdown background | | --sck-bg-secondary | #F4F5F7 | #272C33 | Card backgrounds | | --sck-bg-hover | #E6E7EB | #30363F | Hover backgrounds | | Text |||| | --sck-text | #1F2329 | #FBFCFD | Primary text | | --sck-text-muted | #5B6778 | #939EAE | Muted text | | Borders |||| | --sck-border | #CBD1D8 | #383F4A | Border color | | Status Colors |||| | --sck-success | #248C3E | #34D058 | Success states | | --sck-error | #E42E2C | #F85149 | Error states | | --sck-warning | #FFA500 | #FFCC00 | Warning states |

Enabling Dark Mode

Add the .dark class to the body element to activate dark mode:

<script>
  import { onMount } from 'svelte';
  let isDark = $state(true);

  onMount(() => {
    // Restore from localStorage or use system preference
    const saved = localStorage.getItem('theme');
    isDark = saved ? saved === 'dark' : window.matchMedia('(prefers-color-scheme: dark)').matches;
    applyTheme();
  });

  function toggleTheme() {
    isDark = !isDark;
    localStorage.setItem('theme', isDark ? 'dark' : 'light');
    applyTheme();
  }

  function applyTheme() {
    document.body.classList.toggle('dark', isDark);
  }
</script>

<button onclick={toggleTheme}>
  {isDark ? '☀️' : '🌙'}
</button>

Troubleshooting & FAQ

"Global is not defined" or "Buffer is not defined"?

You generally do not need to configure this manually. connectorkit-svelte automatically polyfills global, Buffer, and process in the browser environment when the provider mounts.

Does this work with SvelteKit SSR?

Yes. The library checks for window before running any wallet logic. However, you should ensure <SvelteConnectorProvider> is only rendered in the client or handles checking browser from $app/environment if you run into hydration mismatches (though we handle most cases internally).

My wallet isn't showing up?

  1. Ensure the wallet is installed and supports the Wallet Standard (most do).
  2. Check if you have wallets.allowList configured and the wallet is missing from it.
  3. Check wallets.denyList.

Mobile wallets aren't detected?

On mobile Safari/Chrome, wallet extensions can't inject—wallets are standalone apps. connectorkit-svelte handles this automatically:

Native Mobile App Support (Automatic):

  • On mobile devices, wallets like Phantom, Solflare, Backpack, Jupiter, and Magic Eden are automatically detected and added to the wallet list.
  • They appear as standard wallets in the connect modal.
  • Tapping them initiates a secure Deep Link connection (redirects to the wallet app).
  • After approval, the wallet redirects back to your dApp, and the connection is automatically established.

WalletConnect (recommended as fallback): Configure WalletConnect for universal mobile support:

const config = {
  appName: 'My App',
  network: 'mainnet',
  walletConnect: {
    projectId: 'YOUR_PROJECT_ID', // Free at https://cloud.walletconnect.com
    metadata: {
      name: 'My App',
      description: 'My Solana dApp',
      url: 'https://myapp.com',
      icons: ['https://myapp.com/icon.png']
    }
  }
};

Mobile connection flow:

  1. User opens your dApp in mobile Safari/Chrome
  2. Taps "Connect Wallet"
  3. Sees Phantom, Solflare, etc. in the standard wallet list
  4. Taps "Phantom" -> Redirects to Phantom app -> User Connects
  5. Redirects back to your dApp -> Wallet is designated as "Connected"

Pro tip: If users open your dApp from within a wallet's browser (e.g., Phantom's built-in browser), wallets inject automatically—no deep links needed.

License

MIT © 2026 Connectorkit Authors