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

@albionlabs/chat-widget

v0.2.9

Published

Embeddable Svelte 5 chat widget that connects to a quant.bot gateway via WebSocket. Supports wallet-based authentication (SIWE), on-chain transaction signing, and floating or inline layouts.

Readme

@albionlabs/chat-widget

Embeddable Svelte 5 chat widget that connects to a quant.bot gateway via WebSocket. Supports wallet-based authentication (SIWE), on-chain transaction signing, and floating or inline layouts.

Install

npm install @albionlabs/chat-widget
# or
pnpm add @albionlabs/chat-widget

Peer dependency: Svelte 5+

Quick Start (Floating Widget)

The ChatWidgetFloating component is the recommended integration. It renders a floating chat bubble in the corner of your page with built-in SIWE authentication, transaction signing, and unread message tracking.

<script lang="ts">
  import { ChatWidgetFloating, setWalletProvider, clearWalletProvider } from '@albionlabs/chat-widget'

  // Your wallet connection logic — any EIP-1193 provider works
  let walletProvider = $state(null)

  function connectWallet() {
    // Use your preferred wallet SDK (wagmi, Dynamic, RainbowKit, etc.)
    // Once connected, call setWalletProvider() with the EIP-1193 provider
  }

  $effect(() => {
    if (walletProvider) {
      setWalletProvider(walletProvider)
    } else {
      clearWalletProvider()
    }
  })
</script>

<ChatWidgetFloating
  config={{ gatewayUrl: 'https://your-gateway.example.com', apiKey: 'your-api-key' }}
  callbacks={{ onRequestWalletConnect: connectWallet }}
/>

That's it. The widget handles SIWE sign-in, WebSocket connection, and chat UI automatically.

Configuration

FloatingChatWidgetConfig

| Property | Type | Required | Default | Description | |----------|------|----------|---------|-------------| | gatewayUrl | string | Yes | — | Gateway base URL (https:// or http://). Converted to wss:///ws:// internally. | | apiKey | string | Yes | — | API key provided by the gateway operator. | | position | 'bottom-right' \| 'bottom-left' | No | 'bottom-right' | Corner placement of the floating bubble. | | offset | { x: number; y: number } | No | { x: 24, y: 24 } | Pixel offset from the corner. | | startOpen | boolean | No | false | Open the chat panel immediately on mount. | | theme | 'light' \| 'dark' | No | 'dark' | Widget color theme. | | name | string | No | 'quant.bot' | Display name shown in the header and SIWE sign-in message. |

FloatingChatCallbacks

| Callback | Description | |----------|-------------| | onRequestWalletConnect | Fired when the user clicks "Connect Wallet" inside the widget. Use this to trigger your wallet SDK's connect flow. | | onOpen | Fired when the chat panel opens. | | onClose | Fired when the chat panel closes. |

Wallet Provider

The widget accepts any EIP-1193 compatible provider. This is the standard interface exposed by MetaMask, wagmi, Dynamic, RainbowKit, and most wallet SDKs.

interface WalletProvider {
  request: (args: { method: string; params?: unknown[] }) => Promise<unknown>
}

The widget uses the following RPC methods through the provider:

| Method | Purpose | |--------|---------| | eth_accounts | Get the connected wallet address | | personal_sign | Sign the SIWE authentication message | | eth_sendTransaction | Sign and send on-chain transactions (strategy deployments, approvals) |

Setting the provider

Call setWalletProvider() whenever a wallet connects, and clearWalletProvider() when it disconnects. The widget detects these changes and manages authentication automatically.

import { setWalletProvider, clearWalletProvider } from '@albionlabs/chat-widget'

// After wallet connects:
setWalletProvider(provider)

// After wallet disconnects:
clearWalletProvider()

Authentication Flow

Authentication is handled automatically by ChatWidgetFloating:

  1. User clicks "Connect Wallet" in the widget header
  2. Widget fires onRequestWalletConnect — your app triggers its wallet SDK
  3. You call setWalletProvider(provider) once connected
  4. Widget auto-initiates SIWE sign-in (creates message, requests signature via personal_sign)
  5. Widget posts the signature to the gateway's /api/auth/login endpoint
  6. On success, the WebSocket connects and the chat is ready

No manual token management is needed.

Integration Examples

With wagmi

<script lang="ts">
  import { ChatWidgetFloating, setWalletProvider, clearWalletProvider } from '@albionlabs/chat-widget'
  import { connect, disconnect, getConnectorClient, signMessage, sendTransaction, switchChain } from '@wagmi/core'
  import { injected } from '@wagmi/connectors'
  import { wagmiConfig } from './wagmi-config'

  let provider = $state(null)

  async function connectWallet() {
    const result = await connect(wagmiConfig, { connector: injected() })
    const client = await getConnectorClient(wagmiConfig)

    provider = {
      request: async (args) => {
        if (args.method === 'personal_sign' && args.params) {
          const [message] = args.params
          return await signMessage(wagmiConfig, { message })
        }
        if (args.method === 'eth_sendTransaction' && args.params) {
          const [tx] = args.params
          const chainId = tx.chainId ? parseInt(tx.chainId, 16) : undefined
          if (chainId) await switchChain(wagmiConfig, { chainId })
          return await sendTransaction(wagmiConfig, {
            to: tx.to,
            data: tx.data,
            value: tx.value ? BigInt(tx.value) : 0n
          })
        }
        if (args.method === 'eth_accounts') {
          return [client.account.address]
        }
        return client.request({ method: args.method, params: args.params })
      }
    }
    setWalletProvider(provider)
  }

  function disconnectWallet() {
    disconnect(wagmiConfig)
    provider = null
    clearWalletProvider()
  }
</script>

<ChatWidgetFloating
  config={{ gatewayUrl: 'https://your-gateway.example.com', apiKey: 'your-api-key' }}
  callbacks={{ onRequestWalletConnect: connectWallet }}
/>

Note: wagmi's sendTransaction() handles chain switching properly, unlike using the raw viem client which may throw a chainId mismatch error.

With MetaMask (direct)

<script lang="ts">
  import { ChatWidgetFloating, setWalletProvider, clearWalletProvider } from '@albionlabs/chat-widget'

  async function connectWallet() {
    if (!window.ethereum) {
      alert('Please install MetaMask')
      return
    }
    await window.ethereum.request({ method: 'eth_requestAccounts' })
    setWalletProvider(window.ethereum)
  }
</script>

<ChatWidgetFloating
  config={{ gatewayUrl: 'https://your-gateway.example.com', apiKey: 'your-api-key' }}
  callbacks={{ onRequestWalletConnect: connectWallet }}
/>

Inline Widget

For full-page layouts (no floating bubble), use ChatWidget directly. You must handle authentication and WebSocket connection yourself.

<script lang="ts">
  import { ChatWidget, connect, setAuth } from '@albionlabs/chat-widget'

  // You manage auth externally:
  setAuth({ token: 'jwt-token', address: '0x...' })
  connect({ gatewayUrl: 'wss://your-gateway.example.com', token: 'jwt-token' })
</script>

<div style="height: 600px;">
  <ChatWidget config={{ gatewayUrl: 'wss://your-gateway.example.com', token: 'jwt-token', name: 'my-bot' }} />
</div>

Transaction Signing

When the AI agent deploys a strategy, the widget handles the full signing flow:

  1. Agent stages transactions via the gateway
  2. Widget displays a signing prompt with transaction details and simulation results
  3. User reviews and confirms
  4. Widget sends each transaction through the wallet provider via eth_sendTransaction
  5. Widget reports transaction hashes back to the gateway
  6. On completion, the Raindex order link is sent to the chat

No additional code is needed — transaction signing works automatically as long as a wallet provider is set.

Theming

The widget supports light and dark color themes via the theme config property.

<!-- Dark theme (default) -->
<ChatWidgetFloating config={{ gatewayUrl, apiKey, theme: 'dark' }} />

<!-- Light theme -->
<ChatWidgetFloating config={{ gatewayUrl, apiKey, theme: 'light' }} />

In dark mode the floating bubble has a dark background with the white Albion marque. In light mode the bubble has a white background with the navy Albion marque. The header stays dark in both themes for brand consistency; the chat body, input, bubbles, modals, and status indicators all adapt.

The inline ChatWidget also accepts theme:

<ChatWidget config={{ gatewayUrl, token, theme: 'light' }} />

Styling

The widget uses its own scoped styles and renders at z-index: 9999. If you have elements that need to appear above the widget, use a higher z-index. The widget's internal modals (e.g., Rainlang review) render at z-index: 10001.

API Reference

Components

| Component | Description | |-----------|-------------| | ChatWidgetFloating | Floating bubble + chat panel with built-in auth. Recommended. | | ChatWidget | Inline chat interface. Requires manual auth/connection setup. | | WalletStatusIndicator | Wallet connection status dot + address display. |

Store Functions

| Function | Description | |----------|-------------| | setWalletProvider(provider) | Register an EIP-1193 wallet provider. | | clearWalletProvider() | Unregister the wallet provider. | | connect(config) | Manually connect the WebSocket (inline widget only). | | disconnect() | Close the WebSocket connection. | | sendMessage(text) | Send a chat message programmatically. | | setAuth({ token, address }) | Set auth state manually (inline widget only). | | clearAuth() | Clear auth state. |

Stores (Readable)

| Store | Type | Description | |-------|------|-------------| | chat | { messages, status, error } | Current chat state. | | auth | { token, address } | Current auth state. |