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

@ows-sdk/kms-client

v1.0.0

Published

Lightweight API key verification client for Opendex KMS. Protects any SDK with a single line of code.

Readme

@ows-sdk/kms-client

API Key Verification for Opendex SDKs

npm TypeScript License Bundle Size

Zero-dependency client to protect any Opendex SDK with API key verification.


Install

npm install @ows-sdk/kms-client
pnpm add @ows-sdk/kms-client
yarn add @ows-sdk/kms-client

Quick Start

Option 1: Guard (recommended for SDKs)

The simplest way to protect your SDK. Two lines: init() to verify, requireInit() to enforce.

import { createGuard, KMSError } from '@ows-sdk/kms-client';

class MySDK {
  private guard = createGuard(apiKey, {
    sdkName: 'my-awesome-sdk',
    sdkVersion: '1.0.0',
  });

  async init() {
    await this.guard.init(); // Verifies API key against KMS
  }

  doSomething() {
    this.guard.requireInit(); // Throws if not verified
    // ... your SDK logic here
  }

  async doSomethingAsync() {
    this.guard.requireInit();
    // ... your async SDK logic here
  }
}

Option 2: Client (for custom flows)

Full control over when and how verification happens.

import { KMSClient, KMSError } from '@ows-sdk/kms-client';

const kms = new KMSClient({
  sdkName: 'my-sdk',
  sdkVersion: '2.0.0',
});

// Verify with full details
const result = await kms.verify('kms_abc123...');
console.log(result.scopes);      // ['verify', 'read']
console.log(result.environment); // 'production'
console.log(result.keyId);       // 'key_xxx'

// Simple boolean check (no throw)
const valid = await kms.isValid('kms_abc123...');

End User's Code

This is what your SDK users write:

import { MySDK } from 'my-awesome-sdk';

const sdk = new MySDK({ apiKey: 'kms_abc123...' });

try {
  await sdk.init();
  sdk.doSomething(); // Works — key is verified
} catch (error) {
  if (error instanceof KMSError) {
    console.error(`[${error.code}] ${error.userMessage}`);
  }
}

Full SDK Example

Here's a complete example of how to integrate @ows-sdk/kms-client into an SDK:

// my-sdk/src/index.ts

import { createGuard, KMSError, type KMSVerification } from '@ows-sdk/kms-client';

export interface MySDKOptions {
  apiKey: string;
  region?: string;
}

export class MySDK {
  private guard;

  constructor(options: MySDKOptions) {
    this.guard = createGuard(options.apiKey, {
      sdkName: 'my-sdk',
      sdkVersion: '1.0.0',
      requiredScope: 'verify', // Key must have 'verify' scope
    });
  }

  /**
   * Initialize the SDK. Must be called before any other method.
   */
  async init(): Promise<void> {
    await this.guard.init();
  }

  /**
   * Check if the SDK is ready to use.
   */
  get isReady(): boolean {
    return this.guard.isVerified;
  }

  /**
   * Get the verified key details.
   */
  get keyInfo(): KMSVerification | null {
    return this.guard.verification;
  }

  /**
   * Your SDK methods — all protected by requireInit()
   */
  async doSomething(): Promise<string> {
    const key = this.guard.requireInit();
    // key.scopes, key.environment, key.projectId are available
    return `Hello from ${key.environment}!`;
  }
}

// Re-export for user convenience
export { KMSError } from '@ows-sdk/kms-client';

API Reference

KMSClient

const client = new KMSClient(options?: KMSClientOptions);

| Option | Type | Default | Description | |--------|------|---------|-------------| | endpoint | string | https://kms.opendexapis.com | KMS API URL | | timeout | number | 5000 | Request timeout (ms) | | retries | number | 2 | Retry attempts on network errors | | retryDelay | number | 500 | Base retry delay (ms, doubles each retry) | | sdkName | string | 'unknown-sdk' | Your SDK name (for analytics) | | sdkVersion | string | '0.0.0' | Your SDK version | | cache | boolean | true | Cache verification results in memory | | cacheTtl | number | 300000 | Cache TTL (ms, default 5 min) |

Methods:

| Method | Returns | Description | |--------|---------|-------------| | verify(apiKey, scope?) | Promise<KMSVerification> | Verify key (throws on invalid) | | isValid(apiKey, scope?) | Promise<boolean> | Check validity (no throw) | | clearCache() | void | Clear cached verifications |

createGuard()

const guard = createGuard(apiKey: string, options?: KMSGuardOptions);

Extends KMSClientOptions with:

| Option | Type | Description | |--------|------|-------------| | requiredScope | string | Scope the key must have |

Properties & Methods:

| Member | Type | Description | |--------|------|-------------| | verification | KMSVerification \| null | Cached result | | isVerified | boolean | Whether init() has been called successfully | | init() | Promise<KMSVerification> | Verify the key (safe to call multiple times) | | requireInit() | KMSVerification | Assert initialized (throws if not) |

KMSVerification

interface KMSVerification {
  valid: true;
  keyId: string;        // 'key_abc123'
  projectId: string;    // 'proj_xyz789'
  name: string;         // 'Production Key'
  scopes: string[];     // ['verify', 'read']
  environment: string;  // 'production'
  rateLimit?: {
    remaining: number;
    reset: number;
    limit: number;
  };
}

Error Classes

import {
  KMSError,            // Base error (has .code and .userMessage)
  KMSValidationError,  // Invalid key (non-retryable)
  KMSNetworkError,     // Network failure (retryable)
  KMSTimeoutError,     // Timeout (retryable)
} from '@ows-sdk/kms-client';

| Error | Codes | Retryable | |-------|-------|-----------| | KMSValidationError | INVALID_FORMAT, NOT_FOUND, DISABLED, EXPIRED, SCOPE_DENIED, IP_BLOCKED, ROTATION_REQUIRED | No | | KMSNetworkError | NETWORK_ERROR | Yes | | KMSTimeoutError | TIMEOUT | Yes | | KMSError | RATE_LIMITED, UNKNOWN | Yes |

Error Handling

import { KMSError, KMSValidationError, KMSTimeoutError } from '@ows-sdk/kms-client';

try {
  await sdk.init();
} catch (error) {
  if (error instanceof KMSValidationError) {
    // Key is definitely invalid — show error.userMessage to user
    console.error(error.userMessage);
    // error.code: 'EXPIRED', 'NOT_FOUND', 'DISABLED', etc.
  } else if (error instanceof KMSTimeoutError) {
    // Network issue — maybe retry later
    console.warn('KMS is unreachable, retrying...');
  } else if (error instanceof KMSError) {
    // Other KMS error (rate limited, unknown)
    console.error(`KMS [${error.code}]: ${error.userMessage}`);
  }
}

Compatibility

  • Node.js 18+ (uses native fetch)
  • Bun — fully supported
  • Deno — fully supported
  • Browsers — works in modern browsers (uses fetch + AbortController)
  • Cloudflare Workers — works in Workers/Pages
  • Edge runtimes — any runtime with fetch support

License

MIT © Opendex, Inc.