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

clarity-auth

v1.0.1

Published

ClarityAuth - ZK-based authentication for Midnight blockchain

Downloads

134

Readme

ClarityAuth - ZK Session Authentication for Midnight

A zero-knowledge authentication contract for Clarity DAO on Midnight blockchain. Enables privacy-preserving session management using ZK proofs.

Features

  • Privacy-Preserving Authentication: User identity is never stored on-chain; only hashed authority identifiers are used
  • Replay Protection: Each challenge can only be used once, preventing replay attacks
  • Session Management: Create, verify, and revoke sessions with cryptographic proofs
  • Audience Binding: Sessions are bound to specific DAO/app identifiers
  • Authority Pattern: Uses Midnight's authority pattern since msg.sender is not available

Architecture

Authority Pattern

Midnight does not expose msg.sender like Ethereum. Instead, ClarityAuth uses the "authority pattern":

  1. User's public key is retrieved via a witness function (getPublicKey)
  2. The public key is hashed to create an "authority" identifier
  3. The authority hash is stored on-chain (not the raw public key)
  4. Ownership is verified by proving knowledge of the public key that hashes to the stored authority

Contract State

// Replay protection: tracks used challenge hashes
ledger usedChallenges: Map<Bytes<32>, Boolean>;

// Active sessions indexed by session public key hash
ledger sessions: Map<Bytes<32>, SessionRecord>;

// Session counter for analytics
ledger sessionCounter: Counter;

Session Record

struct SessionRecord {
  authority: Bytes<32>;    // Hash of user's publicKey (proves ownership)
  expiresAt: Uint<64>;     // Unix timestamp for session expiry
  audience: Bytes<32>;     // DAO/app identifier
  createdAt: Uint<64>;     // Creation timestamp
}

Installation

npm install

Target Midnight Stack

This repo now targets the official Midnight compatibility matrix published on April 3, 2026:

Source: Midnight compatibility matrix

Building

Compile the Compact Contract

npm run build:contract

This compiles contract/src/clarity-auth.compact to build/.

Build TypeScript

npm run build

Testing

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run with coverage
npm run test:coverage

Deployment

This repo owns the Midnight contract deployment flow. The Clarity app should only consume the deployed contract address.

Generate a Deployment Seed

npm run wallet:seed -- --network preprod

This prints a fresh MIDNIGHT_SERVER_WALLET_SEED=... value and its derived unshielded address. Fund that address before deploying.

Local Midnight Infrastructure

npm run midnight:local:up
npm run midnight:local:logs

This starts the local node, indexer, and proof server from docker-compose.midnight.yml.

Web Deploy UI

MIDNIGHT_PROOF_SERVER=http://127.0.0.1:6300 npm run deploy:web

Then open the Vite page it prints, connect mnLace, and click Deploy contract.

If deployment succeeds, the page shows the exact env line to copy into the app repo:

NEXT_PUBLIC_MIDNIGHT_AUTH_CONTRACT_ADDRESS=<deployed-address>

Notes

  • For preprod, use a running local proof server. The currently working image is the one pinned in docker-compose.midnight.yml.
  • Deployment now happens from the browser wallet, not from a CLI seed-wallet flow.
  • The app repo at /Users/justin/Desktop/code/claritydao-mvp should not own deployment anymore; it should only read the deployed address from env.

Usage

TypeScript Integration

import {
  createClarityAuthClient,
  generateChallenge,
  createSessionPkHash
} from 'clarity-auth';

// Build these from your app's connected Midnight wallet session.
const providers = {
  privateStateProvider,
  zkConfigProvider,
  proofProvider,
  publicDataProvider,
  walletProvider,
  midnightProvider,
};

const client = createClarityAuthClient({
  providers,
  contractAddress: 'abcd...contract-address-without-0x-prefix',
  wallet: {
    publicKey: walletPublicKeyBytes,
  },
});

// Generate a challenge for replay protection
const challenge = client.generateChallenge();

// Create a session public key and hash it
const sessionPk = crypto.getRandomValues(new Uint8Array(32));
const sessionPkHash = await client.createSessionHash(sessionPk);

// Define audience (DAO identifier)
const audience = await hashBytes(new TextEncoder().encode('clarity-dao'));

// Create a session (expires in 1 hour)
const expiresAt = BigInt(Math.floor(Date.now() / 1000) + 3600);

const result = await client.authorizeSession({
  challenge,
  sessionPkHash,
  expiresAt,
  audience,
});

if (result.success) {
  console.log('Session created:', result.txHash);
}

For preprod browser use, this package expects your app to provide an already connected Midnight wallet session and the corresponding providers. This package does not currently bootstrap those providers from the browser wallet on its own.

Verifying Session Ownership

// Verify the caller owns a valid session
const verified = await client.verifySessionOwnership({
  sessionPkHash,
  audience,
});

if (verified.result) {
  console.log('Session ownership verified');
}

Revoking a Session

// Only the session owner can revoke
const revoked = await client.revokeSession({ sessionPkHash });

if (revoked.success) {
  console.log('Session revoked');
}

Contract Circuits

authorize_session

Creates a new authenticated session.

Parameters:

  • challenge: Bytes<32> - Unique challenge (prevents replay)
  • sessionPkHash: Bytes<32> - Hash of session public key
  • expiresAt: Uint<64> - Unix timestamp for expiry
  • audience: Bytes<32> - DAO/app identifier

Validation:

  • Challenge must not have been used before
  • Expiry must be in the future
  • Session must not already exist

revoke_session

Revokes an existing session.

Parameters:

  • sessionPkHash: Bytes<32> - Session to revoke

Validation:

  • Session must exist
  • Caller must own the session (authority match)

is_session_valid

Checks if a session is valid.

Parameters:

  • sessionPkHash: Bytes<32> - Session to check

Returns: Boolean - True if session exists, not revoked, and not expired

verify_session_ownership

Proves the caller owns a valid session.

Parameters:

  • sessionPkHash: Bytes<32> - Session to verify
  • audience: Bytes<32> - Expected audience

Validation:

  • Session must exist and be valid
  • Caller must own the session
  • Audience must match

is_challenge_used

Checks if a challenge has been used.

Parameters:

  • challenge: Bytes<32> - Challenge to check

Returns: Boolean - True if challenge was used

session_exists

Checks if a session record exists.

Parameters:

  • sessionPkHash: Bytes<32> - Session to check

Returns: Boolean - True if session exists (may be revoked)

Witness Functions

Witnesses are implemented in TypeScript and run locally during ZK proof generation:

| Witness | Description | |---------|-------------| | getPublicKey() | Returns user's 32-byte public key from wallet | | getCurrentTime() | Returns current Unix timestamp in seconds | | computeAuthorityHash(pubKey) | Computes SHA-256 hash of public key |

Security Considerations

  1. Replay Protection: Each challenge can only be used once
  2. Authority Verification: Session ownership is cryptographically verified
  3. Session Expiry: Sessions have explicit expiry timestamps
  4. Audience Binding: Prevents cross-app session hijacking
  5. ZK Privacy: Raw public keys are never stored on-chain

Directory Structure

clarity-auth/
├── contract/
│   └── src/
│       └── clarity-auth.compact    # Compact contract
├── cli/
│   └── src/
│       ├── index.ts                # Main API
│       ├── types.ts                # TypeScript types
│       ├── witnesses.ts            # Witness implementations
│       └── deploy.ts               # Deployment logic
├── tests/
│   └── clarity-auth.test.ts        # Test suite
├── build/                          # Compiled output
├── package.json
├── tsconfig.json
├── vitest.config.ts
└── README.md

License

MIT

Contributing

Contributions are welcome. Please open an issue first to discuss proposed changes.