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

@cef-ai/vault-sdk

v5.7.0

Published

Client SDK for apps talking to a user's CEF Vault from outside the Agent Runtime: chat UIs, Slack bots, data pipelines, integrations.

Readme

@cef-ai/vault-sdk

Client SDK for apps talking to a user's CEF Vault from outside the Agent Runtime: chat UIs, Slack bots, data pipelines, integrations.

Install

pnpm add @cef-ai/vault-sdk

Quickstart

Browser app, wallet already registered as a gateway proxy on-chain (the common case once onboarding has run once via @cef-ai/account):

import { VaultSDK, type EnsureProgressEvent } from "@cef-ai/vault-sdk";

const sdk = new VaultSDK({
  endpoint: "https://vault.cere.io",
  garEndpoint: "https://gar.cere.io",
  chainUrl: "wss://rpc.cere.network",        // the vault-delegate grant step
  s3GatewayAuthInfoUrl: "https://ddc-s3-gateway.compute.dev.ddcdragon.com/auth/info",
  // Override to point at the prod marketplace; defaults to the dev cluster URL.
  marketplaceEndpoint: "https://agent-marketplace.compute.dev.ddcdragon.com",
  signer: mySigner,                          // any `@cef-ai/signer` Signer
});

const vault = await sdk.vault.ensure({
  onProgress: (e: EnsureProgressEvent) => console.log(e.kind),
});

await vault.scope("default").publish({
  type: "user_message",
  context: "conv-42",
  payload: { text: "Hi" },
});

Server-side (pre-provisioned wallet, skip onboarding):

import { VaultSDK, CereWallet } from "@cef-ai/vault-sdk";

const signer = await CereWallet.fromMnemonic(process.env.WALLET_MNEMONIC!);
const sdk = new VaultSDK({
  endpoint: "https://vault.cere.io",
  garEndpoint: "https://gar.cere.io",
  chainUrl: "wss://rpc.devnet.cere.network/ws",
  s3GatewayAuthInfoUrl: "https://ddc-s3-gateway.compute.dev.ddcdragon.com/auth/info",
  signer,
});
const vault = await sdk.vault.ensure({ onboard: false });

Onboarding

vault-sdk depends on no @cere-ddc-sdk/* package and stays chain-free at module load — the chain stack (@cef-ai/account → @cef-ai/chain) is loaded lazily, only when vault.ensure() actually runs the vault-delegate grant step. vault.ensure() also runs a lightweight, HTTP-only onboarding status check by default:

  1. Status check — GET /auth/onboarding/status (404 means prod, skip the rest of this section entirely).
  2. Bootstrap (devnet only) — if faucet_eligible or ddc_seed_eligible, POST /auth/onboarding/bootstrap to drip CERE and seed the DDC deposit.
  3. If the gateway reports the wallet is still not a registered proxy (gateway_is_proxy: false), vault.ensure() throws OnboardingRequiredError instead of trying to submit the on-chain extrinsic itself.

Registering the gateway as a proxy is now done externally, via @cef-ai/account's provisioning.ensure:

import { provisioning } from "@cef-ai/account";

await provisioning.ensure({
  signer: myChainSigner,           // a `@cef-ai/signer` Signer
  chainUrl: "wss://rpc.devnet.cere.network/ws",
  gateway: gatewaySs58Address,
});

// Now retry — the gateway will see the proxy and `ensure()` will proceed.
const vault = await sdk.vault.ensure({ onProgress: (e) => console.log(e.kind) });

onProgress receives an EnsureProgressEvent for each stage:

| Kind | Meaning | | --- | --- | | inspecting-wallet | Gateway status probe is in flight. | | funding-wallet | Devnet auto-fund (CERE drip + DDC seed deposit); never fires on prod. | | gateway-authorization-required | Onboarding required; carries status: OnboardingStatus. ensure() throws OnboardingRequiredError right after this fires. | | authorizing-vault | Granting vault-api write delegation: ensureVaultDelegate checks/submits the on-chain NonTransfer proxy. Only fires on the default (tokenless) path. | | provisioning-vault | Calling POST /api/v1/vaults to claim the record. |

One error can surface from the pipeline:

  • OnboardingRequiredError — the gateway reports the wallet still needs the on-chain proxy step (whether onboard was left at its default or set to false). Run @cef-ai/account's provisioning.ensure externally, then retry ensure().

Write delegation (the claim's authorization)

By default vault.ensure() claims the vault tokenless: after the onboarding check it grants vault-api's delegate key an on-chain NonTransfer proxy (@cef-ai/account's ensureVaultDelegate, which discovers the key from GET {endpoint}/api/v1/delegate-info and skips submission when the grant already exists), then POSTs {name, label: "vault"} — vault-api routes that shape through its proxy saga. This needs a signer and a chainUrl (constructor or per call); without a chainUrl the wallet path fails with a config error.

opts.delegationToken is the legacy escape hatch: when passed, the grant step is skipped entirely and the token-bearing claim body of the old flow is sent instead (vault-api accepts both shapes). Nothing in this SDK mints DDC delegation tokens any more — the @cef-ai/account native builder was removed with the migration; token-holding callers bring their own.

Connecting an agent

vault.agents.connect({ agentId, scope, settings }) is the high-level entry point. It builds the v2 agreement payload, signs it with your wallet, POSTs the signed envelope to the Global Agent Registry (GAR), and then calls vault-api POST /agents with the resulting signature — all internally. The agent-service pubkey the GAR agreement is keyed on is derived from the agentId prefix (<agentServicePubkey>:<alias>); pass agentServicePubkey explicitly to override. version/manifestCid are not sent — the vault-api resolves the manifest from the DDC registry itself, so no prior getAgent call is required to connect.

// Optional: fetch the display card to render before connecting.
const { agentId, card } = await sdk.marketplace.getAgent("personal-assistant");
console.log(card.name, card.description);

const handle = await vault.agents.connect({
  agentId,
  scope: "default",
  settings: { language: "en" },
});

console.log(handle.agentId, handle.status);

Requires garEndpoint and a signer on VaultSDKConfig. If you already have a pre-signed agreementSignature (e.g. from a custodial flow), drop down to the low-level Agents.connect(vaultId, ConnectAgentRequest) exported from @cef-ai/vault-sdk/internal.

Surface

| Method | Maps to | | --- | --- | | sdk.vault.ensure({ onboard?, onProgress?, chainUrl?, delegationToken? }) | onboarding check + on-chain vault-delegate grant + POST /api/v1/vaults (tokenless by default) | | sdk.vault.current() | GET /api/v1/vaults | | sdk.vault.delegations.grant(vaultId, { vaultBucketId, registryBucketId, expiresAt? }) — owner only; mints the vault and registry delegation tokens with the configured signer (two signatures) and sends them; re-run to renew before delegationsExpireAt | GET /api/v1/delegate-info + PUT /api/v1/vaults/:v/delegations | | sdk.vault.delegations.put(vaultId, { vaultDelegationToken, registryDelegationToken }) — tokens minted with mintDelegationTokens(...) | PUT /api/v1/vaults/:v/delegations | | vault.scopes.{list,get,create,update,delete} | /api/v1/vaults/:v/scopes | | vault.agents.connect({ agentId, scope, settings }) (signs GAR internally) | POST {garEndpoint}/api/v1/agreements + POST /api/v1/vaults/:v/agents | | vault.agents.{list,get} → AgentConnectionHandle | /api/v1/vaults/:v/agents | | handle.update(settings) / handle.disconnect() | PATCH / DELETE | | handle.setCeiling({ gpuUnits?, a2aTokens? }) — spend ceiling; gpuUnits = platform-metered, a2aTokens = agent self-reported (integer); absent/0 = no ceiling, {} clears both; read back as handle.ceiling (absent = none) | PUT /agents/:a/ceiling | | handle.cubby(alias).query(...) / .exec(...) | /scopes/:s/cubbies/:alias/{query,exec} | | handle.jobs.list({ state?, cursor?, limit? }) | /agents/:a/jobs | | vault.scope(s).publish(input) | POST /scopes/:s/events | | vault.scope(s).subscribe(filter, handler, opts?) | poll-backed long-poll over /streams/:c/events | | vault.scope(s).subscribeAll(filter, handler, { refreshIntervalMs? }) | fans out across streams.list(); refreshes every 30 s by default | | vault.scope(s).streams.list() / .get(c) / .stream(c).events.list() | /scopes/:s/streams[/:c[/events]] | | vault.jobs.list({ state? }) / .get(jobId).activities.list() | /jobs[/...] | | handle.jobs.get(jobId).activities.subscribe({ since? }, handler) | poll-backed activity tail with seen-id dedupe | | sdk.marketplace.getAgent(id, version?) → { agentId, agentServicePubkey, version, card } | public GET /api/v1/marketplace/agents/:id[/versions/:v] | | sdk.marketplace.list({ limit?, cursor?, query? }) | public GET /api/v1/marketplace/agents | | sdk.health.live() / .ready() | public GET /health / /ready |

VaultSDKConfig knobs

| Field | Description | | --- | --- | | endpoint: string | Base URL for the vault API (wallet-authenticated). | | chainUrl?: string | Cere node WS URL. Required on vault.ensure()'s wallet path (signer + no delegationToken): drives the on-chain vault-delegate grant. Also settable per call. | | garEndpoint?: string | Base URL for the Global Agent Registry. Required for vault.agents.connect. | | marketplaceEndpoint?: string | Base URL for the agent marketplace API (separate host from the vault API; reads are unauthenticated). Default: dev cluster URL (https://agent-marketplace.compute.dev.ddcdragon.com). | | s3GatewayAuthInfoUrl?: string | Gateway /auth/info URL; its dirname is the gateway base the onboarding pipeline talks to. Default: dev cluster gateway. | | signer?: Signer / auth?: AuthProvider | Authenticated calls. Mutually exclusive — auth overrides signer. Signer is @cef-ai/signer's canonical interface. | | fetch?: typeof fetch | Inject a custom fetch for tests / non-browser runtimes. | | timeoutMs?: number | Per-request timeout (default 30 s). |

Scope.metadata: Record<string, unknown> is a free-form, server-stored map. vault.scopes.update(name, { metadata }) is a partial patch — server semantics are shallow-merge per top-level key (keys in the patch overwrite, others are preserved). The SDK whitelists the request body so only the keys you supply reach the wire.

Pluggable auth

VaultSDK accepts either a signer (default → WalletAuthProvider) or a fully custom auth: AuthProvider:

new VaultSDK({ endpoint, auth: new BearerAuthProvider(token) });

Ships with WalletAuthProvider and NoAuth. Implement AuthProvider yourself to plug in delegation tokens, trusted-headers, or anything else.

Signers

The SDK consumes a @cef-ai/signer.Signer — the canonical, chain-free signer interface shared across the SDK suite: { type, address, publicKey: Uint8Array, isReady(), sign(bytes, intent?) }. vault-sdk 3.0.0 retired its bespoke Wallet interface; pass any Signer directly.

  • KeypairWallet.fromSeed(bytes) — raw 32-byte ed25519 seed (server use); implements Signer.
  • CereWallet.fromMnemonic(mnemonic, type?) — wraps UriSigner; implements Signer.
  • CereWallet.fromKeystore(json, passphrase, type?) — Cere/Polkadot JSON keystore; implements Signer.

Browser apps using the CEF wallet pass embedWallet.asSigner() straight into new VaultSDK({ signer }) — it already satisfies Signer, so no adapter is needed (this replaces the old 3-method Wallet shim).

The UriSigner / JsonSigner classes powering CereWallet are vendored from @cere-activity-sdk/signers (Apache-2.0); see src/wallet/cere-internal/README.md for attribution and divergences. We dropped the runtime dep because the upstream package is neglected; the underlying @polkadot/keyring, @polkadot/util and @polkadot/util-crypto are pulled in directly.

Browser-extension and CereWalletNative adapters live in their own packages.

Lower-level access

@cef-ai/vault-sdk/internal re-exports Vaults, Scopes, Agents, Events, Browse, Cubbies, Health, Marketplace, plus VaultHttpClient and endpoints.

Onboarding primitives (runOnboarding, pollUntilProxyReady, getOnboardingStatus, runBootstrap, signerToOnboardingSigner) live under their respective files in src/internal/ for advanced consumers that need to drive the HTTP-only status/bootstrap pipeline piecewise. Use them only when the fluent surface isn't enough. On-chain proxy registration is not part of this SDK at all — see @cef-ai/account's provisioning.ensure (gateway proxy) and ensureVaultDelegate (vault-api write delegate).

Spec

See ../../specs/platform/03-components/vault-sdk.md (internal sibling repo) for the design contract.