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

@zerova-sh/zkapi

v0.1.0

Published

Standalone TypeScript client for Zerova private payments and bounded AI on Robinhood Chain Mainnet

Readme

Zerova zkAPI SDK

Private-payment and bounded AI integration for TypeScript and JavaScript applications.

@zerova-sh/zkapi provides a framework-independent client for Zerova on Robinhood Chain Mainnet. Browse models, prepare requests, stream text responses, and coordinate browser payments and recovery without managing proofs or temporary inference credentials yourself.

The package maintains its own implementation and public assets. It does not depend on, re-export, or download another zkAPI SDK, and it does not require a customer model-provider API key.

Version 0.1.0 · ESM · Robinhood Chain Mainnet

Contents

Features

  • Typed, framework-independent API. ESM exports and generated TypeScript declarations; no runtime npm dependencies.
  • Public model discovery. Paginated catalog reads with eligibility, price versions, expiry, and exact rational tariffs.
  • Bounded text generation. Complete responses and Server-Sent Events, with explicit disclosure and session-cap consent.
  • Browser-owned payments. EIP-1193 wallet integration, local note custody, explicit funding, withdrawal initiation, and encrypted backup export.
  • Recovery-aware execution. Durable dispatch bookkeeping, serialized financial admission, original-session settlement, and no automatic paid replay.
  • Self-hosted proof assets. Verified worker/WASM/key loading and an explicit asset-copy helper; no postinstall downloads or consumer-side Rust compilation.

The SDK separates model discovery, explicit payment actions, response delivery, and settlement so applications can present each state accurately.

Requirements

| Environment | Available functionality | Requirements and limits | | --- | --- | --- | | Browser | Public APIs and payment/text-generation methods | Secure context, IndexedDB, Web Locks, BroadcastChannel, Web Workers, WebCrypto, and compatible CSP | | Node.js 24+ | Catalog, readiness, preflight, amount helpers, and asset-copy tooling | ESM and standard Fetch/WebCrypto APIs; no native paid wallet runtime | | Other runtimes | Not verified | No Deno, Bun, Edge, React Native, or native OS compatibility claim |

Supply a compatible EIP-1193 provider for deposits and withdrawals. Use your existing wallet connector; Reown/AppKit is not a package dependency. JavaScript consumers use the same API without TypeScript annotations.

The SDK targets one pinned deployment:

| Setting | Value | | --- | --- | | Network | Robinhood Chain Mainnet | | Chain ID | 4663 | | Billing asset | Native ETH; note accounting in integer gwei | | Vault | 0x101469731196e9023Ddab3B02962E892cE74b355 | | Protocol | https://zkapi.zerova.sh | | Catalog | https://api.zerova.sh | | Public RPC | https://robinhood.drpc.org |

These are configuration pins, not a live availability attestation. Arbitrary chain, vault, operator, signer, or RPC overrides are not supported.

Installation

Local package

For authorized local evaluation, use the tarball produced under sdk/artifacts/. Place it in your application directory and install it:

npm install --ignore-scripts ./zerova-zkapi-0.1.0.tgz

Compare the artifact with its accompanying SHA256SUMS. Local packaging does not establish permission to redistribute it; read LICENSE.md before redistribution.

npm distribution

After the owner completes the release gates and publishes the package, the intended installation command is:

npm install @zerova-sh/zkapi

That command is not an assertion that a registry release currently exists. Pin the package version for reproducible application builds.

Package contents

The npm archive contains only the compiled SDK and declarations under dist/, the required public proof/worker/WASM assets under assets/, package.json, and two documents: README.md and LICENSE.md. Attribution and legal notices are consolidated in LICENSE.md.

Source files, tests, fixtures, build scripts, changelog/security documents, separate notices, audit reports, engineering decisions, dependency inventories, provenance working records, release-readiness records, and local verification artifacts remain in the source workspace. They are not included in the consumer package. Type declarations (.d.ts and .d.mts) are part of the SDK's TypeScript interface, not test files.

Packaging uses an explicit file-by-file policy. verify:package checks the complete npm inventory, required runtime assets, and local documentation links; ordinary npm pack runs that guard before creating an archive. Internal files are excluded without deleting them from the project.

Quick start

1. Explore the public catalog

No wallet or payment initialization is needed:

import { createZerova } from '@zerova-sh/zkapi'

const zerova = createZerova()
const page = await zerova.models.list({ q: 'deepseek', limit: 20 })

console.table(page.items.map(model => ({
  name: model.name,
  model: model.provider_service_code,
  eligible: model.inference_eligible,
})))

if (page.nextCursor) {
  const nextPage = await zerova.models.list({
    q: 'deepseek',
    limit: 20,
    cursor: page.nextCursor,
  })

  console.log(nextPage.items.length)
}

Use provider_service_code, not the catalog record's internal id, when selecting a chat model. models.get(model) accepts that same model identifier. Listing a model does not prove live availability or affordability; generation revalidates executable metadata and prices.

2. Host the public proof assets

Run the Node-only helper from your application's build tooling:

import { copyAssets } from '@zerova-sh/zkapi/build'

await copyAssets({
  outDir: 'public/zerova/zkapi/0.1.0',
})

Serve that directory at /zerova/zkapi/0.1.0/. The helper verifies packaged hashes and refuses to overwrite different existing assets. Use versioned directories and retain earlier assets required for recovery. Consumers do not need Rust, a protocol checkout, or private environment files.

3. Initialize a browser payment client

Pass the provider obtained from your application's explicit wallet-connection flow:

import { createZerova } from '@zerova-sh/zkapi'
import type { Eip1193Provider } from '@zerova-sh/zkapi'

export async function createBrowserClient(provider: Eip1193Provider) {
  const zerova = createZerova({
    walletProvider: provider,
    assetsBaseUrl: '/zerova/zkapi/0.1.0/',
  })

  const snapshot = await zerova.initialize()
  return { zerova, snapshot }
}

Imports and client creation do not fetch configuration, connect a wallet, access payment storage, create a worker, or fund a note. initialize() explicitly activates the browser runtime, proof worker, local journals, and bounded recovery. It does not authorize a transaction or paid generation.

[!NOTE] A private note belongs to its application origin's local storage. A new origin does not inherit a note from zerova.sh, and reconnecting the funding wallet alone does not restore it. This version does not expose browser note import. An empty wallet requires an explicit, separately reviewed funding action.

Configuration

createZerova(options?) accepts only the following options:

| Option | Type | Default | Purpose | | --- | --- | --- | --- | | assetsBaseUrl | string | /zerova/zkapi/ | Public asset directory; must end with / and use HTTPS or an allowed loopback HTTP origin | | walletProvider | Eip1193Provider | Not supplied | Host-owned wallet provider for explicit browser transactions | | fetch | FetchTransport | Global fetch | Optional transport for approved SDK requests and worker-source retrieval |

There is no apiKey, baseURL, account JWT, conversation ID, or automatic-renewal option. A custom transport must preserve omitted credentials, redirect rejection, destination restrictions, and the no-referrer policy. It must not add history credentials, log sensitive bodies, replay paid requests, or assume that worker-internal WASM/key downloads pass through it.

One configured financial client owns a page. Reuse it across components rather than initializing a payment client for each render. Competing live clients fail closed. After disposal, reopen with the same provider, asset URL, and transport identity; changing configuration requires a fresh page. Existing financial locks also coordinate browser tabs.

Text generation

Before submitting any draft, your UI must explain the content path and obtain explicit spending-limit consent. Set contentDisclosureAcknowledged: true only after that disclosure: preflight itself sends content to Zerova, even though it does not start paid provider inference.

Complete a response

Call this function only from an explicitly approved user submission, using a current catalog model and a sufficiently funded note:

import type { ZerovaClient } from '@zerova-sh/zkapi'

export async function generateReply(
  zerova: ZerovaClient,
  model: string,
  prompt: string,
) {
  return zerova.chat.complete({
    model,
    messages: [{ role: 'user', content: prompt }],
    spendingLimitUsd: '1',
    contentDisclosureAcknowledged: true,
    maxTokens: 256,
  })
}

The result contains model, text, usage, and paymentState. Render the text and payment state separately: a complete answer can still have paymentState: 'settlement_pending'. Provider-reported usage is provisional, not final settlement evidence.

Stream a response

chat.stream() returns an async iterable of typed events:

import type { ChatEvent, ChatRequest, ZerovaClient } from '@zerova-sh/zkapi'

export async function streamReply(
  zerova: ZerovaClient,
  request: ChatRequest,
  onEvent: (event: ChatEvent) => void,
) {
  for await (const event of zerova.chat.stream(request)) {
    onEvent(event)
  }
}

| Event | Payload | Intended use | | --- | --- | --- | | delta | text | Append visible response text | | usage | usage | Display provisional provider usage | | complete | result | Display the completed answer and its separate payment state |

Pass an AbortController's signal on the ChatRequest to support cancellation. Aborting, breaking the iterator, closing a tab, or losing a connection does not establish zero usage or a refund. Partial streams are not synthesized into completed responses. Preserve pending state and use original-operation recovery rather than replaying generation.

Prepare without authorizing payment

chat.prepare(request) returns immutable model, priceVersion, maximumCostUsd, validUntil, and spendingLimitUsd metadata. It runs catalog resolution and disclosed preflight, but does not initialize a wallet or issue access. Preparation is advisory, not a reservation; complete() and stream() revalidate before dispatch.

Request limits and settlement

| Setting | Behavior | | --- | --- | | spendingLimitUsd | Required string: '1', '2', '3', '4.5', or '6' | | Messages | Text only; system, user, and assistant roles | | maxTokens | Integer from 1 to 512; defaults to 512 and is bounded by model metadata | | Concurrency | One admitted generation at a time | | Paid retries and provider fallback | None | | Settlement | Attempted for the original session after the request |

Session caps are maximum authorizations, not flat message prices or permission for unlimited renewals. The SDK resolves prices from Zerova's published catalog, validates preflight bounds, retains the temporary credential internally, and durably records dispatch before sending once. Missing or stale prices stop new access. Published price metadata is distinct from a request-time price guarantee.

Payments and recovery

Inspect local state and live readiness

payments.inspect() returns a redacted snapshot with state, balanceGwei, pending, and backupRecommended. Before initialization it returns not_initialized without accessing storage. After initialization, its local states include empty, ready, recovery_required, and settlement_pending.

readiness() separately checks the matching deployment and reports public CORS, indexing, quote, funding, and inference readiness. A local ready state or positive balance does not establish selected-cap coverage or live model availability. productionVerified remains false until the required acceptance work is completed; the package version does not override that field.

Use subscribe(listener) for redacted payment-state changes; it returns an unsubscribe function. Subscriptions do not expose note secrets, proofs, or temporary bearer credentials.

Review and confirm funding

Create a quote first. Invoke confirmation only after the user reviews the chain, vault, amount, and wallet gas:

import type { DepositQuote, ZerovaClient } from '@zerova-sh/zkapi'

export async function prepareFunding(zerova: ZerovaClient, from: string) {
  return zerova.payments.quoteDeposit({ amountEth: '0.001', from })
}

export async function confirmFunding(
  zerova: ZerovaClient,
  quote: DepositQuote,
) {
  return zerova.payments.deposit(quote, { confirmed: true })
}

Quotes are instance-owned: copied, modified, or reused quote objects are rejected. confirmed: true records application consent; it does not replace the user's wallet approval. A plain ETH transfer to the vault is not a note deposit. Funding readiness is separate from quote and inference availability.

Initiate a withdrawal

import type { ZerovaClient } from '@zerova-sh/zkapi'

export async function withdrawToWallet(
  zerova: ZerovaClient,
  destination: string,
) {
  return zerova.payments.withdraw({
    mode: 'mutual',
    destination,
    confirmed: true,
  })
}

Invoke withdrawal only after explicit review and consent. The operation result distinguishes state, transactionHash, payoutVerified, and payoutCredited; submission or credited payout is not proof of delivery.

mode: 'escape' initiates the underlying unilateral path, subject to contract timing and ownership checks. Public escape-finalization and payout-claim methods are not exposed in this version. Initiation is not a completed exit; retain compatible original recovery tooling. Full funded exit/recovery acceptance remains a release gate.

Recover the original operation

| Method | Responsibility | | --- | --- | | recovery.settle() | Reconcile the existing lease and inspect retained payment state | | recovery.resume() | Recover an existing deposit, settle existing access, and synchronize retained withdrawals |

These are explicit reconciliation actions, not passive status reads; they can activate the browser runtime. They never generate a replacement answer. Unknown outcomes retain dispatch records and native journals. A dispatch marker clears only after a matching verified successor for the original note with no remaining native obligation—not merely because a UI looks clean or another note is present.

Export an encrypted backup

import type { ZerovaClient } from '@zerova-sh/zkapi'

export async function exportBackup(
  zerova: ZerovaClient,
  passphrase: string,
) {
  return zerova.payments.exportExitKit({
    passphrase,
    sensitiveExportAcknowledged: true,
  })
}

Use a user-selected passphrase of at least 12 characters and obtain explicit export consent. Save the returned encrypted kit through your application's reviewed download flow; never log it or the passphrase, or store them in conversation history. Pending conflicts block export. A settled snapshot is not a complete pending-journal backup, and exporting it does not revoke other copies. Plaintext note exchange and browser import are not exposed here.

Dispose without deleting payment state

dispose() stops SDK-owned timers, listeners, and worker access. It refuses while a financial operation is active and never deletes notes, journals, or unresolved exposure. Disposal is not settlement, withdrawal, or recovery. Application logout and history deletion must likewise preserve payment storage.

API reference

Package entry points

| Import | Exports | | --- | --- | | @zerova-sh/zkapi | Client factory, public types, ZerovaError, profile, spending tiers, and amount helpers | | @zerova-sh/zkapi/browser | Browser-facing client factory, selected types, error, profile, and spending tiers | | @zerova-sh/zkapi/profiles | Immutable robinhoodMainnet profile and spendingLimitsUsd | | @zerova-sh/zkapi/build | Node-only copyAssets() helper and its types |

There is no native entry point in this version. Do not import the Node-only build helper into a browser bundle or rely on internal source paths as a public API.

Client methods

| Surface | Methods | | --- | --- | | Lifecycle | initialize(), readiness(), subscribe(listener), dispose() | | Catalog | models.list(query?), models.get(model, options?) | | Text | chat.prepare(request), chat.complete(request), chat.stream(request) | | Payments | payments.inspect(), quoteDeposit(input), deposit(quote, approval), withdraw(options), exportExitKit(input) | | Recovery | recovery.settle(), recovery.resume() |

See the public type declarations for exact parameters and results. The package ships generated declarations; no separate type package or upstream SDK installation is required.

Exact amount helpers

import { parseEth, formatEth, parseUsd, formatUsd } from '@zerova-sh/zkapi'

const principalGwei = parseEth('0.001')
const principalEth = formatEth(principalGwei)
const costUnits = parseUsd('0.00000465')
const costUsd = formatUsd(costUnits)

| Helpers | Integer representation | | --- | --- | | parseEth() / formatEth() | Gwei: 10^9 units per ETH, not wei | | parseUsd() / formatUsd() | Trillionths of USD: 10^12 units per USD | | parseAmount() / formatAmount() | Explicit decimal scale |

Parsing returns bigint; formatting returns a canonical decimal string. Public monetary fields use strings. Accepted ETH/USD lease conversion, current indicative USD, catalog model rates, wallet gas, and verified settled charges are separate values. Do not convert them through floating-point arithmetic or rewrite saved proof-bound quotes.

Error handling

ZerovaError exposes sanitized code, message, phase, exposure, retryable, and toJSON() fields. It does not attach raw provider errors, request content, proofs, or private wallet state.

import { ZerovaError } from '@zerova-sh/zkapi'

export function requiresRecovery(error: unknown): boolean {
  if (!(error instanceof ZerovaError)) return false

  return error.exposure !== 'none'
    || error.code === 'recovery_required'
    || error.code === 'request_settlement_pending'
}

This helper classifies UI guidance; it is not permission to retry or discard state. Handle the original error and offer explicit recovery separately.

| Code | Recommended handling | | --- | --- | | invalid_request, invalid_configuration | Correct the request or configuration before submitting again | | unsupported_environment, wallet_required | Use the required browser capabilities or supply the wallet provider | | model_unavailable, prices_stale, preflight_invalid | Refresh/review model and price metadata; do not bypass validation | | deployment_mismatch, operator_unavailable | Stop new access; verify the pinned deployment and live readiness | | payment_busy, profile_conflict | Finish the existing operation or use the page's configured client | | recovery_required, request_settlement_pending | Preserve journals and reconcile the original obligation | | inference_outcome_unknown | Assume usage may exist; do not replay generation | | withdrawal_submission_pending, withdrawal_confirmation_pending | Check the original withdrawal, not a second submission |

The full taxonomy is in the packaged error implementation. Cancellation is not a financial rollback. Inspect exposure and pending state rather than assuming an error means no charge; retryable is not an automatic-retry policy.

Security and privacy

Mainnet payments use real ETH. The deployed proof setup is operator-trusted and single-party; no independent audit or completed production/funded-recovery acceptance is claimed.

Content and credential boundaries

Applications send preflight and inference content to Zerova. Zerova processes requests and forwards inference to third-party model providers. Payment unlinkability is not content confidentiality, IP anonymity, anonymous history, or public-chain privacy.

  • Keep application authentication and history outside the payment SDK. Never forward JWTs, cookies, login-wallet identity, or conversation identifiers into protocol/inference requests.
  • Model-provider credentials stay server-side. High-level results do not expose the temporary bounded credential.
  • Treat same-origin scripts and XSS as custody risks. Do not log notes, proofs, passphrases, encrypted kits, or raw protocol diagnostics.
  • Preserve financial journals, earlier deployment assets, and original-operation recovery material. Reconnecting a wallet or restoring an older snapshot is not sufficient recovery.

Browser deployment and CSP

Merge the SDK's requirements into your application's existing policy; do not replace or weaken unrelated directives:

| Directive | Required consideration | | --- | --- | | connect-src | The pinned protocol, catalog, public RPC, and your public asset origin | | worker-src | Permit the verified Blob worker, typically 'self' blob: | | script-src | Permit supported WASM compilation, typically with 'wasm-unsafe-eval', while retaining your existing script restrictions |

The SDK checks worker bytes before creating a Blob worker and pins WASM/proving-key hashes. Artifact reads are bounded and omit credentials/referrers. If you host assets cross-origin, that host must also permit credential-free browser reads. Actual CSP, browser compatibility, API CORS, and hosted readiness must be verified in your deployment; do not bypass browser security to make initialization succeed.

A private vulnerability-reporting contact must be established before publication. Do not post note secrets, proofs, passphrases, provider credentials, customer state, or raw protocol diagnostics publicly. Repository-only security records are not included in the npm archive; the consumer-facing security boundaries are documented in this section.