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

@cmdoss/cryptoguard-sdk

v1.0.0

Published

CryptoGuard SDK for Chrome extensions and Node.js servers - SLSA Level 3 binary transparency verification

Readme

CryptoGuard SDK

Binary transparency verification SDK for Chrome extensions and Node.js servers

npm version TypeScript License: MIT

Overview

CryptoGuard SDK provides cryptographic verification of file integrity by comparing SHA-256 hashes of web resources against blockchain-stored references. The SDK ensures that files served to users match their registered versions, protecting against tampering, unauthorized modifications, and supply chain attacks.

Architecture

The SDK supports two distinct runtime environments:

Extension Platform

Designed for Chrome browser extensions with automatic and manual verification capabilities:

  • Automatic Verification: Intercepts HTTPS requests via chrome.webRequest API and verifies resources in real-time
  • Manual Verification: Provides API for on-demand verification of specific URLs
  • Event System: Emits verification events for UI updates and logging

Server Platform

Designed for Node.js backend services with manual verification:

  • Manual Verification Only: Accepts pre-computed hashes for verification
  • Event System: Same event-driven architecture as extension platform
  • CI/CD Integration: Suitable for build pipelines and deployment validation

Both platforms share the same verification logic and event system, differing only in how resources are captured and hashed.


Installation

npm install crptg

Requirements:

  • Node.js ≥18.0.0
  • TypeScript ≥5.0.0 (recommended)
  • Chrome ≥88 (for extensions only)

Integration Guide

Extension Platform

1. Install the Package

npm install crptg

2. Update manifest.json

Add required permissions to your extension's manifest.json:

{
  "manifest_version": 3,
  "permissions": [
    "webRequest",
    "tabs",
    "storage"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

Required Permissions:

  • webRequest: Intercept HTTP requests for automatic verification
  • tabs: Access tab URLs for same-origin validation
  • storage: Cache verification results (optional but recommended)
  • host_permissions: ["<all_urls>"]: Verify resources from any domain

3. Initialize in Background Script

import { CryptoGuardSDKFactory, VerificationEvent } from 'crptg';

// Create scanner instance
const scanner = CryptoGuardSDKFactory.create({
  platform: 'extension'
});

// Initialize SDK
await scanner.initialize();

// Register event listeners
scanner.on(VerificationEvent.VERIFICATION_COMPLETED, (data) => {
  console.log('Verification completed:', data.result.status);
  // Update badge, notify user, etc.
});

scanner.on(VerificationEvent.VERIFICATION_FAILED, (data) => {
  console.error('Verification failed:', data.result.url);
  // Alert user about compromised resource
});

// Automatic verification happens in background via webRequest
// Manual verification also available:
const result = await scanner.verifyResource('https://example.wal.app/app.js');

Server Platform

1. Install the Package

npm install crptg

2. Initialize in Application

import { CryptoGuardSDKFactory } from 'crptg';
import { createHash } from 'crypto';
import * as fs from 'fs';

// Create scanner instance
const scanner = CryptoGuardSDKFactory.create({
  platform: 'server'
});

// Initialize SDK
await scanner.initialize();

// Compute hash from file
const fileContent = fs.readFileSync('./dist/app.js');
const hash = createHash('sha256')
  .update(fileContent)
  .digest('hex');

// Verify resource
const result = await scanner.verifyResource({
  url: 'https://example.com/app.js',
  hash: hash
});

if (result.status === 'VERIFIED') {
  console.log('✅ File integrity verified');
} else if (result.status === 'FAILED') {
  console.error('❌ Hash mismatch detected');
}

API Reference

Factory

CryptoGuardSDKFactory.create(config)

Creates a platform-specific scanner instance.

Parameters:

  • config.platform: 'extension' | 'server' - Target runtime environment

Returns: CryptoGuardScanner

Example:

const scanner = CryptoGuardSDKFactory.create({ platform: 'extension' });

Scanner Methods

scanner.initialize()

Initializes the SDK and prepares for verification operations. Must be called before any verification.

Returns: Promise<void>

Example:

await scanner.initialize();

scanner.verifyResource(params)

Verifies a resource's integrity against blockchain registry.

Extension Platform:

await scanner.verifyResource(url: string): Promise<SiteVerificationResult>
  • SDK fetches resource and computes hash automatically

Server Platform:

await scanner.verifyResource(params: { url: string; hash: string }): Promise<SiteVerificationResult>
  • Requires pre-computed SHA-256 hash (64 hex characters)

Returns: SiteVerificationResult

Example:

// Extension
const result = await scanner.verifyResource('https://example.wal.app/app.js');

// Server
const result = await scanner.verifyResource({
  url: 'https://example.com/app.js',
  hash: 'abc123...'
});

scanner.on(event, listener)

Registers an event listener for verification lifecycle events.

Parameters:

  • event: VerificationEvent - Event type to listen for
  • listener: Function - Callback function invoked when event occurs

Returns: void

Example:

scanner.on(VerificationEvent.VERIFICATION_COMPLETED, (data) => {
  console.log('Status:', data.result.status);
});

scanner.off(event, listener)

Removes a previously registered event listener.

Parameters:

  • event: VerificationEvent - Event type
  • listener: Function - The specific listener to remove

Returns: void


scanner.getStatistics()

Returns runtime statistics about the scanner instance.

Returns: Object containing:

  • initialized: boolean - Initialization status
  • platform: 'extension' | 'server' - Platform type
  • captureStrategy: string - Active capture strategy name
  • totalListeners: number - Total registered event listeners
  • registeredEvents: string[] - Active event types

scanner.destroy()

Cleans up resources and removes all event listeners. Scanner cannot be reused after destruction.

Returns: Promise<void>


Events Reference

The SDK emits events throughout the verification lifecycle. All events follow the same pattern:

scanner.on(VerificationEvent.EVENT_NAME, (data) => {
  // Handle event
});

Event Types

VERIFICATION_STARTED

Emitted when verification begins for a resource.

Data:

{
  url: string;           // URL being verified
  requestId: string;     // Unique verification ID
  timestamp: number;     // Start timestamp
}

Use Case: Display loading indicator, log verification start


REGISTRY_FOUND

Emitted when domain is found in blockchain registry.

Data:

{
  domain: string;              // Domain name
  registryType: RegistryType;  // 'walrus' | 'cryptoguard'
  metadata: RegistryMetadata;  // Registry metadata
  requestId: string;
}

Use Case: Confirm domain is registered, display registry type


RESOURCE_COMPLETED

Emitted when individual resource verification completes (per-file).

Data:

{
  url: string;
  status: VerificationStatus;  // 'VERIFIED' | 'FAILED' | 'IGNORED' | 'ERROR'
  computedHash?: string;       // Actual hash
  expectedHash?: string;       // Registry hash
  requestId: string;
}

Use Case: Track progress for multi-resource sites, per-file logging


VERIFICATION_COMPLETED

Emitted when overall verification succeeds (all resources verified).

Data:

{
  result: SiteVerificationResult;
  requestId: string;
}

Use Case: Display success badge, log successful verification, update UI


VERIFICATION_FAILED

Emitted when overall verification fails (hash mismatch detected).

Data:

{
  result: SiteVerificationResult;
  reason: string;        // Failure reason
  requestId: string;
}

Use Case: Alert user, block resource, log security incident


ERROR

Emitted when technical error occurs during verification.

Data:

{
  error: VerificationError;
  url: string;
  requestId: string;
}

Use Case: Error logging, retry logic, user notification


Type Definitions

SiteVerificationResult

Complete verification result for a resource.

interface SiteVerificationResult {
  domain: string;                             // Domain name
  url: string;                                // Verified URL
  status: VerificationStatus;                 // Overall status
  registryType?: RegistryType;                // Registry used
  resources: ResourceVerificationResult[];    // Per-resource results
  processingTime: number;                     // Duration (ms)
  timestamp: number;                          // Completion time
  requestId: string;                          // Unique ID
  error?: string;                             // Error message if failed
}

VerificationStatus

Possible verification outcomes.

enum VerificationStatus {
  VERIFIED = 'VERIFIED',           // Hash matches registry
  FAILED = 'FAILED',               // Hash mismatch detected
  MISSING_STATIC = 'MISSING_STATIC', // Deployment mismatch
  ERROR = 'ERROR',                 // Technical error
  IGNORED = 'IGNORED',             // Not registered
  PARTIAL = 'PARTIAL'              // Some resources failed
}

Status Meanings:

  • VERIFIED: Resource hash matches blockchain registry ✅
  • FAILED: Hash mismatch - potential tampering ⚠️
  • MISSING_STATIC: File registered but not deployed (or vice versa)
  • ERROR: Network error, RPC failure, or other technical issue
  • IGNORED: Resource not registered for verification
  • PARTIAL: Multi-resource site with mixed results (some passed, some failed)

RegistryType

Supported blockchain registries.

enum RegistryType {
  WALRUS = 'walrus',           // Walrus sites (*.wal.app) on mainnet
  CRYPTOGUARD = 'cryptoguard'  // CryptoGuard registry on testnet
}

VerificationEvent

Available event types for registration.

enum VerificationEvent {
  VERIFICATION_STARTED = 'VERIFICATION_STARTED',
  REGISTRY_FOUND = 'REGISTRY_FOUND',
  RESOURCE_COMPLETED = 'RESOURCE_COMPLETED',
  VERIFICATION_COMPLETED = 'VERIFICATION_COMPLETED',
  VERIFICATION_FAILED = 'VERIFICATION_FAILED',
  ERROR = 'ERROR'
}

Extension Permissions Explained

When using the extension platform, your manifest.json must include these permissions:

{
  "permissions": [
    "webRequest",
    "tabs",
    "storage"
  ],
  "host_permissions": ["<all_urls>"]
}

Why Each Permission is Required

webRequest Enables automatic verification by intercepting HTTP requests before resources are loaded. The SDK uses chrome.webRequest.onBeforeRequest to capture URLs and trigger verification in the background without blocking page load.

tabs Provides access to tab URLs for same-origin policy validation. The SDK verifies that resources belong to the same domain as the requesting tab, preventing cross-origin verification attempts and maintaining security boundaries.

storage Allows caching of verification results to improve performance. While optional, it significantly reduces repeated blockchain queries for frequently accessed resources.

host_permissions: ["<all_urls>"] Grants permission to verify resources from any HTTPS domain. Required because the SDK supports both *.wal.app domains and any domain registered in the CryptoGuard registry.

Security Note

These permissions are necessary for the SDK to function correctly. The SDK does not:

  • Modify HTTP requests or responses
  • Access or store sensitive user data
  • Track browsing history
  • Send data to third-party servers

All verification occurs locally by comparing hashes against public blockchain registries.


Network Configuration

The SDK automatically selects the appropriate Sui blockchain network based on domain pattern:

| Domain Pattern | Registry | Sui Network | |----------------|----------|-------------| | *.wal.app | Walrus | Mainnet | | All others | CryptoGuard | Testnet |

Network selection is hardcoded for security and requires no user configuration.


Example: Complete Extension Integration

// background.js
import { CryptoGuardSDKFactory, VerificationEvent, VerificationStatus } from 'crptg';

class VerificationExtension {
  constructor() {
    this.scanner = CryptoGuardSDKFactory.create({ platform: 'extension' });
  }

  async initialize() {
    await this.scanner.initialize();
    this.registerEventListeners();
  }

  registerEventListeners() {
    // Track verification start
    this.scanner.on(VerificationEvent.VERIFICATION_STARTED, ({ url }) => {
      this.updateBadge('...', 'blue'); // Loading state
    });

    // Handle successful verification
    this.scanner.on(VerificationEvent.VERIFICATION_COMPLETED, ({ result }) => {
      if (result.status === VerificationStatus.VERIFIED) {
        this.updateBadge('✓', 'green');
        this.notifyUser('Resource verified successfully');
      }
    });

    // Handle verification failure
    this.scanner.on(VerificationEvent.VERIFICATION_FAILED, ({ result }) => {
      this.updateBadge('✗', 'red');
      this.notifyUser('⚠️ Security Alert: Resource failed verification', 'error');
      this.logSecurityIncident(result);
    });

    // Handle errors
    this.scanner.on(VerificationEvent.ERROR, ({ error, url }) => {
      console.error('Verification error:', error, url);
      this.updateBadge('!', 'orange');
    });
  }

  updateBadge(text, color) {
    chrome.action.setBadgeText({ text });
    chrome.action.setBadgeBackgroundColor({ color });
  }

  notifyUser(message, type = 'info') {
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icon.png',
      title: 'CryptoGuard',
      message
    });
  }

  logSecurityIncident(result) {
    // Log to analytics, send alert, etc.
    console.error('Security incident:', {
      url: result.url,
      expected: result.resources[0]?.expectedHash,
      actual: result.resources[0]?.computedHash,
      timestamp: result.timestamp
    });
  }
}

// Initialize extension
const extension = new VerificationExtension();
extension.initialize().catch(console.error);

Example: Server CI/CD Integration

// verify-build.js
import { CryptoGuardSDKFactory } from 'crptg';
import { createHash } from 'crypto';
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';

async function verifyBuildArtifacts() {
  const scanner = CryptoGuardSDKFactory.create({ platform: 'server' });
  await scanner.initialize();

  const distDir = './dist';
  const baseUrl = 'https://cdn.example.com';

  const files = readdirSync(distDir);
  const results = [];

  for (const file of files) {
    const filePath = join(distDir, file);
    const fileContent = readFileSync(filePath);
    const hash = createHash('sha256').update(fileContent).digest('hex');

    const result = await scanner.verifyResource({
      url: `${baseUrl}/${file}`,
      hash
    });

    results.push({ file, status: result.status });

    if (result.status !== 'VERIFIED') {
      console.error(`❌ Verification failed: ${file}`);
      console.error(`   Expected: ${result.resources[0]?.expectedHash}`);
      console.error(`   Actual:   ${result.resources[0]?.computedHash}`);
    } else {
      console.log(`✅ Verified: ${file}`);
    }
  }

  // Exit with error if any verification failed
  const failedCount = results.filter(r => r.status === 'FAILED').length;
  if (failedCount > 0) {
    console.error(`\n❌ ${failedCount} file(s) failed verification`);
    process.exit(1);
  }

  console.log(`\n✅ All ${results.length} file(s) verified successfully`);
  await scanner.destroy();
}

verifyBuildArtifacts().catch(error => {
  console.error('Build verification error:', error);
  process.exit(1);
});

Security Considerations

Hash Computation

The SDK uses SHA-256 for cryptographic hash computation. For server platform, ensure hashes are computed correctly:

// ✅ Correct - Use raw bytes
const hash = createHash('sha256')
  .update(fileContent)  // Buffer or Uint8Array
  .digest('hex');

// ❌ Incorrect - Don't base64 encode first
const wrongHash = createHash('sha256')
  .update(fileContent.toString('base64'))
  .digest('hex');

Registry Trust

The SDK retrieves expected hashes from immutable blockchain registries:

  • Walrus Registry: Public Sui mainnet - production-grade security
  • CryptoGuard Registry: Sui testnet - suitable for testing and development

Users should understand which registry their domains use and the security implications of each network.

Same-Origin Validation

Extension platform enforces same-origin policy: resources are only verified if they belong to the same domain as the requesting tab. This prevents malicious sites from triggering verification of unrelated domains.


License

MIT License - See LICENSE file for details.


Links

  • npm Package: https://www.npmjs.com/package/crptg
  • Repository: https://github.com/CommandOSSLabs/binary-transparency
  • Issues: https://github.com/CommandOSSLabs/binary-transparency/issues

Built by the CryptoGuard Team