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

thanos-connect

v0.1.0

Published

Drop-in Sign-In With Thanos integration — EIP-1193 + EIP-6963 discovery, SIWT flow, React + vanilla.

Readme

thanos-connect

Drop-in Sign-In With Thanos integration for third-party dApps.

npm install thanos-connect
# or
pnpm add thanos-connect
# or
yarn add thanos-connect

Zero runtime dependencies. Tree-shakeable. Works with any frontend framework (React component shipped separately at thanos-connect/react).

Why this exists

If you want to add "Sign in with Thanos" to your dApp, you need:

  • EIP-6963 discovery (multi-wallet safe)
  • A SIWE-compatible message format
  • personal_sign round-trip
  • Backend verify endpoint contract
  • Sensible error handling (user cancels, no wallet, etc.)

This package collapses all of that into a single class and one method. Pairs with the wallet's own backend at https://thanos.fi but works with your own auth server too.

60-second integration (vanilla JS / TypeScript)

import { ThanosConnect } from 'thanos-connect';

const thanos = new ThanosConnect({
  appName: 'Ignite DEX',
  chainId: 700777, // Lithosphere Makalu — default
});

// Click handler
document.getElementById('signin').addEventListener('click', async () => {
  try {
    const { address, sessionToken } = await thanos.signIn();
    console.log('signed in as', address);
    // sessionToken is what your /api/auth/verify endpoint returned
  } catch (err) {
    console.error('sign-in failed:', err);
  }
});

That's the whole flow. The package handles discovery, fallback, nonce fetch, signature, and backend verify.

60-second integration (React)

import { ThanosConnectButton } from 'thanos-connect/react';

export function Header() {
  return (
    <ThanosConnectButton
      config={{ appName: 'EGO Exchange', chainId: 700777 }}
      onSignIn={(session) => {
        console.log('signed in:', session.address);
        // Persist session.sessionToken in your auth context
      }}
      onError={(err) => console.error(err)}
    />
  );
}

The button auto-detects whether Thanos is installed and switches to an "Install Thanos Wallet" CTA when it isn't.

For custom UI, use the hook:

import { useThanos } from 'thanos-connect/react';

export function MyConnect() {
  const { signIn, signOut, session, isSigningIn, isAvailable } = useThanos({
    appName: 'AGII',
    chainId: 700777,
  });

  if (!isAvailable) return <a href="https://thanos.fi/app">Install Thanos</a>;
  if (session)     return <button onClick={signOut}>Sign out</button>;
  return <button onClick={() => signIn()} disabled={isSigningIn}>Sign in</button>;
}

Backend contract

By default the package calls two endpoints on your server. Override the paths via nonceEndpoint / verifyEndpoint, or set them to null to handle the round-trip yourself.

GET /api/auth/nonce?address=0x…text/plain

Issue a fresh nonce keyed by address with a 5-10 min TTL. Return as plain text (not JSON). Example (Express):

import crypto from 'crypto';

app.get('/api/auth/nonce', (req, res) => {
  const address = req.query.address as string;
  if (!/^0x[a-fA-F0-9]{40}$/.test(address)) return res.status(400).end();
  const nonce = crypto.randomBytes(16).toString('hex');
  storeNonce(address, nonce, { ttlSec: 300 });
  res.type('text/plain').send(nonce);
});

POST /api/auth/verifyapplication/json

Recover the address from the signed message, validate the nonce, issue a session.

import { verifyMessage } from 'ethers';
import { parseSiweMessage } from 'thanos-connect';

app.post('/api/auth/verify', async (req, res) => {
  const { message, signature, address } = req.body;

  // Recover signer
  const recovered = verifyMessage(message, signature);
  if (recovered.toLowerCase() !== address.toLowerCase()) {
    return res.status(401).json({ error: 'signature mismatch' });
  }

  // Validate the nonce came from us + hasn't been used
  const parsed = parseSiweMessage(message);
  if (!parsed) return res.status(400).json({ error: 'malformed message' });
  if (!await consumeNonce(address, parsed.nonce)) {
    return res.status(401).json({ error: 'nonce invalid or already used' });
  }

  // Issue your session token
  const sessionToken = await issueSession(address);
  res.json({ sessionToken });
});

parseSiweMessage() and buildSiweMessage() are exported from the package — use them to keep the wire format identical on both sides.

Configuration reference

| Field | Type | Default | Notes | |-------|------|---------|-------| | appName | string | required | Shown in the SIWE message statement | | appUrl | string | window.location.origin | Canonical URL anchor | | chainId | number | 700777 (Makalu) | Chain ID for the sign-in | | statement | string | Sign in to {appName} with your Thanos Wallet. | Custom SIWE statement | | nonceEndpoint | string | null | /api/auth/nonce | Set null to generate nonce client-side | | verifyEndpoint | string | null | /api/auth/verify | Set null to skip backend round-trip | | fetch | typeof fetch | global | Override for SSR / RN / edge runtimes | | walletRdns | string | fi.thanos.wallet | Loosen for any EIP-6963 wallet | | debug | boolean | false | Log discovery + flow steps |

Errors

import { ThanosUnavailable, SignInRejected } from 'thanos-connect';

try {
  await thanos.signIn();
} catch (err) {
  if (err instanceof ThanosUnavailable) {
    // Show install CTA
  } else if (err instanceof SignInRejected) {
    // User cancelled in the wallet — silent recovery, no banner needed
  } else {
    // Network / backend / unexpected
  }
}

Multi-chain example

const thanos = new ThanosConnect({
  appName: 'COLLE AI',
  chainId: 1, // sign in on Ethereum mainnet
});

Switch chains after sign-in:

const provider = await thanos.getProvider();
await provider.request({
  method: 'wallet_switchEthereumChain',
  params: [{ chainId: '0xab169' }], // 700777
});

Per-app drop-in snippets

Literal copy-paste hooks for the 9 apps in the integration wave. Each < 15 lines. The Lithosphere ecosystem catalogue lives at https://ecosystem.litho.ai — these are the apps already wired into the Thanos Discover screen, so consistency matters across both.

Ignite DEX — https://ignite.litho.ai

import { ThanosConnectButton } from 'thanos-connect/react';

<ThanosConnectButton
  config={{ appName: 'Ignite DEX', chainId: 700777 }}
  onSignIn={({ address, sessionToken }) => {
    localStorage.setItem('ignite.session', sessionToken!);
    location.reload();
  }}
/>

EGO Exchange — URL TBD with Esha

<ThanosConnectButton
  config={{ appName: 'EGO Exchange', chainId: 700777 }}
  onSignIn={(s) => myAuthStore.setSession(s)}
/>

COLLE AI — https://colle.ai

<ThanosConnectButton
  config={{ appName: 'COLLE AI', chainId: 700777 }}
  onSignIn={(s) => router.push('/dashboard?token=' + s.sessionToken)}
/>

AGII — https://agii.app

<ThanosConnectButton
  config={{ appName: 'AGII', chainId: 700777 }}
  onSignIn={(s) => useAuthStore.getState().setSession(s)}
/>

ATUA AI — https://atua.ai

<ThanosConnectButton
  config={{ appName: 'ATUA AI', chainId: 700777 }}
  onSignIn={(s) => signInToAtua(s.address, s.sessionToken)}
/>

Imagen Network — https://imagen.network

<ThanosConnectButton
  config={{ appName: 'Imagen Network', chainId: 700777 }}
  onSignIn={(s) => attachSession(s)}
/>

Mansa AI — https://mansa.world

<ThanosConnectButton
  config={{ appName: 'Mansa AI', chainId: 700777 }}
  onSignIn={(s) => persistMansaSession(s)}
/>

Makalu Explorer — https://makalu.litho.ai

Makalu is the Lithosphere main chain — use the default chainId:

<ThanosConnectButton
  config={{ appName: 'Makalu Explorer', chainId: 700777 }}
  onSignIn={(s) => loginExplorer(s)}
/>

Kamet Explorer — https://kamet.litho.ai

Kamet is the sister chain (DNNS lives here) — use chainId 900523:

<ThanosConnectButton
  config={{ appName: 'Kamet Explorer', chainId: 900523 }}
  onSignIn={(s) => loginExplorer(s)}
/>

Bonus: ecosystem.litho.ai itself

The ecosystem directory has no wallet-connect flow today. If you wire one, the snippet is identical:

<ThanosConnectButton
  config={{ appName: 'Lithosphere Ecosystem', chainId: 700777 }}
  onSignIn={(s) => /* gate the listing dashboard */ null}
/>

SSR / Next.js

The wallet only exists in the browser. Wrap the button in a client-only boundary:

'use client';
import { ThanosConnectButton } from 'thanos-connect/react';
// ... use as normal

For Next.js app router, the component is already marked use client on import — no extra setup needed.

Pairing with WalletConnect for mobile users

If your dApp also supports mobile wallets via WalletConnect, route non-extension users through that flow and reuse the same SIWE message format. See INTEGRATE-THANOS-AUTH.md in the main repo for the WC integration sample.

License

MIT. Use everywhere.

Source / issues

https://github.com/imasssad/Thanos-Wallet/tree/main/packages/connect