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

@scryme/sdk

v10.1.26

Published

The official TypeScript SDK for the **Scryme V3 API**—engineered for scalability, security, type safety, and developer convenience. This SDK provides complete, type-safe coverage of all Scryme V3 services, allowing developers to seamlessly integrate store

Readme

Scryme V3 SDK

The official TypeScript SDK for the Scryme V3 API—engineered for scalability, security, type safety, and developer convenience. This SDK provides complete, type-safe coverage of all Scryme V3 services, allowing developers to seamlessly integrate storefronts, mobile apps, connected applications, and server-side workflows with the Scryme ecosystem.

For the complete, interactive documentation, live sandbox playgrounds, and detailed OpenAPI schemas, please visit our documentation portal: 👉 https://docs.scryme.tech


🚀 Features

  • End-to-End Type Safety: Direct compilation from the core OpenAPI 3.0 specification.
  • Strictly Isolated Client & Server SDKs: Prevents request state and session pollution in multi-tenant environments.
  • Stateful Customer Engine & Auth: Full support for customer registration (signUp), credential sign-in (signIn), proactive/reactive token refresh, active session tracking, multi-session revocation, and reactive React hooks (useSession).
  • Stateful Shopping Cart: Dynamic customerId resolution, automatic line item difference calculations (cart.update), totals metrics, guest-to-customer cart deep-merging (mergeGuestCart), and multi-location checkout.
  • Axios-Based Network Layer: Interceptor-based automatic token exchange, proactive/reactive expiration handling, and multi-tenant orgSlug auto-injection.
  • Comprehensive Domain Coverage:
    • Auth & Customer Engine: Customer login, token refresh, active session management, address directory, and client credentials flow.
    • Catalog & Services: Products, services, CMS customizations, product reviews with auto-resolved customer context, service categories, resources, availability slots, and public OTP booking flows.
    • Orders & Cart: Stateful shopping cart, sales orders, quote requests, B2B quotes, STK push payments, and checkout.
    • Inventory: Stock queries, multi-branch listings, batch tracking (trace, split, merge), B2B availability checks, physical reconciliation, assemblies, and lead time/waste analysis.
    • CRM: Custom CRM record definitions, custom fields, relationships, associations, notes logging, and timeline activities.
    • Loyalty: Loyalty status (tiers & points), voucher validation, customer favorites, and reward redemption.
    • Finance & Accounting: Invoices, corporate expenses, utility account tracking, petty cash funds, Profit & Loss reports, balance sheets, and cash flow analysis.
    • POS: POS device provisioning, standalone POS keys, staff login, terminal sync, and petty cash expense logging.
    • Members & Roles: Staff rosters, custom roles, permission sets, departments, invitations, and attendance logging (check-in/check-out).
    • Integrations & Webhooks: Subscription management, Strapi E-commerce integration, and Windmill workflow callback orchestration.

📦 Installation

Install @scryme/sdk into your project:

pnpm add @scryme/sdk
# or
npm install @scryme/sdk
# or
yarn add @scryme/sdk

🔑 Client & Server SDK Architecture

The SDK provides distinct, fully isolated client-side (@scryme/sdk/client) and server-side (@scryme/sdk/server) constructors to prevent request state and session pollution in multi-tenant environments.


📱 Client-Side Setup (@scryme/sdk/client)

The ScrymeClientSDK provides stateful session persistence (localStorage or custom StorageProvider), reactive auth event listeners, and stateful customer cart operations.

Initialization

import { ScrymeClientSDK, createClientSDK } from "@scryme/sdk/client";

// Class-based constructor
const scrymeClient = new ScrymeClientSDK({
  clientId: "storefront_client_id",
  orgSlug: "my-organization",
  baseURL: "https://api.scryme.tech", // Optional, defaults to https://api.scryme.tech
});

// Or using factory helper
const scrymeClientAlt = createClientSDK({
  clientId: "storefront_client_id",
  orgSlug: "my-organization",
});

👤 Customer Authentication & Session Engine (scrymeClient.customer.auth)

ScrymeClientSDK includes a stateful Customer Authentication engine that manages customer login credentials, local session storage, JWT auto-refresh, active session tracking, and reactive UI hooks.

Customer Registration & Sign-Up (signUp)

Registers a new customer profile. If a password is provided, signUp automatically signs the customer in and initializes an active customer session:

const response = await scrymeClient.customer.auth.signUp({
  name: "Jane Smith",
  email: "[email protected]",
  password: "securepassword123", // Establishes customer login credentials
  phone: "+254700000123",
  company: "Acme Commerce Inc",
  customerType: "B2B_PREMIUM",
  taxId: "PIN-KRA-123456",
  address: {
    label: "Headquarters",
    street1: "123 Commercial Way",
    city: "Nairobi",
    country: "Kenya",
    isDefault: true,
  },
});

console.log("Customer registered:", response.data);

Customer Sign-In (signIn)

Authenticates a customer using email and password, starting an active session in Redis, saving the JWT token to storage, and firing a SIGNED_IN event:

try {
  const authResponse = await scrymeClient.customer.auth.signIn({
    email: "[email protected]",
    password: "securepassword123",
  });

  console.log("Bearer Token:", authResponse.token);
  console.log("Session Metadata:", authResponse.session);
  console.log("Customer Profile:", authResponse.user);
} catch (error) {
  console.error("Login failed:", error);
}

Sign-Out (signOut)

Clears persisted session tokens, resets memory state, and fires a SIGNED_OUT event:

await scrymeClient.customer.auth.signOut();

Session Refresh & Inspection

// Explicitly refresh the current customer session
const freshSession = await scrymeClient.customer.auth.refreshSession();

// Get internal session state synchronously/asynchronously
const sessionState = await scrymeClient.customer.auth.getSession();
console.log("Token:", sessionState.token);
console.log("Active User:", sessionState.user);

// Listen for authentication state changes (SIGNED_IN, SIGNED_OUT, INITIAL_SESSION)
const { unsubscribe } = scrymeClient.customer.auth.onAuthStateChange((event, session) => {
  console.log(`Auth state event: ${event}`, session);
});
// Clean up listener when done
unsubscribe();

Concurrent Session Revocation

Customers can view and destroy active sessions across devices:

// List all active concurrent sessions
const sessions = await scrymeClient.customer.auth.getSessions();
console.log("Active sessions count:", sessions.length);

// Revoke a specific session by ID
await scrymeClient.customer.auth.revokeSession("sess_abc12345");

// Revoke all other sessions except the active one
await scrymeClient.customer.auth.revokeAllSessions("other");

// Revoke all sessions
await scrymeClient.customer.auth.revokeAllSessions();

Reactive React Hook (useSession)

React storefront components can use useSession for immediate, real-time synchronization with customer authentication state:

import React from "react";
import { scrymeClient } from "./scryme";

export function UserProfileHeader() {
  const { data, isPending, error, refetch } = scrymeClient.customer.auth.useSession();

  if (isPending) return <div>Loading customer session...</div>;
  if (error) return <div>Error loading session: {error.message}</div>;
  if (!data?.user) return <div>Welcome, Guest! <button onClick={() => scrymeClient.customer.auth.signIn(...)}>Sign In</button></div>;

  return (
    <div>
      <span>Welcome back, {data.user.name}!</span>
      <button onClick={() => scrymeClient.customer.auth.signOut()}>Sign Out</button>
    </div>
  );
}

👤 Customer Profile & Address Directory (scrymeClient.customer)

Manage the logged-in customer's profile details and address book:

// Fetch current logged-in customer profile
const profile = await scrymeClient.customer.getProfile();
console.log("Profile:", profile);

// Update profile details
const updated = await scrymeClient.customer.updateProfile({
  phone: "+254799999999",
  company: "Acme Holdings Ltd",
});

// Manage saved addresses
const addresses = await scrymeClient.customer.getAddresses();
await scrymeClient.customer.addAddress({
  label: "Office Branch",
  street1: "45 Westlands Rd",
  city: "Nairobi",
  country: "Kenya",
  isDefault: false,
});

🛒 Stateful Shopping Cart Engine (scrymeClient.cart)

The SDK provides a stateful shopping cart submodule with automatic customerId resolution from active customer sessions, line item quantity delta calculation, and guest-to-customer cart deep merging.

Dynamic customerId Resolution

For operations such as cart.add, cart.remove, cart.update, and bookings.create, the SDK automatically resolves customerId from the active user session (user?.customerId || user?.id || user?.customer?.id) if omitted from call arguments. If no authenticated customer session exists and no explicit customerId is passed, operations requiring customer context safely throw an error.

Cart Mutations & Updates

// 1. Fetch current active cart
const cartResponse = await scrymeClient.cart.get({ sessionId: "guest_session_123" });

// 2. Add product variant or service to cart
await scrymeClient.cart.add({
  productId: "prod_sourdough_bread",
  variantId: "var_large_500g",
  quantity: 2,
  sessionId: "guest_session_123", // Optional if customer is signed in
});

// 3. Smart quantity update (computes delta, calls add/remove appropriately)
await scrymeClient.cart.update({
  productId: "prod_sourdough_bread",
  variantId: "var_large_500g",
  quantity: 5, // Automatically increments by +3
});

// 4. Retrieve flat array of cart items
const items = await scrymeClient.cart.getItems();

// 5. Calculate summary metrics and total item count
const totals = await scrymeClient.cart.getTotals();
console.log("Total Items Count:", totals.itemsCount);

Guest-to-Customer Cart Deep-Merging (mergeGuestCart)

When an anonymous guest customer signs in, call mergeGuestCart to aggregate their guest items into their permanent customer cart and clear the guest cart:

// Sign in customer
await scrymeClient.customer.auth.signIn({
  email: "[email protected]",
  password: "password123",
});

// Merge guest cart items into customer cart
const mergedCart = await scrymeClient.cart.mergeGuestCart(
  "guest_session_123", // Guest session ID
  "cust_abc123"        // Target customer ID
);

console.log("Merged Cart Items:", mergedCart.data.items);

Checkout & Sales Order Generation (checkout)

Converts the active shopping cart into an official enterprise Sales Order and deducts inventory at the target location:

const order = await scrymeClient.cart.checkout({
  locationId: "loc_nairobi_main",
  notes: "Deliver before 2 PM",
  channel: "ONLINE_STOREFRONT",
});

console.log("Sales Order Created:", order.id);

🌐 Server-Side Setup (@scryme/sdk/server)

The ScrymeServerSDK strictly isolates requests and Axios instances for multi-tenant server environments (Next.js Server Components, API routes, Windmill workflows, backend services).

Initialization

import { ScrymeServerSDK, createServerSDK } from "@scryme/sdk/server";

const scrymeServer = new ScrymeServerSDK({
  baseURL: "https://api.scryme.tech",
  orgSlug: "my-organization",
  clientId: "your_client_id_123",
  clientSecret: "your_client_secret_456",
});

async function runServerFlow() {
  // Call APIs directly—the SDK handles Client Credentials token exchange and orgSlug auto-injection!
  const products = await scrymeServer.catalog.getProducts({ limit: 10 });
  const customers = await scrymeServer.admin.getCustomers({ limit: 20 });
  console.log("Products count:", products.data.length);
}

🔒 Best Practices & Security

Multi-Tenant Organization Scoping

All domain resources are isolated by organization. The SDK automatically injects the configured orgSlug parameter into all API calls.

Webhook Verification

When receiving webhooks from Scryme, verify payload HMAC signatures to prevent spoofing:

import * as crypto from "crypto";

function verifySignature(
  payload: string,
  signature: string,
  webhookSecret: string
): boolean {
  const hmac = crypto.createHmac("sha256", webhookSecret);
  const expectedSignature = hmac.update(payload).digest("hex");

  // Pre-hash signatures to SHA-256 to guarantee equal length buffers and prevent timing attacks
  const expectedHash = crypto.createHash("sha256").update(expectedSignature).digest();
  const actualHash = crypto.createHash("sha256").update(signature || "").digest();

  return crypto.timingSafeEqual(expectedHash, actualHash);
}

📄 License

This package is licensed under the GNU Affero General Public License version 3 (AGPL-3.0). Please see the LICENSE file for details.