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

ic-siwa

v0.1.2

Published

Sign in with Avalanche for the Internet Computer

Readme

IC-SIWA TypeScript Library

Sign in with Avalanche for the Internet Computer.

Installation

bun add ic-siwa
# or
npm install ic-siwa

Quick Start

import {SiwaClient} from "ic-siwa";
import {createWalletClient, http} from "viem";
import {avalanche} from "viem/chains";

// Create SIWA client
const siwa = new SiwaClient({
  canisterId: "xxxxx-xxxxx-xxxxx-xxxxx-xxx",
});

// Create wallet client (using viem)
const walletClient = createWalletClient({
  chain: avalanche,
  transport: http(),
});

// Login with wallet
const result = await siwa.loginWithWallet(walletClient);
console.log("Logged in as:", result.principal.toText());

// Check if authenticated
if (await siwa.isAuthenticated()) {
  const principal = await siwa.getPrincipal();
  console.log("Current principal:", principal?.toText());
}

// Make authenticated calls
const actor = await siwa.createActor(canisterId, idlFactory);
const data = await actor.getData();

// Logout
await siwa.logout();

Manual Login Flow

If you need more control over the login process:

const siwa = new SiwaClient({
  canisterId: "xxxxx-xxxxx-xxxxx-xxxxx-xxx",
});

// 1. Prepare login message
const address = "0x1234...abcd";
const prepared = await siwa.prepareLogin(address);

// 2. Sign message with your wallet
const signature = await wallet.signMessage(prepared.message);

// 3. Complete login
const result = await siwa.login(signature, address);

Configuration Options

const siwa = new SiwaClient({
  // Required: IC-SIWA Provider canister ID
  canisterId: "xxxxx-xxxxx-xxxxx-xxxxx-xxx",

  // Optional: IC host (default: https://ic0.app)
  host: "https://ic0.app",

  // Optional: Custom storage provider (default: localStorage)
  storage: new MemoryStorageProvider(),

  // Optional: Auto-refresh delegation before expiry (default: true)
  autoRefresh: true,
});

Storage Providers

The library includes two storage providers:

  • LocalStorageProvider (default) - Persists identity in browser localStorage
  • MemoryStorageProvider - In-memory storage for testing or SSR

You can also implement your own by implementing the StorageProvider interface.

Error Handling

import {SiwaError, SiwaErrorCode} from "ic-siwa";

try {
  await siwa.login(signature, address);
} catch (error) {
  if (error instanceof SiwaError) {
    switch (error.code) {
      case SiwaErrorCode.InvalidSignature:
        console.error("Invalid signature");
        break;
      case SiwaErrorCode.MessageExpired:
        console.error("Login message expired");
        break;
      default:
        console.error("Login failed:", error.message);
    }
  }
}

Astro Component

The library includes a ready-to-use Astro component for the login button.

Basic Usage

---
import LoginButton from 'ic-siwa/astro';
---

<LoginButton canisterId="xxxxx-xxxxx-xxxxx-xxxxx-xxx" />

Props

| Prop | Type | Default | Description | | ------------- | ------------------------------------- | ------------------------ | ---------------------------- | | canisterId | string | required | IC-SIWA Provider canister ID | | host | string | https://ic0.app | IC host URL | | label | string | Sign in with Avalanche | Button text | | size | xs\|sm\|md\|lg\|xl | md | Button size | | variant | primary\|secondary\|accent\|neutral | primary | Color variant | | style | solid\|outline\|soft\|ghost | solid | Button style | | showAddress | boolean | true | Show address when logged in | | class | string | "" | Additional CSS classes | | id | string | siwa-login-btn | Custom element ID |

Custom Styling

<LoginButton
  canisterId="xxxxx-xxxxx-xxxxx-xxxxx-xxx"
  label="Connect Wallet"
  variant="accent"
  style="outline"
  size="lg"
  class="my-custom-class"
/>

Events

The component emits custom events you can listen to:

---
import LoginButton from 'ic-siwa/astro';
---

<div id="auth-container">
  <LoginButton canisterId="xxxxx-xxxxx-xxxxx-xxxxx-xxx" />
</div>

<script>
  const container = document.getElementById('auth-container');

  container.addEventListener('siwa:login-start', () => {
    console.log('Login started...');
  });

  container.addEventListener('siwa:login-success', (e) => {
    console.log('Logged in as:', e.detail.principal);
    console.log('Address:', e.detail.address);
  });

  container.addEventListener('siwa:login-error', (e) => {
    console.error('Login failed:', e.detail.error);
  });

  container.addEventListener('siwa:logout', () => {
    console.log('User logged out');
  });
</script>

Custom Icon

You can replace the default Avalanche logo with a custom icon:

<LoginButton canisterId="xxxxx-xxxxx-xxxxx-xxxxx-xxx">
  <svg slot="icon" ...>...</svg>
</LoginButton>

Requirements

  • DaisyUI and Tailwind CSS for the Astro component styling
  • An Avalanche-compatible wallet (Core, MetaMask, etc.)
  • Deployed ic_siwa_provider canister

License

Unlicense