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

@nibblelayer/apex-hono

v0.1.0

Published

Public Hono SDK for Apex self-hosted payable route integration.

Readme

@nibblelayer/apex-hono

Hono middleware SDK that connects your application to the Apex control plane for x402 payment-gated routes.

Purpose

The primary integration surface for external developers. Drop one line of middleware onto any Hono route and instantly enforce x402 payment requirements without managing pricing, wallets, or settlements yourself.

Install

pnpm add @nibblelayer/apex-hono hono

Quick Start

Set the SDK token and Apex API URL in your runtime environment:

export APEX_TOKEN="apx_sdk_your_scoped_token"
export APEX_URL="http://localhost:3000"
import { Hono } from 'hono';
import { apex } from '@nibblelayer/apex-hono';

const app = new Hono();

// Protect routes with x402 payment middleware. The scoped SDK token resolves
// service and environment from Apex; app code does not need those IDs.
app.use('/api/premium/*', apex());

// Unprotected routes work normally
app.get('/api/free', (c) => c.json({ message: 'free content' }));

// Protected route - requires payment
app.get('/api/premium/weather', (c) => c.json({ temp: 22 }));

export default app;

You can also pass values explicitly, which override environment variables:

app.use('/api/premium/*', apex({
  token: 'apx_sdk_your_scoped_token',
  apexUrl: 'https://api.apex.example.com',
}));

API Reference

apex(options?)

One-line Hono middleware factory. It resolves token from options.token, options.apiKey, or APEX_TOKEN, and resolves apexUrl from options.apexUrl or APEX_URL. Scoped SDK tokens (apx_sdk_...) use the signed /sdk/manifest endpoint so Apex can infer service and environment from the token.

interface ApexHonoOptions {
  token?: string;                         // Preferred scoped SDK token alias
  apiKey?: string;                        // Backward-compatible alias
  apexUrl?: string;                       // Apex API base URL
  serviceId?: string;                     // Optional strict binding or legacy mode
  environment?: 'test' | 'prod';          // Optional strict binding or legacy mode
  refreshIntervalMs?: number;
  enableIdempotency?: boolean;
  eventDelivery?: 'fire-and-forget' | 'batched';
  useSignedManifest?: boolean;
  verifySignedManifest?: boolean;
}

Lower-level API

createApexClient(config)

Factory function. Creates and initializes an ApexClient instance.

import { createApexClient } from '@nibblelayer/apex-hono';

const client = createApexClient({
  apiKey: 'apex_your_key',
  serviceId: 'svc_your_service',
  environment: 'test',
  apexUrl: 'http://localhost:3000',
});

app.use('/api/premium/*', await client.protect());

client.on('payment.settled', (data) => {
  console.log('Payment settled:', data);
});

ApexClientConfig

interface ApexClientConfig {
  apiKey: string;               // Apex API key (apex_...) or scoped SDK token (apx_sdk_...)
  serviceId?: string;           // Required for legacy unsigned mode
  environment?: 'test' | 'prod';// Required for legacy unsigned mode
  apexUrl: string;              // Apex API base URL
  refreshIntervalMs?: number;   // Manifest refresh interval (default: 60000)
  enableIdempotency?: boolean;  // Add payment-identifier extension (default: true)
  eventDelivery?: 'fire-and-forget' | 'batched'; // Event delivery mode (default: 'fire-and-forget')
  useSignedManifest?: boolean;  // Defaults true for apx_sdk_ tokens
  verifySignedManifest?: boolean; // Defaults true in signed mode
}

ApexClient Methods

| Method | Signature | Description | |---|---|---| | protect() | () => Promise<MiddlewareHandler> | Returns Hono middleware that enforces x402 payment on matching routes | | refreshManifest() | () => Promise<void> | Force an immediate manifest refresh from the Apex API | | on() | (event: SDKEventType, handler: Function) => void | Register an event listener | | off() | (event: SDKEventType, handler: Function) => void | Remove an event listener | | close() | () => void | Stop the refresh timer and clean up resources |

Events

| Event | Description | |---|---| | manifest.refreshed | Manifest successfully re-fetched and validated | | manifest.stale | Manifest refresh failed; using cached version | | payment.verified | A payment was verified for a protected route | | payment.settled | A payment was settled on-chain | | payment.failed | A payment failed verification or settlement |

Error Handling

import {
  ApexConnectionError,
  ApexManifestValidationError,
} from '@nibblelayer/apex-hono';

try {
  const apex = createApexClient(config);
  await apex.protect();
} catch (err) {
  if (err instanceof ApexConnectionError) {
    // Network or API connectivity failure
    console.error('Connection failed:', err.message);
    console.error('Cause:', err.cause);
  }

  if (err instanceof ApexManifestValidationError) {
    // Manifest failed Zod validation
    console.error('Validation issues:', err.issues);
  }
}

| Error Class | Properties | Description | |---|---|---| | ApexConnectionError | .message, .cause | Thrown when the SDK cannot reach the Apex API | | ApexManifestValidationError | .message, .issues | Thrown when the fetched manifest fails schema validation |

How It Works

  1. Initializationapex() constructs the client immediately but fetches the manifest lazily on the first request.
  2. Validation — Signed SDK manifests are verified and then validated against apexManifestSchema (Zod). Invalid manifests throw ApexManifestValidationError.
  3. Middleware assembly — Route-level x402 payment middleware is built from manifest route definitions. If enableIdempotency is true, a payment-identifier extension is added to each route.
  4. Auto-refresh — The manifest is re-fetched at refreshIntervalMs intervals. If a refresh fails, a manifest.stale event is emitted and the cached manifest continues to serve requests.
  5. Fallback — If @x402/hono is not installed, the SDK falls back to an adapter middleware that returns 402 Payment Required with the manifest pricing details.

Peer Dependencies

  • hono >= 4.0.0
  • @x402/hono (optional — enables full x402 payment protocol support; falls back to basic 402 responses when absent)

License

Apache-2.0