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

@framers/agentos-ext-anchor-providers

v1.1.0

Published

External anchor providers for AgentOS provenance — blockchain, WORM storage, and transparency log integrations

Downloads

42

Readme

@framers/agentos-ext-anchor-providers

External anchor providers for the AgentOS provenance system. Extends the built-in signed hash chain with external tamper-evidence backends — WORM storage, transparency logs, and blockchain timestamping.

Proof Levels

Each provider advertises a proof level (ascending trust):

| Level | Meaning | Provider | |-------|---------|----------| | verifiable | Local signed hash chain only | Built-in (NoneProvider) | | externally-archived | Immutable external archive with retention policy | WormSnapshotProvider | | publicly-auditable | Append-only public transparency log | RekorProvider | | publicly-timestamped | Blockchain-anchored timestamp proof | OpenTimestampsProvider, EthereumProvider, SolanaProvider |

Installation

pnpm add @framers/agentos-ext-anchor-providers

Install the peer dependency for your chosen provider:

# For WORM Snapshot (S3 Object Lock)
pnpm add @aws-sdk/client-s3

# For Rekor (Sigstore Transparency Log)
pnpm add sigstore

# For OpenTimestamps (Bitcoin)
pnpm add opentimestamps

# For Ethereum (On-Chain Anchor)
pnpm add ethers

# For Solana (On-Chain Anchor)
pnpm add @solana/web3.js

# Optional (only if using base58 secret keys)
pnpm add bs58

Quick Start

Option 1: Config-Driven (via Registry)

Register all providers once at startup, then use the core factory:

import { registerExtensionProviders } from '@framers/agentos-ext-anchor-providers';
import { createAnchorProvider } from '@framers/agentos';

// Register once at startup
registerExtensionProviders();

// Create provider from config
const provider = createAnchorProvider({
  type: 'rekor',
  options: { serverUrl: 'https://rekor.sigstore.dev' },
});

Option 2: Direct Construction

Import and instantiate providers directly:

import { RekorProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new RekorProvider({
  serverUrl: 'https://rekor.sigstore.dev',
  timeoutMs: 15000,
});

Using with AnchorManager

import { AnchorManager, profiles } from '@framers/agentos';
import { RekorProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new RekorProvider();
const config = profiles.sealedAutonomous();

const anchorManager = new AnchorManager(
  storageAdapter,
  ledger,
  keyManager,
  config,
  '', // table prefix
  provider, // external anchor provider
);

Providers

WORM Snapshot Provider (S3 Object Lock)

Archives anchor records to S3 with Object Lock retention. Provides compliance-grade immutability — objects cannot be deleted or overwritten during the retention period.

Proof level: externally-archived Peer dependency: @aws-sdk/client-s3

import { WormSnapshotProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new WormSnapshotProvider({
  bucket: 'my-provenance-bucket',    // Required: S3 bucket with Object Lock enabled
  region: 'us-east-1',               // Required: AWS region
  keyPrefix: 'provenance/anchors/',  // Default: 'provenance/anchors/'
  retentionDays: 365,                // Default: 365
  retentionMode: 'COMPLIANCE',       // 'GOVERNANCE' (default) or 'COMPLIANCE'
  timeoutMs: 30000,                  // Default: 30000
  retries: 3,                        // Default: 3
});

Rekor Provider (Sigstore Transparency Log)

Publishes anchor hashes to Sigstore Rekor, a publicly auditable append-only transparency log. Entries are permanently recorded and anyone can verify inclusion.

Proof level: publicly-auditable Peer dependency: sigstore

import { RekorProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new RekorProvider({
  serverUrl: 'https://rekor.sigstore.dev',  // Default: public Rekor instance
  timeoutMs: 30000,
  retries: 3,
});

OpenTimestamps Provider (Bitcoin)

Creates OpenTimestamps proofs anchored to the Bitcoin blockchain. Proofs are initially pending and confirm after a Bitcoin block includes the calendar commitment (typically 1-2 hours).

Proof level: publicly-timestamped Peer dependency: opentimestamps

import { OpenTimestampsProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new OpenTimestampsProvider({
  calendarUrls: [                           // Default: public OTS calendars
    'https://a.pool.opentimestamps.org',
    'https://b.pool.opentimestamps.org',
    'https://a.pool.eternitywall.com',
  ],
  timeoutMs: 30000,
  retries: 3,
});

Ethereum Provider (On-Chain Anchor)

Publishes anchor Merkle roots as calldata in Ethereum transactions. Provides cryptographic proof of existence at a specific block height.

Proof level: publicly-timestamped Peer dependency: ethers

import { EthereumProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new EthereumProvider({
  rpcUrl: 'https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY',  // Required
  signerPrivateKey: '0x...',         // Required: hex private key
  chainId: 1,                        // Default: 1 (mainnet)
  contractAddress: '0x...',          // Optional: anchor storage contract
  gasLimit: 100000,                  // Optional: gas limit override
  timeoutMs: 60000,
  retries: 3,
});

Composite Usage

Use CompositeAnchorProvider from @framers/agentos to publish to multiple backends simultaneously:

import { CompositeAnchorProvider } from '@framers/agentos';
import { RekorProvider, WormSnapshotProvider } from '@framers/agentos-ext-anchor-providers';

const provider = new CompositeAnchorProvider([
  new WormSnapshotProvider({ bucket: 'my-bucket', region: 'us-east-1' }),
  new RekorProvider(),
]);

// Publishes to both WORM and Rekor in parallel
// Proof level: publicly-auditable (highest among children)

Or via config with the composite type:

registerExtensionProviders();

const provider = createAnchorProvider({
  type: 'composite',
  targets: [
    { type: 'worm-snapshot', options: { bucket: 'my-bucket', region: 'us-east-1' } },
    { type: 'rekor' },
  ],
});

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                     @framers/agentos (core)                      │
│                                                                  │
│  AnchorManager ──→ AnchorProvider interface                      │
│       │                  ↑                                       │
│       │            ┌─────┴──────┐                                │
│       │            │NoneProvider│ (built-in, local-only)         │
│       │            └────────────┘                                │
│       │            ┌──────────────────┐                          │
│       │            │CompositeProvider │ (built-in, multi-target) │
│       │            └──────────────────┘                          │
│       │                                                          │
│  createAnchorProvider() ←─── registerAnchorProviderFactory()     │
└──────────────────────┬───────────────────────────────────────────┘
                       │ (registry pattern)
┌──────────────────────▼───────────────────────────────────────────┐
│            @framers/agentos-ext-anchor-providers           │
│                                                                  │
│  registerExtensionProviders()                                    │
│       │                                                          │
│       ├── WormSnapshotProvider  (externally-archived)            │
│       ├── RekorProvider         (publicly-auditable)             │
│       ├── OpenTimestampsProvider(publicly-timestamped)           │
│       ├── EthereumProvider      (publicly-timestamped)           │
│       └── SolanaProvider        (publicly-timestamped)           │
└──────────────────────────────────────────────────────────────────┘

Writing Custom Providers

Implement the AnchorProvider interface from @framers/agentos:

import type { AnchorProvider, AnchorRecord, AnchorProviderResult, ProofLevel } from '@framers/agentos';

export class MyCustomProvider implements AnchorProvider {
  readonly id = 'my-custom';
  readonly name = 'My Custom Provider';
  readonly proofLevel: ProofLevel = 'externally-archived';

  async publish(anchor: AnchorRecord): Promise<AnchorProviderResult> {
    try {
      // Your publishing logic here
      const ref = await publishToMyBackend(anchor);
      return { providerId: this.id, success: true, externalRef: ref };
    } catch (e) {
      return { providerId: this.id, success: false, error: String(e) };
    }
  }

  async verify(anchor: AnchorRecord): Promise<boolean> {
    // Verify the anchor against the external record
    return verifyAgainstMyBackend(anchor);
  }

  async dispose(): Promise<void> {
    // Cleanup resources
  }
}

Register it with the core factory:

import { registerAnchorProviderFactory } from '@framers/agentos';
import { MyCustomProvider } from './MyCustomProvider';

registerAnchorProviderFactory('my-custom', (opts) => new MyCustomProvider(opts));

Utilities

fetchWithRetry(url, init, options)

HTTP fetch wrapper with exponential backoff retry. Used internally by providers that communicate over HTTP.

import { fetchWithRetry } from '@framers/agentos-ext-anchor-providers';

const response = await fetchWithRetry('https://api.example.com/anchor', {
  method: 'POST',
  body: JSON.stringify(data),
}, { timeoutMs: 10000, retries: 3 });

canonicalizeAnchor(anchor)

Deterministic JSON serialization of an AnchorRecord with sorted keys. Ensures all providers hash the same byte representation.

hashCanonicalAnchor(anchor)

Computes SHA-256 hex digest of the canonical anchor representation.

Implementation Status

| Provider | Status | Notes | |----------|--------|-------| | WormSnapshotProvider | Stub | Requires @aws-sdk/client-s3 implementation | | RekorProvider | Stub | Requires sigstore SDK implementation | | OpenTimestampsProvider | Stub | Requires opentimestamps implementation | | EthereumProvider | Stub | Requires ethers implementation | | SolanaProvider | Implemented | Requires @solana/web3.js (and a funded signer) |

All providers except SolanaProvider currently return { success: false } from publish() until their respective SDK integrations are implemented. SolanaProvider is functional when its optional peer dependencies are installed and the configured signer is funded.

Testing

# Run all tests
pnpm test

# Run with coverage
pnpm test:coverage

# Watch mode
pnpm test:watch

Test Structure

| File | Description | |------|-------------| | test/providers.spec.ts | Unit tests for all 4 providers — identity, stub behavior, config | | test/register.spec.ts | Registration tests — verifies factories are registered with core | | test/integration.spec.ts | End-to-end integration — factory creation, provider identity, stub behavior | | test/utils.spec.ts | Utility tests — canonicalization, SHA-256 hashing, HTTP retry | | test/types.spec.ts | Config resolution tests — default values, overrides |

Related Packages

| Package | Description | Link | |---------|-------------|------| | @framers/agentos | Core AgentOS framework with AnchorProvider interface, AnchorManager, registry | packages/agentos | | @framers/agentos provenance types | AnchorProvider, ProofLevel, AnchorProviderResult interfaces | src/core/provenance/types.ts | | @framers/agentos factory | createAnchorProvider(), registerAnchorProviderFactory() | src/core/provenance/anchoring/providers/createAnchorProvider.ts | | @framers/agentos built-in providers | NoneProvider, CompositeAnchorProvider | src/core/provenance/anchoring/providers/ | | @framers/agentos AnchorManager | Periodic anchoring with external provider support | src/core/provenance/anchoring/AnchorManager.ts | | @framers/agentos profiles | sealedAuditable() convenience profile | src/core/provenance/config/PolicyProfiles.ts |

License

MIT