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

@attestto/login

v0.1.1

Published

One-line DID login for any website. Web Component with OAuth bridge — Google, Microsoft, or any DID wallet. No framework required.

Readme

@attestto/login

npm version license

Works with: Vanilla JS Works with: React Works with: Vue Works with: Svelte Works with: Angular Works with: WordPress No framework required

One-line DID login for any website. Drop a Web Component, get passwordless authentication backed by cryptographic identity. Falls back to Google/Microsoft OAuth and converts tokens into portable Verifiable Credentials.

@attestto/login gives your users decentralized identity login with zero friction. No passwords, no OAuth vendor lock-in, no monthly subscription. One HTML element, works in any page. Part of the Attestto identity infrastructure.

Documentation · Playground · Full API

Quick start

Option 1: Copy-paste (any website, WordPress, Joomla, static HTML)

<script type="module" src="https://unpkg.com/@attestto/login"></script>
<attestto-login></attestto-login>

That's it. Users see a "Login with DID" button. If they have a DID wallet extension installed, they authenticate with cryptographic proof. No passwords.

Option 2: npm (React, Vue, Svelte, Angular)

npm install @attestto/login
import '@attestto/login'
// Now use <attestto-login> in your templates

With OAuth fallback

Users without a DID wallet can still log in. Their OAuth token gets converted into a Verifiable Credential — next time, they use the credential directly.

<attestto-login
  providers="google,microsoft"
  issuer-endpoint="/api/auth/issue-vc"
  trusted-issuers="did:web:yoursite.com"
></attestto-login>

First login uses Google. Every login after uses their DID wallet. Google is cut out of the loop.

How it works

User clicks "Login with DID"
  → pickWallet() shows wallet selector
  → Wallet presents Verifiable Credential (CHAPI)
  → verifyPresentation() validates the trust chain
  → login-success event fires with user's DID

User clicks "Continue with Google" (fallback)
  → OAuth redirect to your backend
  → Backend verifies Google token
  → Backend issues a Verifiable Credential
  → VC stored in user's wallet
  → Next login uses DID path directly

Attributes

| Attribute | Type | Default | Description | |---|---|---|---| | providers | string | "" | Comma-separated OAuth providers: "google,microsoft" | | issuer-endpoint | string | "" | Backend URL for OAuth → VC exchange | | trusted-issuers | string | "" | Comma-separated trusted issuer DIDs | | resolver-url | string | "" | DID resolver URL for VP verification | | did-label | string | "Login with DID" | Primary button label | | theme | "light" | "dark" | "light" | Color scheme | | compact | boolean | false | Button-only mode (no card wrapper) |

Events

All events are composed — they cross Shadow DOM boundaries.

| Event | Detail | When | |---|---|---| | login-success | LoginResult | Authentication succeeded | | login-error | { error, method } | Authentication failed or cancelled | | oauth-start | { provider } | User clicked an OAuth button | | wallets-discovered | { count, wallets } | Wallet discovery completed |

const login = document.querySelector('attestto-login')

login.addEventListener('login-success', (e) => {
  console.log('Authenticated:', e.detail.did)
  console.log('Method:', e.detail.method) // 'did' or 'google'

  // Create your session
  fetch('/api/session', {
    method: 'POST',
    body: JSON.stringify({ did: e.detail.did })
  })
})

CSS theming

Override CSS custom properties to match your brand:

attestto-login {
  --attestto-primary: #594FD3;
  --attestto-primary-hover: #7B72ED;
  --attestto-text: #1a1a2e;
  --attestto-bg: #ffffff;
  --attestto-bg-card: #f8fafc;
  --attestto-border: #e2e8f0;
  --attestto-font: system-ui, sans-serif;
}

Style internal elements via CSS parts:

attestto-login::part(did-button) { border-radius: 20px; }
attestto-login::part(oauth-button) { font-size: 0.85rem; }
attestto-login::part(divider) { margin: 1.5rem 0; }

Advanced: use the wallet adapter directly

@attestto/login re-exports the full @attestto/id-wallet-adapter API for advanced use cases:

import {
  discoverWallets,
  pickWallet,
  verifyPresentation,
  requestSignature,
} from '@attestto/login'

// Build your own login UI with full control
const wallets = await discoverWallets()
const wallet = await pickWallet()
const result = await verifyPresentation(vp, wallet, { resolverUrl, trustedIssuers })

Backend: OAuth → VC exchange

Your backend handles the OAuth callback and issues a Verifiable Credential. Example with Express:

app.get('/api/auth/issue-vc', async (req, res) => {
  const { provider, redirect } = req.query

  // 1. Run OAuth flow with the provider
  const oauthResult = await runOAuth(provider)

  // 2. Issue a VC proving the user authenticated
  const vc = await issuer.issue({
    type: 'AuthenticationCredential',
    subjectDid: oauthResult.did || generateDid(),
    claims: {
      provider,
      email: oauthResult.email,
      verifiedAt: new Date().toISOString(),
    },
  })

  // 3. Redirect back with the VC for wallet storage
  res.redirect(`${redirect}#vc=${encodeCredential(vc)}`)
})

Ecosystem

| Package | Role | |---|---| | @attestto/id-wallet-adapter | Wallet discovery protocol (re-exported) | | @attestto-com/vc-sdk | Issue VCs server-side (OAuth bridge) | | @attestto/verify | Document verification + signing |

Privacy

No tracking, no analytics, no telemetry. The component runs entirely client-side. OAuth tokens are exchanged via your own backend — Attestto never sees them. DID login never touches any server. See the Attestto privacy model.

License

Apache 2.0 — see LICENSE


One line of HTML. Passwordless login. No vendor lock-in.