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

@turnstilealgo/core

v0.1.1

Published

**The shared vocabulary of Turnstile's Algorand batch-settlement scheme.** Pure, dependency-light primitives with no chain I/O and no HTTP: address codec, ed25519 voucher signing/verification, channel-id and voucher-message encoding (byte-for-byte identic

Readme

@turnstilealgo/core

The shared vocabulary of Turnstile's Algorand batch-settlement scheme. Pure, dependency-light primitives with no chain I/O and no HTTP: address codec, ed25519 voucher signing/verification, channel-id and voucher-message encoding (byte-for-byte identical to the on-chain contract's own encoding), the wire types every other package passes over HTTP, and CAIP-2 network-id helpers.

npm install @turnstilealgo/core

Safe to import from a browser, a CLI, a server, or a test file — nothing in this package touches a network, a filesystem, or the clock.

Why it's separate

The client, server, and facilitator schemes in @turnstilealgo/x402-avm-batch all need to construct the exact same channel-id and voucher-message bytes the on-chain contract verifies with ed25519verify_bare. Getting that encoding wrong in even one byte means signatures silently fail to verify on-chain while looking fine in TypeScript. Centralizing it here — with golden test vectors checked against the contract's own emulator tests — is what makes "TS↔contract signature parity" a real, continuously-verified property instead of an assumption.

Quickstart

import { newSessionKey, signVoucher, channelId, encodeAddress, toB64, type ChannelConfig, type Deployment } from '@turnstilealgo/core';

// A session key is the "hot" key that signs a voucher on every request --
// see the security model in the top-level README for why it's never the
// same key that holds funds.
const session = await newSessionKey(); // { sk, pk }

const config: ChannelConfig = {
  payer, payerAuthorizer: encodeAddress(session.pk),
  receiver, receiverAuthorizer,
  asset: assetId.toString(),
  withdrawDelay: 900, // seconds
  salt: toB64(crypto.getRandomValues(new Uint8Array(32))),
};
const deployment: Deployment = { genesisHash, appId };

const cid = channelId(config, deployment);
const signature = await signVoucher(session.sk, deployment, cid, maxClaimable);

API reference

| Module | Exports | |---|---| | address | encodeAddress(publicKey), decodeAddress(algorandAddress) — Algorand's checksummed base32 address format | | bytes | u64be, concat, toHex/fromHex, toB64/fromB64, eq — the byte-level building blocks every encoder above uses | | config | ChannelConfig, Deployment interfaces; encodeConfig(config) (ARC-4 struct encoding); channelId(config, deployment) | | voucher | voucherMessage(deployment, channelId, maxClaimable), signVoucher(secretKey, ...), verifyVoucher(publicKey, ...), newSessionKey(), publicKeyOf(secretKey) | | constants | SCHEME, VOUCHER_PREFIX/CHANNEL_PREFIX (domain-separation bytes, must match contract.py byte-for-byte), CAIP2 (MainNet/TestNet ids), GENESIS_HASH_B64, USDC_ASA_ID, WITHDRAW_DELAY_MIN/MAX, caip2FromGenesisHash(hash) | | wire | HTTP wire types (ChannelConfigWire, VoucherWire, AvmBatchPayload, ChannelStateWire, SettlementResponseAvmBatch), converters (configToWire/configFromWire/channelIdFromWire), type guards (isDepositPayload/isVoucherPayload/isRefundPayload), and ERR — every stable error code this scheme can return |

Encoding this package implements

  • channelId = sha256("x402-avm-bs-channel-v1" ‖ genesisHash(32) ‖ itob(appId) ‖ arc4(config))
  • Voucher message (102 bytes): "x402-avm-bs-voucher-v1" ‖ genesisHash(32) ‖ itob(appId) ‖ channelId(32) ‖ itob(maxClaimable)
  • Signatures are raw ed25519 over that message — the contract checks them with ed25519verify_bare, not ed25519verify (which prepends ProgData + a program hash; using the wrong opcode is a classic AVM pitfall this package's tests exist partly to catch).

Full byte layout and field-by-field rationale: docs/spec/scheme_batch_settlement_avm.md.

Testing

pnpm -F @turnstilealgo/core test

11 tests, including round-trip encode/decode, cross-checking channelId/voucherMessage output against test/vectors.json — the same golden vectors the Python contract's offline test suite checks against, so a change here that silently breaks on-chain compatibility fails in CI on both sides, not just one.