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

@r4-sdk/node

v1.1.0

Published

Official R4 SDK for Node.js — programmatic access to R4 vault secrets

Readme

@r4-sdk/node

Official R4 SDK for Node.js. Use it from trusted server-side or agent runtimes to read R4 vault-backed secrets, download encrypted attachments, and call authenticated machine API routes.

The SDK is intentionally self-contained: it has no R4-internal runtime dependencies and ships only the compiled lib/ output.

Requirements

  • Node.js 18 or newer
  • An AGENT-scoped R4 API key and local PEM private key for zero-trust decryption
  • Or a CLI account profile for low-level machine API calls

Installation

npm install @r4-sdk/node

Quick Start

import R4 from '@r4-sdk/node'

const r4 = await R4.create({
  apiKey: process.env.R4_API_KEY!,
  privateKeyPath: './agent-private-key.pem',
})

const password = r4.env.PRODUCTION_DB_PASSWORD

Only fields explicitly marked as environment variables in R4 are exposed through r4.env.

Scope the environment map to one project:

const r4 = await R4.create({
  profile: 'openclaw-agent',
  projectId: 'production-infrastructure',
})

const password = r4.env.PRODUCTION_DB_PASSWORD

This uses the same project environment data as r4 project env production-infrastructure. Values are decrypted locally; the machine API only returns encrypted vault data and wrapped keys.

Configuration

| Option | Required | Description | | --- | --- | --- | | apiKey | No | AGENT-scoped API key in {accessKey}.{secret} format. | | auth | No | Explicit auth provider for low-level machine API access. | | profile | No | Named CLI profile from ~/.r4. | | unlockPassword | No | Unlock password for account profiles created by r4 login. | | privateKey | No | Inline PEM private key. Use only when your runtime already manages key custody securely. | | privateKeyPath | No | Filesystem path to the local PEM private key. | | trustStorePath | No | JSON trust-store path for pinned signer keys. | | projectId | No | Restrict vault discovery to one project by ID or slug. | | baseUrl | No | API base URL. Defaults to https://r4.dev. | | dev | No | Use https://dev.r4.dev when baseUrl is not set. |

Provide either privateKey or privateKeyPath for R4.create(). When both dev and baseUrl are provided, baseUrl wins.

High-level local decryption requires an AGENT API key or an agent profile imported with r4 configure agent --config <path>. Account profiles are supported by R4Client for authenticated machine API calls.

Core API

R4.create(config)

Creates an SDK instance, fetches accessible vault metadata, verifies signer trust, unwraps vault keys locally with the already-registered agent key, and populates r4.env.

r4.env

Flat Record<string, string> of decrypted environment variables. Keys are generated as VAULT_ITEM_FIELD in SCREAMING_SNAKE_CASE.

r4.refresh()

Re-fetches accessible vaults and rebuilds the local env map.

r4.requestMachine({ method, path, body })

Sends an authenticated request to a machine API route without bypassing SDK auth handling.

const identity = await r4.requestMachine({
  method: 'GET',
  path: '/me',
})

new R4Client(auth, baseUrl)

Low-level machine API client for workflows that do not need local decryption.

import { R4Client } from '@r4-sdk/node'

const client = new R4Client(process.env.R4_API_KEY!, 'https://r4.dev')
const identity = await client.getMachineIdentity()

The first argument can also be an explicit auth provider:

const client = new R4Client(
  {
    type: 'accessToken',
    accessToken: process.env.R4_ACCESS_TOKEN!,
    deviceInstallationId: process.env.R4_DEVICE_INSTALLATION_ID,
  },
  'https://r4.dev',
)

Or load a CLI profile:

const client = R4Client.fromProfile({
  profile: 'personal',
  unlockPassword: process.env.R4_CLI_PASSWORD,
})

Attachments

downloadVaultAttachment retrieves a signed download ticket, verifies signer trust and content checkpoints, downloads ciphertext, checks ciphertext and plaintext hashes/sizes, decrypts locally, and optionally writes the plaintext file.

const result = await r4.downloadVaultAttachment({
  vaultId: 'VAULT_ID',
  assetId: 'ASSET_ID',
  outputPath: './artifact.bin',
})

console.log(result.outputPath)
console.log(result.bytes.length)

Managed Token Providers

Use callAnthropicWithTokenProvider when you want R4 budget enforcement while keeping the vendor API key local to the runtime.

const result = await r4.callAnthropicWithTokenProvider({
  tokenProviderId: 'TOKEN_PROVIDER_ID',
  body: {
    model: 'claude-sonnet-4-5-20250929',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Summarize the incident notes.' }],
  },
})

console.log(result.response)
console.log(result.usage.actualCostUsd)

If you need raw decrypted provider fields for a custom client, use the explicit escape hatch:

const provider = await r4.getTokenProviderFields('TOKEN_PROVIDER_ID', {
  unsafeExport: true,
})

Security Model

The SDK never asks R4 to decrypt vault values. The runtime:

  1. Loads the private key from the imported agent runtime config.
  2. Uses the public key registered by the Platform agent wizard.
  3. Fetches wrapped vault data encryption keys and signer directories.
  4. Verifies signer fingerprints and rotation continuity.
  5. Pins trusted signer keys in a local trust store.
  6. Verifies wrapped-key signatures before unwrapping vault keys locally.
  7. Decrypts only the requested vault fields or attachment bytes in process memory.

The trust store is written with owner-only permissions. If a trust store exists but cannot be parsed, the SDK fails closed instead of silently resetting pins.

Operational Notes

  • Keep the private key outside source control and deployment logs.
  • Use one agent key per runtime identity so access can be revoked precisely.
  • Create agents in the R4 web UI, download the runtime JSON config, and import it with r4 configure agent --config <path> when you want the CLI and SDK to share the same local agent profile.
  • The web UI registers the public key and applies selected security groups during agent creation.
  • Rotate keys by re-registering the new public key with continuity proof and rewrapped vault keys.
  • Prefer privateKeyPath over inline privateKey unless the surrounding runtime already has a dedicated secret manager.

Development

pnpm install
pnpm run typecheck
pnpm run test
pnpm run test:pack
pnpm run build

npm pack --dry-run is covered by pnpm run test:pack; it verifies that source files and tests are excluded from the published tarball.