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

@premai/api-sdk

v1.0.65

Published

TypeScript client and local compatibility proxy for the [Prem Confidential API](https://docs.prem.io/).

Readme

@premai/api-sdk

TypeScript client and local compatibility proxy for the Prem Confidential API.

Documentation | Quickstart | API keys | npm

Choose an integration

| You want to | Use | | --- | --- | | Call the Confidential API from TypeScript | createRvencClient | | Use a configurable OpenAI-compatible client | confidential-proxy --compat openai | | Use a configurable Anthropic-compatible client | confidential-proxy --compat anthropic | | Launch Claude Code through the local proxy | confidential-claude | | Launch Qwen Code through the local proxy | confidential-qwen |

Install

npm install @premai/api-sdk

The SDK runs natively on Node.js, Bun, Deno, and Bare. It needs no native add-ons. The Bare runtime also powers the mobile client.

The package also publishes three command-line programs:

  • confidential-proxy: a local OpenAI and Anthropic-compatible HTTP server.
  • confidential-claude: an interactive launcher for Claude Code.
  • confidential-qwen: an interactive launcher for Qwen Code.

Prerequisites

  1. Create a Prem API key in the dashboard.
  2. Get the current Confidential API endpoints from dashboard.prem.io/endpoints.json.
  3. Generate a 32-byte Key Encryption Key (KEK), encoded as 64 hexadecimal characters:
export PREM_API_KEY="your-api-key"
export CLIENT_KEK="$(openssl rand -hex 32)"
export PROXY_URL="https://gateway.prem.io"
export ENCLAVE_URL="https://conf-engine.prem.io"

Keep the KEK in a secret manager and reuse it. Do not commit the API key, the KEK, or the serialized DEK store to source control.

These variable names apply to the examples only:

  • PREM_API_KEY — the SDK does not read this variable. Pass its value as apiKey, or send it in the authentication header for the local proxy.
  • CLIENT_KEK — an encryption key, not an API credential.
  • PROXY_URL — the remote Prem gateway URL, not the local confidential-proxy listener.

TypeScript quickstart

The TypeScript client performs encryption in the application process. You do not need to run confidential-proxy when you use this client directly.

import { createRvencClient } from "@premai/api-sdk";

function requireEnv(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Set ${name}`);
  return value;
}

async function main() {
  const client = await createRvencClient({
    apiKey: requireEnv("PREM_API_KEY"),
    clientKEK: requireEnv("CLIENT_KEK"),
    config: {
      endpoints: {
        proxy: requireEnv("PROXY_URL"),
        enclave: requireEnv("ENCLAVE_URL"),
      },
    },
  });

  const models = await client.models.list({ type: "CHAT" });
  const model = models.find((item) => item.enabled !== 0)?.model;
  if (!model) {
    throw new Error("No enabled chat model is available for this API key");
  }

  const response = await client.chat.completions.create({
    model,
    messages: [{ role: "user", content: "Reply with exactly OK." }],
    max_completion_tokens: 256,
  });

  console.log(response.choices[0]?.message?.content);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

To get a list of available models, see List available models. For request and response details, see Chat completions.

Local compatibility proxy

Use the proxy when an application already supports an OpenAI or Anthropic base URL. The proxy listens on http://127.0.0.1:8787 by default.

npx -p @premai/api-sdk confidential-proxy \
  --compat openai \
  --kek "$CLIENT_KEK"

The proxy reads PROXY_URL and ENCLAVE_URL from the environment. It does not read CLIENT_KEK automatically, so pass the KEK with --kek. It also does not read PREM_API_KEY. Each client must send its own API key with the request.

In another terminal, list the models available to the API key:

curl http://127.0.0.1:8787/v1/models \
  -H "Authorization: Bearer $PREM_API_KEY"

Then send a chat completion with an enabled chat model from that response:

export PREM_MODEL="your-enabled-chat-model"

curl http://127.0.0.1:8787/v1/chat/completions \
  -H "Authorization: Bearer $PREM_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"$PREM_MODEL\",
    \"messages\": [{\"role\": \"user\", \"content\": \"Reply with exactly OK.\"}],
    \"max_completion_tokens\": 256
  }"

Compatibility modes

| Mode | Local routes | | --- | --- | | openai | /v1/* | | anthropic | /v1/* | | both | /openai/v1/* and /anthropic/v1/* |

Use --compat both only when one proxy process must expose both API formats.

Run the proxy as a daemon

The proxy runs in the foreground by default. Use these subcommands to run it in the background instead:

| Command | Purpose | | --- | --- | | confidential-proxy start | Starts the proxy as a background daemon | | confidential-proxy status | Reports the process ID and whether the endpoint answers | | confidential-proxy stop | Stops the daemon with a graceful shutdown |

start takes the same options as the foreground command. Optionally add --log-file to redirect the daemon's stdout and stderr to a file.

npx -p @premai/api-sdk confidential-proxy start \
  --compat openai \
  --kek "$CLIENT_KEK" \
  --log-file ./proxy.log

npx -p @premai/api-sdk confidential-proxy status
npx -p @premai/api-sdk confidential-proxy stop

start returns only after the proxy answers on its port, so a script can start the daemon and then send requests. It waits up to 30 seconds. If the proxy does not answer, start prints the reason and exits non-zero. Check the --log-file output for details — the daemon reports startup errors there.

The proxy also writes <data-dir>/confidential-proxy.log in every mode. Use --log-level debug to add detail to that file.

| Option | Default | Commands | | --- | --- | --- | | --state-file <path> | <data-dir>/proxy.state.json | start, status, stop | | --log-file <path> | None | start | | --log-level <level> | info | start, foreground | | --shutdown-timeout <ms> | 30000 | start, foreground |

<data-dir> is ~/Library/Application Support/confidential-proxy-nodejs on macOS and ~/.local/share/confidential-proxy-nodejs on Linux. Pass the same --state-file to every command. To run two daemons at the same time, give each one its own --port and --state-file.

--log-level accepts error, warn, info, http, verbose and debug. --shutdown-timeout sets how long the proxy waits for in-flight requests before it closes the listener.

The state file holds a shutdown token, do not move it to a shared location.

See Confidential Proxy for routes, TLS, CORS, Docker, and all CLI options.

Claude Code

confidential-claude starts or reuses the local proxy in Anthropic mode. It lists the enabled models, lets you select one, and launches the installed claude command against the local endpoint.

It needs Claude Code, an interactive terminal, and the same endpoints and keys as above. The launcher reads the Prem API key from API_KEY.

export API_KEY="$PREM_API_KEY"
npx -p @premai/api-sdk confidential-claude

The launcher forwards extra arguments to Claude Code. To stop a proxy that the launcher started, run:

npx -p @premai/api-sdk confidential-proxy stop

The confidential boundary applies only to supported model traffic, after the local proxy encrypts it. Claude Code's repository access, shell commands, MCP servers, hooks, and tool results stay on the local machine or in their own external systems. See the Claude Code guide.

Qwen Code

confidential-qwen does the same for Qwen Code. It starts or reuses the local proxy in Anthropic mode, lists the enabled models, lets you select one, and launches the installed qwen command against the local endpoint.

It needs Qwen Code, an interactive terminal, and the same endpoints and keys as above. The launcher reads the Prem API key from API_KEY.

export API_KEY="$PREM_API_KEY"
npx -p @premai/api-sdk confidential-qwen

The launcher picks the model and the authentication type itself, so it drops --model, -m, and --auth-type from the arguments you pass. It forwards the rest to Qwen Code. Use confidential-proxy stop to stop a proxy that the launcher started.

The confidential boundary works the same way as for Claude Code. Qwen Code's repository access, shell commands, MCP servers, and tool results stay on the local machine or in their own external systems. See the Qwen Code guide.

API surface

The client exposes these primary namespaces:

  • client.chat.completions: encrypted chat completions, including streaming.
  • client.models: models available to the API key.
  • client.audio.transcriptions: encrypted audio transcription.
  • client.audio.translations: encrypted audio translation. Confirm that an enabled model supports translation before you use it.
  • client.files: encrypted file upload, listing, retrieval, indexing, and deletion.
  • client.tools: encrypted tool requests supported by the account and runtime.

Use the public reference for request and response contracts:

Persist file keys

File and RAG operations update client.dekStore. Serialize the store after each write. Restore it when the application starts again:

import {
  deserializeDEKStore,
  serializeDEKStore,
} from "@premai/api-sdk";

const serialized = serializeDEKStore(client.dekStore);
// Store `serialized` in secure application storage.

const dekStore = deserializeDEKStore(serialized);
// Pass `dekStore` to createRvencClient on the next start.

If you lose the KEK or the DEK store, you can no longer use the files that you uploaded before.

Security boundary

  • The TypeScript process or the local proxy encrypts supported inference, audio, file, and tool payloads before they leave the machine. It does not encrypt model discovery or operational metadata.
  • The Prem gateway receives ciphertext and operational metadata. It uses the metadata for authentication, billing, rate limits, routing, and session handling.
  • Attestation is on by default. The client verifies hardware evidence and freshness for supported paths. The attestation reference lists the remaining measurement-policy limits. The SDK accepts attest: false and the proxy accepts --no-attest. Both flags turn off the default gate.
  • A client can still process plaintext before it calls the local proxy. Review the guide for that client before you treat the full workflow as confidential.

Read How it works, Security model, Encryption, and Attestation before you deploy the SDK in a sensitive workflow.

Mobile (React Native)

The SDK runs inside a react-native-bare-kit worklet. See the React Native guide for the worklet setup and the WASM asset path.

Configuration reference

TypeScript client

| Option | Required | Default | Purpose | | --- | --- | --- | --- | | apiKey | Yes | None | Prem API authentication | | clientKEK | Yes unless CLIENT_KEK is set | CLIENT_KEK | Wraps file and RAG data-encryption keys; it is not an API credential | | config.endpoints.proxy | Yes unless PROXY_URL is set | PROXY_URL | Prem gateway endpoint | | config.endpoints.enclave | Yes unless ENCLAVE_URL is set | ENCLAVE_URL | Confidential runtime endpoint | | attest | No | true | Runs the SDK's attestation gate | | requestTimeoutMs | No | 600000 | Request timeout in milliseconds | | maxBufferSize | No | 10485760 | Maximum streaming buffer size in bytes | | dekStore | No | New store | Restores file and RAG key state |

Proxy defaults

| Setting | Default | | --- | --- | | Host | 127.0.0.1 | | Port | 8787 | | Compatibility mode | openai | | JSON body limit | 32mb | | Request shutdown timeout | 30000 ms |

Run confidential-proxy --help to see the options in the installed version.

Guides