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

c2pa-rs-javascript-library

v0.1.4

Published

TypeScript bindings for C2PA signing and verification powered by Rust and WebAssembly

Readme

c2pa-rs-javascript-library

TypeScript/JavaScript bindings for C2PA (Coalition for Content Provenance and Authenticity) signing and verification, powered by Rust compiled to WebAssembly.

What It Does

  • Sign images, PDFs, SVGs, and text formats (JSONC, XML, Markdown) with C2PA manifests
  • Verify C2PA manifests and extract provenance data
  • CAWG identity assertions — prepare, sign, and verify named-actor identity credentials
  • Structured text — first-class support for source code and document formats

Works in any bundler that supports WASM (Vite, webpack 5, Rollup, esbuild).

Supported Formats

| MIME type | Format | |---|---| | image/jpeg | JPEG | | image/png | PNG | | image/svg+xml | SVG | | image/x-adobe-dng | DNG | | application/pdf | PDF | | jsonc | JSONC / JSON with comments | | xml | XML | | md | Markdown |

Installation

npm install c2pa-rs-javascript-library

Quick Start

Verify an asset

import { verifyAsset } from 'c2pa-rs-javascript-library';

const bytes = new Uint8Array(await file.arrayBuffer());

const result = await verifyAsset('image/jpeg', bytes, []);
console.log(result.state);       // true if trusted
console.log(result.manifests);   // array of recognized manifests

Sign an asset

import { signAsset } from 'c2pa-rs-javascript-library';

const signcert = new Uint8Array(/* PEM bytes */);
const pkey     = new Uint8Array(/* private key bytes */);

const result = await signAsset(
  'image/jpeg',
  assetBytes,
  {
    claim_generator_info: [{ name: 'my-app' }],
    title: 'photo.jpg',
    assertions: [
      {
        label: 'c2pa.actions',
        data: { actions: [{ action: 'c2pa.created' }] },
      },
    ],
  },
  signcert,
  pkey,
  'es256'
);

// result.signedAsset — Uint8Array of the signed file
// result.manifest   — Uint8Array of the raw JUMBF manifest

CAWG identity assertions

import {
  prepareIdentityAssertion,
  signIdentityAssertionPayloadX509,
  finalizeIdentityAssertion,
} from 'c2pa-rs-javascript-library';

// Step 1 — capture the signer payload
const prepared = await prepareIdentityAssertion(
  'image/png', assetBytes, manifest, signcert, pkey, 'es256',
  { sigType: 'cawg.x509.cose', reserveSize: 4096, roles: ['cawg.creator'] }
);

// Step 2 — sign with an external key / HSM
const signature = signIdentityAssertionPayloadX509(
  prepared.signerPayloadCbor, identitySigncert, identityPkey, 'es256'
);

// Step 3 — embed the real signature
const result = await finalizeIdentityAssertion(prepared, signature);

For a single-pass X.509 flow use signAssetWithX509Identity(...).

ICA (Identity Claims Aggregation) signing

import {
  computeIcaIssuerDid,
  signAssetWithIcaIdentity,
} from 'c2pa-rs-javascript-library';

// Derive the did:jwk DID for the issuer's Ed25519 key (32 raw bytes).
const issuerDid = computeIcaIssuerDid(issuerPrivateKeyBytes);

const result = await signAssetWithIcaIdentity(
  'image/png',
  assetBytes,
  manifest,
  signcert,
  pkey,
  'es256',
  issuerDid,
  issuerPrivateKeyBytes,  // 32-byte Ed25519 seed
  [
    {
      type: 'cawg.social_media',
      username: 'myhandle',
      uri: 'https://social.example.com/myhandle',
      verifiedAt: '2024-01-01T00:00:00Z',
      provider: { id: 'https://social.example.com', name: 'Example Social' },
    },
  ],
  { sigType: 'cawg.identity_claims_aggregation', reserveSize: 8192, roles: ['cawg.creator'] }
);

Structured text (JSONC / XML / Markdown)

import { signJsoncAsset, verifyJsoncAsset } from 'c2pa-rs-javascript-library';

const signed = await signJsoncAsset(source, manifest, signcert, pkey, 'es256');
const result = await verifyJsoncAsset(signed.signedAsset, []);

Equivalent signXmlAsset, verifyXmlAsset, signMarkdownAsset, verifyMarkdownAsset helpers are also exported.

API Reference

See src/index.ts for full TypeScript signatures.

Core

| Function | Description | |---|---| | signAsset(format, asset, manifest, cert, key, alg, tsaUrl?) | Sign any supported format | | verifyAsset(format, asset, trustedCerts) | Verify and parse manifests | | cleanAsset(format, asset) | Remove any embedded C2PA manifest |

Identity assertions (CAWG)

| Function | Description | |---|---| | prepareIdentityAssertion(...) | Capture signer payload for external signing | | finalizeIdentityAssertion(prepared, signature) | Embed externally produced signature | | signAssetWithX509Identity(...) | Single-pass X.509 identity signing | | signIdentityAssertionPayloadX509(cbor, cert, key, alg) | Sign a CBOR payload with X.509 | | verifyIdentityAssertions(format, asset, trustedCerts) | Verify CAWG identity assertions | | computeIcaIssuerDid(privateKey) | Derive did:jwk from a 32-byte Ed25519 seed | | signAssetWithIcaIdentity(...) | Single-pass ICA (W3C VC) identity signing |

CAWG metadata

| Function | Description | |---|---| | addCawgMetadataAssertion(manifest, metadata) | Add a cawg.metadata assertion | | signAssetWithCawgMetadata(...) | Sign and attach CAWG metadata in one step |

Structured text helpers

Each format has sign*, verify*, and clean* variants:

  • signJsoncAsset / verifyJsoncAsset / cleanJsoncAsset
  • signXmlAsset / verifyXmlAsset / cleanXmlAsset
  • signMarkdownAsset / verifyMarkdownAsset / cleanMarkdownAsset

Utilities

| Function | Description | |---|---| | parseJsonc(asset) | Parse JSONC (JSON with comments) to a plain object |

Manifest definition

The manifest object passed to signing functions follows the C2PA ManifestDefinition schema:

{
  claim_generator_info: [{ name: string; version?: string }];
  title?: string;
  assertions?: { label: string; data: unknown }[];
  instance_id?: string;    // auto-generated if omitted
  label?: string;          // auto-generated if omitted
  assertion_salt?: number[]; // optional fixed salt for deterministic assertion hashes
}

License

MIT OR Apache-2.0