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

@sundaeswap/sprinkles

v0.5.0

Published

A TypeScript library for building interactive CLI menus and TUI applications with TypeBox schema validation

Readme

Sprinkles

Note: This is an early release (v0.x). The API may change between minor versions as we refine the library based on community feedback.

A TypeScript library for building interactive CLI menus and TUI applications with TypeBox schema validation. Sprinkles provides a declarative way to create nested menus, handle user input, and manage persistent settings with type safety.

Features

  • Schema-driven UI: Define your data structures using TypeBox schemas, and Sprinkles automatically generates interactive prompts
  • Nested menu support: Create hierarchical menu structures with submenus
  • Persistent settings: Automatic JSON-based settings storage with BigInt support
  • Type-safe: Full TypeScript support with type inference from schemas
  • Cardano integration: Built-in helpers for Blaze SDK wallet and provider management
  • Transaction dialogs: Ready-to-use transaction signing and submission flows

Installation

npm install @sundaeswap/sprinkles

Quick Start

import { Sprinkle, Type } from "sprinkles";

// Define your settings schema
const AppSettingsSchema = Type.Object({
  username: Type.String({ title: "Username" }),
  theme: Type.Union([
    Type.Literal("dark"),
    Type.Literal("light")
  ])
});

// Create a Sprinkle instance
const app = await Sprinkle.New(AppSettingsSchema, "./config");

// Define your menu
const mainMenu = {
  title: "Main Menu",
  items: [
    {
      title: "Say Hello",
      action: async (sprinkle) => {
        console.log(`Hello, ${sprinkle.settings.username}!`);
      }
    }
  ]
};

// Show the menu
await app.showMenu(mainMenu);

API Reference

Core Classes

Sprinkle<S extends TSchema>

The main class for managing your CLI application.

Constructor
constructor(type: S, storagePath: string)
Static Methods
  • Sprinkle.New<S>(type: S, storagePath: string): Promise<Sprinkle<S>> - Create and initialize a new Sprinkle instance
  • Sprinkle.GetProvider(network, settings): Provider - Create a Cardano provider instance
  • Sprinkle.GetWallet(settings, provider): Promise<Wallet> - Create a Cardano wallet instance
  • Sprinkle.GetBlaze(network, providerSettings, walletSettings): Promise<Blaze> - Create a Blaze SDK instance
  • Sprinkle.SettingsPath(storagePath: string): string - Get the settings file path
Instance Methods
  • showMenu(menu: IMenu<S>): Promise<void> - Display a menu and handle user interactions
  • EditStruct<U>(type: U, current: TExact<U>): Promise<TExact<U>> - Interactive editor for schema-based structures
  • FillInStruct<U>(type: U, def?: TExact<U>): Promise<TExact<U>> - Interactive form to fill in a structure
  • TxDialog(blaze, tx): Promise<void> - Display transaction dialog with sign/submit options
  • saveSettings(): void - Persist current settings to disk
  • LoadSettings(type, storagePath): Promise<void> - Load settings from disk

Types

IMenu<S>

Defines a menu structure:

interface IMenu<S extends TSchema> {
  title: string;
  items: TMenuItem<S>[];
}

IMenuAction<S>

Defines a menu action:

interface IMenuAction<S extends TSchema> {
  title: string;
  action: (sprinkle: Sprinkle<S>) => Promise<Sprinkle<S> | void>;
}

TMenuItem<S>

A menu item can be either an action or a submenu:

type TMenuItem<S extends TSchema> = IMenuAction<S> | IMenu<S>;

Built-in Schemas

NetworkSchema

Cardano network selection:

Type.Union([
  Type.Literal("mainnet"),
  Type.Literal("preview"),
  Type.Literal("preprod")
])

ProviderSettingsSchema

Cardano provider configuration:

Type.Union([
  Type.Object({
    type: Type.Literal("blockfrost"),
    projectId: Type.String({ minLength: 1, title: "Blockfrost Project ID" })
  }),
  Type.Object({
    type: Type.Literal("maestro"),
    apiKey: Type.String({ minLength: 1, title: "Maestro API Key" })
  })
])

WalletSettingsSchema

Cardano wallet configuration:

Type.Union([
  Type.Object({
    type: Type.Literal("hot"),
    privateKey: Type.String({ minLength: 1, title: "Hot Wallet Private Key" })
  }),
  Type.Object({
    type: Type.Literal("cold"),
    address: Type.String({ minLength: 1, title: "Cold Wallet Address" })
  })
])

MultisigScript

Cardano multisig script schema with support for:

  • Signature verification
  • AllOf (all signatures required)
  • AnyOf (any signature works)
  • AtLeast (m-of-n threshold)
  • Before/After (time-based conditions)
  • Script hash references

Advanced Usage

Creating Nested Menus

const menu = {
  title: "Main Menu",
  items: [
    {
      title: "User Management",
      items: [
        {
          title: "Add User",
          action: async (sprinkle) => {
            // Add user logic
          }
        },
        {
          title: "Remove User",
          action: async (sprinkle) => {
            // Remove user logic
          }
        }
      ]
    }
  ]
};

Modifying Settings from Actions

{
  title: "Change Username",
  action: async (sprinkle) => {
    const newSettings = await sprinkle.EditStruct(
      Type.Object({ username: Type.String() }),
      { username: sprinkle.settings.username }
    );
    return new Sprinkle(sprinkle.type, sprinkle.storagePath);
  }
}

Working with Cardano Transactions

const blaze = await Sprinkle.GetBlaze(
  "preprod",
  providerSettings,
  walletSettings
);

// Build your transaction
const tx = await blaze
  .newTransaction()
  .payLovelace(recipientAddress, 5_000_000n)
  .complete();

// Show transaction dialog
await app.TxDialog(blaze, tx);

Settings Persistence

Settings are automatically saved to {storagePath}/settings.json. The file format includes:

{
  "settings": {
    "username": "alice",
    "count": "42n"
  },
  "defaults": {
    "string": "last_entered_value"
  }
}

Note: BigInt values are serialized with an 'n' suffix and automatically parsed on load.

License

MIT