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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vantezzen/pow

v1.0.2

Published

A simple challenge-response proof-of-work implementation for web apps

Downloads

4

Readme

pow - A simple Proof-of-Work implementation for web apps

This package provides a simple Proof-of-Work implementation for web apps. It is designed to abstract away the complexity of Proof-of-Work and provide a simple interface to use it in your web app to verify users and prevent spam.

The library is unopinionated about what Frontend and Backend frameworks you use and how you transfer data between them.

Installation

npm install @vantezzen/pow

Example

A fully client-side demo can be accessed at https://vantezzen.github.io/pow/.

The example implementation can be found in the demo folder.

Usage

This library contains two main classes: PowServer should run in a secure environment (e.g. your NodeJS backend) and PowClient should run in your client (e.g. a React frontend).

Your PowServer contains a secret key that is used to generate and verify challenges. The PowClient can then take a challenge generated by the server to solve.

Both the server and client are written to be environment-agnositic and can be used inside NodeJS and the browser.

Server

import { PowServer, PowCrypto } from "@vantezzen/pow";

// You can use any secret key you want or use `PowCrypto` to generate a random key instead
const powCrypto = new PowCrypto();
const secret = await powCrypto.generateSecret();

// Please note that the secret key must be the same between generating a challenge and verifying it.
// If you use multiple servers, you should use a shared secret key for all of them.

// Create a new server instance
const server = new PowServer(secret);

// Generate a challenge. This is just an encrypted string that you can send to the client.
const challenge = await server.generateChallenge();

// You should now send the challenge string over to the client using your preferred method.
// In this example, the challenge is sent using socket.io
socket.emit("challenge", challenge, async (nonce) => {
  // We now received a nonce from the client and can verify it.
  const result = await powServer.verifyProofOfWork(challenge, nonce);

  // The result is a `PowVerifyResult` object that contains the result of the verification.
  if (result.isValid) {
    // The nonce is valid and the user can be verified
  } else {
    // The nonce is invalid and the user should be rejected
    console.log("Error", result.error);
  }
});

Client

import { PowClient } from "@vantezzen/pow";

// Create a new client instance
const client = new PowClient();

// Again, the challenge can be transferred to the client using any method you want.
// In this example, the challenge is received using socket.io
socket.on("challenge", async (challenge, callback) => {
  // We now received a challenge from the server and can solve it.
  try {
    const nonce = await powClient.solveChallenge(challenge);

    // We now have a nonce that we can send back to the server.
    // In this example, the nonce is sent using socket.io
    callback(nonce);
  } catch (error) {
    // The challenge could not be solved. This is most likely because the proof of work took to long and timed out.
    console.log("Error", error);
  }
});

Changing the difficulty

By default, the proof of work difficulty is set to 4. This means that the hash of the challenge and nonce must start with 0000 to be considered valid. On average, it takes 1 second to solve a challenge with difficulty 4 on a modern computer.

If you want to increase the difficulty, you can do so by passing a higher difficulty to the PowServer and PowClient constructor. You should always consider updating the validity option of the PowServer as well as the timeout option of the PowClient to prevent the challenge from being discarded if the client takes too long. The difficulty needs to be the same on the server and client.

const server = new PowServer(secret, {
  difficulty: 6,
  validity: 30000,
});

const client = new PowClient({
  difficulty: 6,
  timeout: 30000,
});

API

PowServer

constructor(secret: string, options?: PowServerOptions)

Creates a new PowServer instance.

  • secret - The secret key that is used to generate and verify challenges. This should be a random string of at least 32 characters.
  • options - Optional options for the server.
    • difficulty - The difficulty of the proof of work (This is the number of leading zeros that the hash of the challenge and nonce must have). Defaults to 4.
    • validity - The validity of the proof of work challenge in milliseconds. Defaults to 15000 (15 seconds). If the client takes longer than this to solve the challenge, the challenge will be considered invalid to prevent replay attacks.

generateChallenge(): Promise<string>

Generates a new challenge.

verifyProofOfWork(challenge: string, nonce: string): Promise<PowVerifyResult>

Verifies a proof of work challenge.

  • challenge - The challenge that was generated by the server.
  • nonce - The nonce that was generated by the client.

PowClient

constructor(options?: PowClientOptions)

Creates a new PowClient instance.

  • options - Optional options for the client.
    • difficulty - The difficulty of the proof of work (This is the number of leading zeros that the hash of the challenge and nonce must have). Defaults to 4.
    • timeout - Time in milliseconds after which the proof of work should be stopped. Defaults to 10000 (10 seconds). If the client takes longer than this to solve the challenge, the challenge will be considered too difficult.

solveChallenge(challenge: string): Promise<string>

Solves a challenge.

  • challenge - The challenge that was generated by the server.

PowCrypto

generateSecret(): Promise<string>

Generates a new random secret key.

PowVerifyResult

isValid: boolean

Whether the proof of work is valid.

error?: string

The error message if the proof of work is invalid.

License

MIT