Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

bitcoin-auth

b-open-io463MIT0.0.4TypeScript support: included

A TypeScript/JavaScript client library for authenticating with REST APIs using Bitcoin keys.

bitcoin, signature, faucet, bsm, auth, brc-77, bsv, bch, btc

readme

Bitcoin Auth

The "Bitcoin Auth" library simplifies authenticating REST APIs using Bitcoin keys by generating and verifying cryptographic signatures in an X-Auth-Token header.

Installation

Install with Bun:

bun add bitcoin-auth

Generating an Auth Token

Import and generate the token:

import { getAuthToken } from 'bitcoin-auth';

// Get a token
const token = getAuthToken({ privateKeyWif, requestPath });

// Include it in your API request
const response = await fetch("https://somedomain.com" + requestPath, {
  headers: { 'X-Auth-Token': token }
});

When your request includes a body:

const token = getAuthToken({ privateKeyWif, requestPath, body });

Using Bitcoin Signed Message and specifying bodyEncoding:

const token = getAuthToken({
  privateKeyWif,
  requestPath,
  scheme: 'bsm',
  body: "eyJrZXkiOiJ2YWx1ZSJ9",
  bodyEncoding: 'base64'
});

Features

  • Auth Token Generation & Verification: Simple functions for handling tokens.
  • Dual Cryptographic Schemes: Supports legacy 'bsm' and modern 'brc77' (recommended, BRC-77).
  • Minimal Dependencies: Only requires the peer dependency @bsv/sdk.

Usage Details

Tokens include:

  • Request path (with query parameters)
  • ISO8601 timestamp
  • SHA256 hash of the body (if present)
  • Signing scheme ('bsm' or 'brc77')

Token format:

pubkey|scheme|timestamp|requestPath|signature

Cryptographic schemes:

  • 'brc77': Default and recommended, uses SignedMessage.sign() from BSV SDK.
  • 'bsm': Legacy Bitcoin Signed Message (BSM.sign() from BSV SDK).

Example Token Generation

import { getAuthToken, parseAuthToken, verifyAuthToken, AuthToken } from 'bitcoin-auth';
import { PrivateKey } from "@bsv/sdk";

const privateKeyWuf = PrivateKey.fromRandom().toWif();
const requestPath = "/some/api/path?param1=value1";
const body = JSON.stringify(["hello", "world"]);

// body present, default (brc77) signing scheme, default body encoding (utf8)
const token = getAuthToken({ privateKeyWif, requestPath, body });

// no body, bsm signing scheme
const token = getAuthToken({ privateKeyWif, requestPath, scheme: 'bsm' });

Parsing & Verification

Parsing a token:

const parsedToken: AuthToken | null = parseAuthToken(tokenWithBody);
if (!parsedToken) {
  console.error("Failed to parse bitcoin-auth token")
}
const { scheme, timestamp, requestPath, signature } = parsedToken;

Verifying tokens:

const authPayload: AuthPayload = {
  requestPath,
  timestamp: new Date().toISOString(),
  body
};

const isValid = verifyAuthToken(tokenWithBody, authPayload);

const payloadNoBody: AuthPayload = {
  requestPath,
  timestamp: new Date().toISOString()
};

const isValidNoBody = verifyAuthToken(tokenNoBodyBsm, payloadNoBody);

Security Note: Always securely handle privateKeyWif.

Types and Interfaces

Core authentication types:

  • AuthConfig: { }
  • AuthToken: { pubkey, scheme, timestamp, requestPath, signature }
  • AuthPayload: Data required for signing/verification:
export interface AuthPayload {
  requestPath: string;
  timestamp: string; // ISO8601 format
  body?: string;
}

Example payload construction:

const payloadWithBody: AuthPayload = {
  requestPath: '/api/items',
  timestamp: new Date().toISOString(),
  body: JSON.stringify({ name: "gadget", price: 9.99 })
};

const payload: AuthPayload = {
  requestPath: '/api/items/123',
  timestamp: new Date().toISOString()
};

API Reference

getAuthToken(config)

Generates a token using an AuthConfig object:

  • config.privateKeyWif: Private key in WIF format (required)
  • config.requestPath: Full URL path (required)
  • config.body?: Optional request body string
  • config.scheme?: Signing scheme ('brc77' or 'bsm', default 'brc77')
  • config.bodyEncoding?: Encoding for the body ('utf8', 'hex', or 'base64', default 'utf8')

verifyAuthToken(token, target, timePad?, bodyEncoding?)

Verifies a token:

  • token: Token string
  • target: Expected AuthPayload
  • timePad: Allowed time skew in minutes (default 5)
  • bodyEncoding: Encoding type (default 'utf8')

Returns true if valid, else false.

parseAuthToken(token)

Parses token into AuthToken or returns null.

Development

Use Bun to build and test:

bun run build
bun test

Other Implementations

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.0.4] - YYYY-MM-DD

Added

  • Added test/brc77-tampering.test.ts to specifically verify that the BRC-77 implementation is not vulnerable to payload tampering.
  • Added test/static-vectors.test.ts with a comprehensive suite of static test vectors for getAuthToken and verifyAuthToken, covering various scenarios for BRC-77 and BSM schemes, including timestamp validation and different tampering attempts.
  • Enhanced AuthConfig to accept an optional timestamp parameter, allowing for fixed timestamps during token generation, primarily to support stable static test vector creation.

Changed

  • Modified getAuthToken, getAuthTokenBSM, and getAuthTokenBRC77 to utilize the optional timestamp from AuthConfig if provided, defaulting to the current time otherwise.

Fixed

  • Corrected issues in test/static-vectors.test.ts related to the generation and validation of tokens with fixed timestamps, ensuring accurate testing of time-based verification logic.
  • Resolved an "Invalid checksum" error in static test vector generation by ensuring valid WIFs are used.

[0.0.3] - 2025-05-14

Added

  • Introduced bodyEncoding option in AuthConfig and related functions (getAuthToken, verifyAuthToken). This allows the request body to be treated as utf8 (default), hex, or base64 when generating the signature.

Changed

  • Updated test suite in test/auth.test.ts to reflect the new token format and to include comprehensive tests for different bodyEncoding options.

Fixed

  • Removed redundant outer Base64 encoding previously applied to the entire token. The signature within the token remains Base64 encoded as per BSM or BRC-77 requirements.
  • Removed an unused toUTF8 import from src/auth.ts.

Please replace YYYY-MM-DD with the actual release date.