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

xno-skills

v0.9.0

Published

XNO CLI - Interact with the Nano cryptocurrency

Downloads

1,067

Readme

xno-skills

npm version License: MIT TypeScript

A TypeScript library, executable, and MCP server, for interacting with the Nano (XNO) cryptocurrency. Generate wallets, convert units, validate addresses, and more.

xno-skills CLI preview

AI Skills

This repository includes built-in skills for AI agents (Claude Code, Cursor, etc.). To install them:

npx skills add CasualSecurityInc/xno-skills

Available skills:

  • create-wallet: Wallet creation/import guidance (BIP39 default; legacy supported; safe --stdin workflows).
  • convert-units: High-precision unit conversion reference.
  • generate-qr: Terminal-friendly Nano payment QR codes (address + optional amount).
  • validate-address: Address format and checksum verification guide.
  • check-balance: Check balance/pending via Nano node RPC.
  • mcp-wallet: Use xno-mcp as a private “wallet” custody blackbox (addresses only; no seed leakage).
  • request-payment: Request XNO from operator (payment request workflow with tracking, QR, receive, report).
  • return-funds: Return XNO to sender (source attribution, ambiguity guards, safe refund).

MCP Server

This package includes a built-in Model Context Protocol (MCP) server that exposes Nano wallet functions as native tools for AI agents (like Claude Desktop or Cursor).

To use it, add the following to your MCP client configuration:

{
  "mcpServers": {
    "xno": {
      "command": "npx",
      "args": ["-y", "-p", "xno-skills@latest", "xno-mcp"]
    }
  }
}

Exposed tools:

  • wallet_create / wallet_list / wallet_addresses: Named “wallets” (custody inside MCP; return addresses only).
  • wallet_balance / wallet_probe_balances: Balance/pending checks for wallet accounts via RPC.
  • wallet_receive / wallet_send: Receive pending blocks and send funds (sign + work + process via RPC).
  • config_get / config_set: Store defaults (RPC URL, work URL, timeouts, default representative; optional wallet persistence).
  • wallet_set_allowance / wallet_get_allowance: Spending limits per wallet (per-tx cap, window budget, destination whitelist).
  • wallet_history: Persistent transaction log (sends, receives, linked payment requests).
  • payment_request_create / payment_request_status / payment_request_receive / payment_request_list: Payment request lifecycle.
  • payment_request_refund: Safe refund with source attribution and ambiguity guards.
  • generate_qr: Generate QR codes for Nano addresses/payment URIs.
  • generate_wallet: Generate a wallet (default: BIP39 derivation).
  • derive_address: Derive an address (supports bip39 + legacy, with auto preference).
  • probe_mnemonic: Probe both derivations via RPC (helps resolve 24-word ambiguity).
  • convert_units: Converts between XNO and raw units.
  • validate_address: Validates address format and checksum.

Installation

npm install xno-skills

Releasing

See RELEASING.md.

MCP Client Setup (Codex, Claude, OpenCode, Gemini, VS Code)

All examples run the MCP server via npx (swap @latest for a pinned version if you prefer).

Codex

codex mcp add xno \
  -c sandbox_mode="danger-full-access" \
  -c 'sandbox_permissions=["network-access"]' \
  -- npx -y -p xno-skills@latest xno-mcp

Claude Desktop (claude_desktop_config.json)

Add via Claude Desktop: Settings -> Developer -> Edit Config.

{
  "mcpServers": {
    "xno": {
      "command": "npx",
      "args": ["-y", "-p", "xno-skills@latest", "xno-mcp"]
    }
  }
}

OpenCode (opencode.jsonc)

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "xno": {
      "type": "local",
      "command": ["npx", "-y", "-p", "xno-skills@latest", "xno-mcp"],
      "enabled": true
    }
  }
}

Gemini CLI (settings.json)

{
  "mcpServers": {
    "xno": {
      "command": "npx",
      "args": ["-y", "-p", "xno-skills@latest", "xno-mcp"]
    }
  }
}

VS Code (.vscode/mcp.json)

{
  "servers": {
    "xno": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "-p", "xno-skills@latest", "xno-mcp"]
    }
  }
}

CLI Usage

Install globally or use with npx:

# Install globally
npm install -g xno-skills

# Or use with npx
npx xno-skills --help

Wallet Commands

Security note: avoid pasting mnemonics/seeds into chat logs. Prefer --stdin (or --mnemonic-env) for import/probing commands.

Create a new wallet

# Default: BIP39 derivation
xno-skills wallet create

# Choose legacy derivation (24-word “seed phrase” style)
xno-skills wallet create --format legacy

# Control BIP39 word count / passphrase / index
xno-skills wallet create --words 12
xno-skills wallet create --passphrase "optional passphrase"
xno-skills wallet create --index 0

# JSON output
xno-skills wallet create --json

Restore from mnemonic

# Safer import via stdin (recommended)
echo "word1 word2 ... word24" | xno-skills wallet from-mnemonic --stdin --json

# JSON output
xno-skills wallet from-mnemonic --stdin --json

Probe mnemonic ambiguity (24-word)

If you have a Nano RPC endpoint, you can probe the first few indexes for both derivations and see which accounts are opened / have balances:

export NANO_RPC_URL="http://127.0.0.1:7076"
echo "word1 word2 ... word24" | xno-skills wallet probe-mnemonic --stdin --json

Convert Units

# Convert XNO to raw
xno-skills convert 1.5 xno --to raw

# Convert raw to XNO
xno-skills convert 1500000000000000000000000000000 raw --to xno

# Convert between units
xno-skills convert 1 mnano --to knano

# JSON output
xno-skills convert 1 xno --to raw --json

Supported units:

  • xno or nano - Nano (10^30 raw)
  • knano - Kilo-nano (10^27 raw)
  • mnano - Mega-nano (10^24 raw)
  • raw - Base unit

Generate QR Codes

# QR code for address
xno-skills qr nano_1abc123...

# QR code with amount
xno-skills qr nano_1abc123... --amount 1.5

# JSON output
xno-skills qr nano_1abc123... --json

Validate Addresses

xno-skills validate nano_1abc123...

RPC (balance/pending)

export NANO_RPC_URL="http://127.0.0.1:7076"
xno-skills rpc account-balance nano_1abc123... --json --xno

API Reference

Seed Generation

generateMnemonic(wordCount = 24): string

Generate a BIP39 mnemonic (12/15/18/21/24 words).

import { generateMnemonic } from 'xno-skills';

const mnemonic = generateMnemonic(24);

generateSeed(): string

Generate a cryptographically secure 32-byte seed (256 bits).

import { generateSeed } from 'xno-skills';

const seed = generateSeed();
// Returns: "0123456789abcdef..." (64 hex characters)

seedToMnemonic(seed: string): string

Convert a hex-encoded seed to a BIP39 mnemonic phrase.

import { seedToMnemonic } from 'xno-skills';

const mnemonic = seedToMnemonic(seed);
// Returns: "word1 word2 word3 ... word24"

mnemonicToSeed(mnemonic: string): string

Convert a BIP39 mnemonic phrase back to its underlying entropy (hex).

Note: this is not the BIP39 PBKDF2 “seed”; it’s the raw entropy the mnemonic encodes.

import { mnemonicToSeed } from 'xno-skills';

const seed = mnemonicToSeed(mnemonic);
// Returns: "0123456789abcdef..." (64 hex characters)

mnemonicToBIP39Seed(mnemonic: string, passphrase?: string): string

Convert a BIP39 mnemonic (+ optional passphrase) to the PBKDF2 “seed” hex used for HD derivation.

validateMnemonic(mnemonic: string): boolean

Validate a BIP39 mnemonic phrase.

import { validateMnemonic } from 'xno-skills';

const isValid = validateMnemonic(mnemonic);
// Returns: true or false

Legacy Address Derivation

deriveAddressLegacy(seed: string, index: number): LegacyAddressResult

Derive a Nano address from a seed using the legacy derivation method.

import { deriveAddressLegacy } from 'xno-skills';

const result = deriveAddressLegacy(seed, 0);
// Returns: { address, privateKey, publicKey }

derivePrivateKeyLegacy(seed: string, index: number): string

Derive a private key from a seed at the specified index.

import { derivePrivateKeyLegacy } from 'xno-skills';

const privateKey = derivePrivateKeyLegacy(seed, 0);
// Returns: "0123456789abcdef..." (64 hex characters)

derivePublicKeyLegacy(privateKey: string): string

Derive a public key from a private key.

import { derivePublicKeyLegacy } from 'xno-skills';

const publicKey = derivePublicKeyLegacy(privateKey);
// Returns: "0123456789abcdef..." (64 hex characters)

publicKeyToAddress(publicKey: string): string

Convert a public key to a Nano address.

import { publicKeyToAddress } from 'xno-skills';

const address = publicKeyToAddress(publicKey);
// Returns: "nano_1abc123..."

BIP44 Address Derivation

deriveAddressBIP44(mnemonic: string, index: number, passphrase?: string): BIP44AddressResult

Derive a Nano address from a mnemonic using BIP44 path m/44'/165'/[index]'.

import { deriveAddressBIP44 } from 'xno-skills';

const result = deriveAddressBIP44(mnemonic, 0);
// Returns: { address, privateKey, publicKey }

// With optional passphrase
const result = deriveAddressBIP44(mnemonic, 0, 'my-passphrase');

derivePrivateKeyBIP44(mnemonic: string, index: number, passphrase?: string): string

Derive a private key from a mnemonic using BIP44.

import { derivePrivateKeyBIP44 } from 'xno-skills';

const privateKey = derivePrivateKeyBIP44(mnemonic, 0);
// Returns: "0123456789abcdef..." (64 hex characters)

derivePublicKeyBIP44(privateKey: string): string

Derive a public key from a BIP44-derived private key.

import { derivePublicKeyBIP44 } from 'xno-skills';

const publicKey = derivePublicKeyBIP44(privateKey);
// Returns: "0123456789abcdef..." (64 hex characters)

publicKeyToAddressBIP44(publicKey: string): string

Convert a BIP44-derived public key to a Nano address.

import { publicKeyToAddressBIP44 } from 'xno-skills';

const address = publicKeyToAddressBIP44(publicKey);
// Returns: "nano_1abc123..."

validateMnemonicBIP44(mnemonic: string): boolean

Validate a BIP39 mnemonic phrase for BIP44 usage.

import { validateMnemonicBIP44 } from 'xno-skills';

const isValid = validateMnemonicBIP44(mnemonic);
// Returns: true or false

mnemonicToBIP39Seed(mnemonic: string, passphrase?: string): string

Convert a mnemonic to a BIP39 seed (512-bit).

import { mnemonicToBIP39Seed } from 'xno-skills';

const seed = mnemonicToBIP39Seed(mnemonic);
// Returns: "0123456789abcdef..." (128 hex characters)

Address Validation

validateAddress(address: string): ValidateAddressResult

Validate a Nano address and extract the public key.

import { validateAddress } from 'xno-skills';

const result = validateAddress('nano_1abc123...');
// Returns: { valid: true, publicKey: "..." }
// Or: { valid: false, error: "Invalid prefix..." }

Unit Conversion

nanoToRaw(nano: string): string

Convert Nano (XNO) to raw units.

import { nanoToRaw } from 'xno-skills';

const raw = nanoToRaw('1.5');
// Returns: "1500000000000000000000000000000"

rawToNano(raw: string, decimals?: number): string

Convert raw units to Nano (XNO).

import { rawToNano } from 'xno-skills';

const nano = rawToNano('1500000000000000000000000000000');
// Returns: "1.5"

// With specific decimal places
const nano = rawToNano(raw, 6);
// Returns: "1.500000"

formatNano(raw: string): string

Format raw units as Nano with full precision.

import { formatNano } from 'xno-skills';

const formatted = formatNano('1500000000000000000000000000000');
// Returns: "1.5"

knanoToRaw(knano: string): string

Convert kilo-nano to raw units.

import { knanoToRaw } from 'xno-skills';

const raw = knanoToRaw('1.5');
// Returns: "1500000000000000000000000000000000"

mnanoToRaw(mnano: string): string

Convert mega-nano to raw units.

import { mnanoToRaw } from 'xno-skills';

const raw = mnanoToRaw('1.5');
// Returns: "1500000000000000000000000000000000000"

Cryptographic Functions

blake2b256(data: Uint8Array): Uint8Array

Compute BLAKE2b-256 hash (32 bytes).

import { blake2b256 } from 'xno-skills';

const hash = blake2b256(new TextEncoder().encode('hello'));
// Returns: Uint8Array(32)

blake2b512(data: Uint8Array): Uint8Array

Compute BLAKE2b-512 hash (64 bytes).

import { blake2b512 } from 'xno-skills';

const hash = blake2b512(new TextEncoder().encode('hello'));
// Returns: Uint8Array(64)

blake2b256Hex(data: Uint8Array): string

Compute BLAKE2b-256 hash and return as hex string.

import { blake2b256Hex } from 'xno-skills';

const hash = blake2b256Hex(new TextEncoder().encode('hello'));
// Returns: "abc123..." (64 hex characters)

Base32 Encoding

base32Encode(bytes: Uint8Array): string

Encode bytes to Nano's Base32 format.

import { base32Encode } from 'xno-skills';

const encoded = base32Encode(new Uint8Array([0x00, 0xff]));
// Returns: "1z"

base32Decode(str: string): Uint8Array

Decode Nano's Base32 format to bytes.

import { base32Decode } from 'xno-skills';

const bytes = base32Decode('1z');
// Returns: Uint8Array([0x00, 0xff])

QR Code Generation

generateAsciiQr(address: string, amount?: number): Promise<string>

Generate an ASCII QR code for a Nano address.

import { generateAsciiQr } from 'xno-skills';

const qr = await generateAsciiQr('nano_1abc123...');
console.log(qr);

// With amount
const qr = await generateAsciiQr('nano_1abc123...', 1.5);

Security Notes

CRITICAL: Handle seeds and private keys with extreme care.

  1. Never share your seed or private keys. Anyone with access to these can fully control your wallet.

  2. Store seeds securely. Use hardware wallets, encrypted storage, or offline backup methods. Never store seeds in plain text files, cloud storage, or version control.

  3. Use environment variables for seeds in development. Never hardcode seeds in your source code.

  4. BIP44 vs Legacy derivation. This library supports both:

    • Legacy: Uses Blake2b-based path derivation (original Nano method)
    • BIP44: Standard HD wallet derivation path m/44'/165'/[index]'

    Choose the method compatible with your existing wallet. Most Nano wallets use legacy derivation.

  5. Mnemonic phrases. When using BIP44, the mnemonic phrase is the master key. Protect it as carefully as a seed.

  6. Passphrase protection. BIP44 supports optional passphrases for additional security. A passphrase acts as a "25th word" - even if someone obtains your mnemonic, they cannot access funds without the passphrase.

  7. Address validation. Always validate addresses before sending funds. Nano addresses include a checksum to catch typos.

  8. Unit precision. Nano uses 30 decimal places. Always use string-based conversion functions to avoid floating-point precision errors.

Development

# Install dependencies
npm install

# Run unit tests
npm test

# Run integration tests
npx vitest run test/integration.test.ts

# Build
npm run build

# Build ESM
npm run build:esm

# Build CJS
npm run build:cjs

Releasing

See RELEASING.md.

Similar Projects

License

MIT