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

@unisat/alkanes-lib

v0.4.0

Published

Minimal Alkanes utilities (varint encipher/decipher) extracted for UniSat projects

Readme

@unisat/alkanes-lib

@unisat/alkanes-lib is a minimal TypeScript library for Alkanes protocol utilities, focused on Runes/Runestone encoding and decoding. It is a subset of the original alkanes project, extracted for use across UniSat projects.

Install

pnpm add @unisat/alkanes-lib

Commands

# Build (outputs CJS + ESM + types to lib/)
pnpm build

# Watch mode
pnpm dev

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Type check without emitting
pnpm typecheck

# Lint
pnpm lint

# Clean output
pnpm clean

Build tool is tsup (wraps esbuild). Output goes to lib/ with both index.js (CJS) and index.mjs (ESM) plus index.d.ts.

Protorune Compatibility

alkanes-lib now includes a local protorune compatibility layer for the upstream Alkanes encoder flow, without depending on @magiceden-oss/runestone-lib.

import {
  ProtoStone,
  ProtoruneRuneId,
  RunestoneProtostoneUpgrade,
  encodeRunestoneProtostone,
} from '@unisat/alkanes-lib'

const mint = new ProtoruneRuneId(840000n, 1n)
const protostone = ProtoStone.message({
  protocolTag: 1n,
  calldata: Buffer.from('01', 'hex'),
  pointer: 2,
  refundPointer: 1,
})

const script = encodeRunestoneProtostone({
  mint,
  pointer: 3,
  protostones: [protostone],
}).encodedRunestone

const sameScript = new RunestoneProtostoneUpgrade(mint, 3, [], undefined, [protostone]).encipher()

Supported compatibility names in this layer are:

  • ProtoruneRuneId
  • ProtoruneEdict
  • RunestoneProtostoneUpgrade
  • existing ProtoStone and encodeRunestoneProtostone

Architecture

Entry Points

  • src/index.ts — re-exports everything from ./bytes and ./runes
  • src/bytes.ts — low-level varint encode/decode primitives using SeekBuffer
  • src/seekbuffer.ts — cursor-based buffer reader used by bytes.ts
  • src/runes/ — all Runes/Runestone domain types

Core Abstractions (src/runes/)

| File | Purpose | | -------------- | ----------------------------------------------------------------------------- | | runestone.ts | Main Runestone class — encipher/decipher Runes OP_RETURN scripts | | tag.ts | Tag and ProtoTag enums with encode/take helpers | | message.ts | Parses integer arrays into field maps and edicts | | varint.ts | JS varint codec (encode, decode, encodeToVec) — plain JS, no TypeScript | | alkane.ts | ProtocolData — Alkanes-specific payload (pointer, refund, calldata, edicts) | | protocol.ts | Protocol — wraps a protocolTag + ProtocolData | | edict.ts | Edict — transfer instruction (id, amount, output) | | etching.ts | Etching — rune creation parameters | | rune_id.ts | RuneId — (block, tx) identifier with delta encoding | | cenotaph.ts | Cenotaph — flawed runestone result | | flag.ts | Flag and RunesFlag — bitmask flag management | | flaw.ts | Flaw — error bitmask constants |

Key Data Flow

Decoding (OP_RETURN to structured data):

payloadFromScript() -> strip OP_RETURN + magic byte 0x5d -> decipherBufferPayload()
integers() -> varint.decode loop -> bigint[]
Message.fromIntegers() -> field map + edicts
Tag.X.take() -> extract typed fields -> Runestone | Cenotaph

Encoding (structured data to OP_RETURN payload):

Runestone.encipher() -> Tag.X.encode() -> push tag/value pairs as varints
varint.encodeToVec() -> LEB128 bigint encoding -> payload hex (without OP_RETURN prefix)

Alkanes (Protocol Extension)

Alkanes extends Runes via Tag.Protocol (tag 16383). The protocol field packs a list of sub-protocols, each with:

  • protocolTag (bigint)
  • ProtocolData: pointer, refund, calldata (bigint[]), edicts

The pack() function in runestone.ts converts bigint arrays to 15-byte little-endian chunks before deciphering.

Varint Note

src/runes/varint.ts is plain JavaScript (not TypeScript). It exports an encodeWrong function that is kept for reference but should not be used. The correct encoder is encodeToVec.

Dependencies

  • @unisat/wallet-bitcoin provides bitcoin (the bitcoinjs-lib wrapper) used in Runestone.payload() and script parsing.

  • @unisat/wallet-types provides shared types.

Testing

Uses Vitest. Tests live in test/. Run a single test file:

pnpm vitest run test/runes/runestone.test.ts