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

@digesty/miniapp-sdk

v0.0.2

Published

Browser SDK for Digesty Mini Apps.

Readme

@digesty/miniapp-sdk

Browser SDK for Digesty Mini Apps.

Use this package when:

  • you want the framework-agnostic Mini App client
  • you need embedded bootstrap, direct launch, callback exchange, or session restore
  • you want to build your own framework adapter on top

Install

pnpm add @digesty/miniapp-sdk

Quick Start

import { createMiniAppClient } from "@digesty/miniapp-sdk";

const client = createMiniAppClient({
  appID: "your-app-id",
});

await client.initEmbedded();

Minimal direct-launch example:

import { createMiniAppClient } from "@digesty/miniapp-sdk";

const client = createMiniAppClient({
  appID: "your-app-id",
});

if (window.location.search.includes("launch_code=")) {
  await client.handleCallback();
} else if (!client.restoreSession()) {
  await client.startDirectLaunch();
}

Config

type MiniAppClientConfig = {
  appID: string;
  apiURL?: string;
  digestyOrigin?: string;
  getLaunchURL?: (args: {
    appID: string;
    codeChallenge: string;
    digestyOrigin: string;
  }) => string;
  storage?: StorageAdapter;
  autoRefresh?: boolean;
};

Defaults:

  • apiURL defaults to "https://worker.digesty.vn"
  • digestyOrigin defaults to "https://digesty.vn"
  • autoRefresh defaults to false
  • getLaunchURL defaults to ${digestyOrigin}/apps/${appID}/launch?code_challenge=...

Most apps can start with:

const client = createMiniAppClient({
  appID: "your-app-id",
});

Use staging explicitly:

const client = createMiniAppClient({
  appID: "your-app-id",
  digestyOrigin: "https://staging.digesty.vn",
});

Use local dev explicitly:

const client = createMiniAppClient({
  appID: "app_local_sdk_test",
  apiURL: "http://localhost:8787",
  digestyOrigin: "http://localhost:3000",
});

Use getLaunchURL only when the Digesty launch route differs from the default:

const client = createMiniAppClient({
  appID: "your-app-id",
  getLaunchURL: ({ appID, codeChallenge, digestyOrigin }) =>
    `${digestyOrigin}/miniapps/${appID}/consent?code_challenge=${encodeURIComponent(codeChallenge)}`,
});

Main Methods

  • initEmbedded(): consume #digesty_launch_token and complete embedded bootstrap
  • requestRefresh(): request a fresh embedded token from the parent Digesty window
  • startDirectLaunch(): begin the direct consent flow
  • handleCallback(): exchange ?launch_code=... for a launch token
  • restoreSession(): restore the last direct-launch session from storage
  • clearSession(): clear stored direct-launch session
  • subscribe(listener): observe MiniAppState
  • onTokenUpdate(listener): observe successful token changes

Flows

Embedded

Use this when your app is running inside a Digesty iframe.

await client.initEmbedded();

The SDK reads digesty_launch_token from the URL hash, validates the payload shape, then uses postMessage with digestyOrigin for handshake and refresh.

Direct

Use this when your app runs as a top-level site.

await client.startDirectLaunch();

Digesty redirects back with launch_code in the query string. Then:

await client.handleCallback();

The SDK exchanges the code against:

POST {apiURL}/api/v2/app-auth/apps/{appID}/launch/exchange

Security Model

This SDK does not verify JWT signatures in the browser. It only parses the token payload shape for UI state.

That means:

  • browser state.claims is fine for rendering
  • backend authorization must not trust those claims unless the token was verified server-side
  • if your backend receives a launch token, verify it against Digesty JWKS first

Backend Verification With JWKS

Backends should verify Digesty launch tokens against:

GET {apiURL}/api/v2/app-auth/jwks

With the default config, that is:

https://worker.digesty.vn/api/v2/app-auth/jwks

Minimum checks:

  • verify the EdDSA signature using the matching kid from the JWKS
  • verify iss === "digesty.ai"
  • verify aud === "app:{appID}"
  • verify app_id === appID
  • verify mode if your endpoint expects only "embed" or only "direct"
  • verify exp and iat according to your JWT library

Current launch token payload shape:

type LaunchTokenPayload = {
  iss: "digesty.ai";
  aud: string;
  sub: string;
  iat: number;
  exp: number;
  jti: string;
  app_id: string;
  mode: "embed" | "direct";
  scopes: string[];
  email?: string;
  email_verified?: boolean;
  name?: string;
  picture?: string;
};

Important notes:

  • sub is a pairwise Digesty subject scoped to the app, not the global Digesty user ID
  • direct launch redirects carry launch_code, not the final token
  • launch code exchange still happens over HTTPS, but server-side JWT verification is the right contract if your backend consumes the resulting token

Server-Managed Direct Callback

The SDK implements the browser-managed direct callback flow. PKCE verifier state lives in browser storage, and handleCallback() exchanges the code in the browser.

If your architecture wants the backend to own the callback instead:

  • let your backend receive launch_code
  • let your backend perform the exchange with Digesty
  • let your backend create its own session
  • set a Secure, HttpOnly cookie
  • redirect the browser to a clean app URL

That is a valid architecture, but it is not implemented by this SDK today.