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

@yusufolosun/stx-utils

v2.0.2

Published

Lightweight, zero-dependency utilities for Stacks (STX) dApp development — formatting, validation, addresses, Clarity decoding, PoX stacking, memos, and more.

Readme

@yusufolosun/stx-utils

npm version license tests zero deps

Lightweight, zero-dependency utilities for Stacks (STX) dApp development.

  • 10 modules — formatting, addresses, blocks, validation, errors, time, explorer, Clarity decoder, memos, and PoX stacking
  • Dual format — ESM + CommonJS with full TypeScript declarations
  • Tree-shakeable — import only what you need
  • 259 tests — comprehensive coverage including edge cases

Install

# npm
npm install @yusufolosun/stx-utils

# yarn
yarn add @yusufolosun/stx-utils

# pnpm
pnpm add @yusufolosun/stx-utils

Modules

| Module | Description | |---|---| | Formatting | Convert between STX / microSTX, compact display (K/M/B) | | Address | Validate, shorten, and parse Stacks principals | | Blocks | Estimate durations from block counts, "time ago" helpers | | Validation | Validate names, stake amounts, and principals | | Errors | Decode Clarity error codes into human-readable messages | | Time | Format dates and relative timestamps | | Explorer | Build Hiro explorer URLs for txs, addresses, contracts, blocks | | Clarity | Decode hex-encoded Clarity values (SIP-005) into JS objects | | Memo | Encode/decode 34-byte STX transfer memos | | Stacking | PoX reward cycle calculations and progress tracking |

Quick Start

import {
  formatSTX,
  toMicroSTX,
  formatSTXCompact,
  shortenAddress,
  isValidAddress,
  blocksToTime,
  blocksAgo,
  validateStake,
  decodeError,
  txUrl,
  blockUrl,
  apiUrl,
  decodeClarityValue,
  encodeMemo,
  blockToCycle,
} from '@yusufolosun/stx-utils';

// STX formatting
formatSTX(1_500_000);            // "1.50"
toMicroSTX(2.5);                 // 2_500_000
formatSTXCompact(1_500_000_000); // "1.5K STX"

// Addresses
shortenAddress('SP1N3809W9CBWWX04KN3TCQHP8A9GN520BD4JMP8Z');
// → "SP1M46...G193"
isValidAddress('SP1N3809W9CBWWX04KN3TCQHP8A9GN520BD4JMP8Z'); // true

// Block time
blocksToTime(144);   // "1 day"
blocksAgo(1000, 994); // "~1h ago"

// Validation
validateStake(0.5);  // null (valid)
validateStake(0.01); // "Minimum stake is 0.02 STX"

// Error decoding
decodeError(105);    // "Already checked in today"

// Explorer URLs
txUrl('0xabc123');   // "https://explorer.hiro.so/txid/0xabc123?chain=mainnet"
txUrl('deadbeef');   // auto-prepends 0x
blockUrl('0xabc', 'testnet');
apiUrl('mainnet');   // "https://stacks-node-api.mainnet.stacks.co"

// Clarity value decoding
const cv = decodeClarityValue('0x0100000000000000000000000000000064');
// → { type: 'uint', value: 100n }

// Memo encoding
const memo = encodeMemo('Hello Stacks');
// → Uint8Array(34) [ 72, 101, 108, ... 0, 0 ]

// PoX stacking
blockToCycle(670000); // → 1 (reward cycle number)

Runtime validation behavior

  • validatePrincipal(value) returns:
    • null for valid standard principals (SP... / ST...) and valid contract principals (SP....contract-name)
    • "Invalid contract name" for malformed contract principals (including multiple dots)
    • "Invalid Stacks address" for malformed standard principals
  • parseContractPrincipal(value) returns null unless input is a strict address.contract-name with one dot and a valid contract name (^[a-zA-Z][\\w-]{0,127}$).
  • memoFromHex(hex) throws:
    • RangeError when length is not 68 hex characters (34 bytes)
    • Error when any character is outside [0-9a-fA-F]

API Reference

Formatting

| Function | Description | |---|---| | formatSTX(microSTX, decimals?) | Convert microSTX to display string | | toMicroSTX(stx) | Convert STX to microSTX | | toSTX(microSTX) | Convert microSTX to numeric STX | | formatSTXWithUnit(microSTX) | Format with automatic unit suffix (uSTX or STX) | | formatSTXCompact(microSTX) | Compact format with K/M/B suffixes | | MICRO_PER_STX | Constant: 1_000_000 |

Address

| Function | Description | |---|---| | isValidAddress(address) | Check standard principal validity | | isContractPrincipal(address) | Check contract principal validity | | getAddressNetwork(address) | Returns "mainnet", "testnet", or null | | shortenAddress(address, startChars?, endChars?) | Truncate for display | | parseContractPrincipal(principal) | Extract [address, name] from strict address.contract-name input |

Blocks

| Function | Description | |---|---| | blocksToTime(blocks) | Human-readable duration from block count | | blocksToSeconds(blocks) | Convert blocks to seconds | | secondsToBlocks(seconds) | Convert seconds to blocks | | blocksAgo(currentBlock, targetBlock) | Relative block time string | | estimateBlockDate(targetBlock, currentBlock, now?) | Estimated Date object | | SECONDS_PER_BLOCK | Constant: 600 | | BLOCKS_PER_DAY | Constant: 144 |

Validation

| Function | Description | |---|---| | validateName(name, maxLength?) | Validate a Clarity string input | | validateStake(stx, minMicroSTX?) | Validate stake amount (rejects NaN, Infinity) | | validatePrincipal(principal) | Validate standard or contract principal | | DEFAULT_MIN_STAKE | Constant: 20_000 (0.02 STX in microSTX) | | DEFAULT_MAX_NAME_LENGTH | Constant: 50 |

Errors

| Function | Description | |---|---| | decodeError(code) | Look up a Clarity error code | | registerErrors(errors) | Add or override error codes | | getErrorRegistry() | Get snapshot of all registered codes |

Time

| Function | Description | |---|---| | formatDate(timestamp, locale?) | Format a UNIX timestamp | | timeAgo(timestamp) | Relative time string |

Explorer

| Function | Description | |---|---| | txUrl(txId, network?) | Transaction explorer link (auto-prepends 0x) | | addressUrl(address, network?) | Address explorer link | | contractUrl(principal, network?) | Contract explorer link | | blockUrl(blockHash, network?) | Block explorer link | | apiUrl(network?) | Stacks node API base URL |

Clarity

| Function | Description | |---|---| | decodeClarityValue(hex) | Decode hex-encoded Clarity value to typed JS object | | unwrapResponse(cv) | Unwrap an ok response or throw on err | | extractValue(cv) | Recursively extract plain JS values from Clarity types |

Supported types: int, uint, bool, buffer, string-ascii, string-utf8, none, some, ok, err, list, tuple, principal.

Memo

| Function | Description | |---|---| | encodeMemo(text) | Encode UTF-8 string to 34-byte memo buffer | | decodeMemo(bytes) | Decode 34-byte memo buffer to string | | memoToHex(text) | Encode memo and return hex string | | memoFromHex(hex) | Decode hex memo to string (throws on invalid length or non-hex chars) | | MEMO_MAX_BYTES | Constant: 34 |

Stacking (PoX)

| Function | Description | |---|---| | blockToCycle(burnBlockHeight, startHeight?, cycleLength?) | Get cycle number from block height | | cycleToBlock(cycle, startHeight?, cycleLength?) | Get first block of a cycle | | cycleProgress(burnBlockHeight, startHeight?, cycleLength?) | Blocks into cycle + progress ratio | | blocksUntilNextCycle(burnBlockHeight, startHeight?, cycleLength?) | Blocks remaining in current cycle | | isInPreparePhase(burnBlockHeight, startHeight?, cycleLength?, prepareLength?) | Whether block is in prepare phase | | BLOCKS_PER_CYCLE | Constant: 2100 | | POX_START_HEIGHT | Constant: 666050 |

License

MIT