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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ordchan/sdk

v0.3.0

Published

TypeScript SDK for interacting with the OrdChan protocol

Readme

OrdChan SDK

npm version License: MIT

A TypeScript SDK for interacting with the OrdChan protocol - a decentralized messaging platform built on Bitcoin Ordinals.

Features

  • 🔍 Search & Discover - Find boards, threads, and replies
  • 📝 Content Creation - Create boards, threads, and replies
  • 🔔 Real-time Updates - Subscribe to new content via WebSockets
  • 👛 Wallet Integration - Built-in adapters for popular Bitcoin wallets (UniSat, OKX, Xverse)
  • 🔑 Direct Key Access - Use private keys or seed phrases without a browser extension
  • 🌍 Network Support - Works on both mainnet and testnet
  • 🏷️ Username Market - Buy, sell, and make offers on usernames
  • 📊 Voting System - Upvote/downvote content with satoshis
  • 🧰 Ordinals Processing - Extract and parse ordinals inscriptions from blocks and transactions
  • 🧩 Extensible Architecture - Easily add custom wallet adapters
  • 🔄 Transaction Access - Get raw transaction data from Bitcoin nodes or public APIs
  • 💱 NFT Marketplace - Buy and sell NFTs with our marketplace utilities (new in v0.3.0)
  • 🌐 Cross-Platform - Compatible with both browser and Node.js environments (new in v0.3.0)

Installation

npm install @ordchan/sdk

Or using Yarn:

yarn add @ordchan/sdk

Quick Start

import { OrdChanSDK, UniSatWalletAdapter, PrivateKeyWalletAdapter } from '@ordchan/sdk';

// Initialize the SDK
const sdk = new OrdChanSDK({
  apiUrl: 'https://api.ordchan.com'
});

// Connect wallet (choose one method)
const connectBrowserWallet = async () => {
  const wallet = new UniSatWalletAdapter();
  await wallet.connect();
  sdk.setWalletAdapter(wallet);
  console.log('Connected to browser wallet');
};

const connectWithSeedPhrase = async () => {
  const wallet = new PrivateKeyWalletAdapter({
    seedPhrase: 'your twelve or twenty four word mnemonic seed phrase',
    network: 'mainnet'
  });
  await wallet.connect();
  sdk.setWalletAdapter(wallet);
  console.log('Connected with seed phrase');
};

// Get all boards
const getBoards = async () => {
  const boards = await sdk.boards.getAll();
  console.log('Boards:', boards);
};

// Create a new thread
const createThread = async () => {
  const thread = await sdk.threads.create({
    board: 'bitcoin',
    title: 'Hello OrdChan',
    content: 'This is my first thread'
  });
  console.log('Created thread:', thread);
};

// Subscribe to new replies in a thread
const subscribeToReplies = (threadId) => {
  const unsubscribe = sdk.replies.subscribe(
    { threadId },
    (reply) => {
      console.log('New reply:', reply);
    }
  );
  
  // To stop listening later:
  // unsubscribe();
};

NFT Marketplace (New in v0.3.0)

The SDK includes a complete marketplace implementation for buying and selling NFTs on Bitcoin:

import { marketplace } from '@ordchan/sdk';
import { UniSatWalletAdapter, PrivateKeyWalletAdapter } from '@ordchan/sdk';

// Example 1: Sell an NFT by creating a listing
const sellNft = async () => {
  // Connect a wallet (browser extension or private key)
  const wallet = new PrivateKeyWalletAdapter({ 
    seedPhrase: 'your seed phrase here',
    network: 'bitcoin'
  });
  await wallet.connect();
  
  // Get seller's address
  const sellerAddress = await wallet.getAddress();
  
  // Find the UTXO containing the inscription
  const inscriptionId = '1d33f2a46047fbb366652d003d8049bbadc6e38062ce1b9b57408a2a5d4373a7i0';
  const inscriptionUtxo = await marketplace.utxo.findInscriptionUtxo(
    inscriptionId,
    sellerAddress,
    'bitcoin' // or 'fractal' for Fractal network
  );
  
  if (!inscriptionUtxo) {
    console.error('Inscription not found in this wallet');
    return;
  }
  
  // Create a listing PSBT
  const price = 10000; // 10,000 satoshis
  const listingPsbt = marketplace.psbt.createNftListingPsbt({
    inscriptionUtxo,
    sellerAddress,
    recipientAddress: sellerAddress, // Where to receive payment
    price,
    platformFeeAddress: 'bc1q...' // Optional: platform fee recipient
  });
  
  // Sign the listing PSBT with the wallet
  const privateKey = await wallet.getPrivateKey(); // Implementation depends on wallet
  const signedPsbt = marketplace.psbt.signNftSellerPsbt(listingPsbt, privateKey);
  
  console.log('Listing PSBT created and signed:');
  console.log(signedPsbt);
  
  // This PSBT can now be shared with potential buyers
  return signedPsbt;
};

// Example 2: Buy an NFT from a listing
const buyNft = async (listingPsbtHex) => {
  // Connect a wallet
  const wallet = new UniSatWalletAdapter();
  await wallet.connect();
  
  // Get buyer's address
  const buyerAddress = await wallet.getAddress();
  
  // Find payment UTXOs
  const utxos = await marketplace.utxo.findAllUtxos(buyerAddress, 'bitcoin');
  
  // Create buyer's PSBT
  const buyerPsbt = marketplace.psbt.createNftBuyerPsbt({
    sellerSignedPsbtHex: listingPsbtHex,
    buyerAddress,
    changeAddress: buyerAddress,
    paymentUtxos: utxos,
    feeRate: 5 // sats/byte
  });
  
  // Sign the buyer's PSBT
  const signedBuyerPsbt = await wallet.signPsbt(buyerPsbt);
  
  // Combine PSBTs
  const completePsbt = marketplace.psbt.combineNftPsbts(
    listingPsbtHex,
    signedBuyerPsbt
  );
  
  // Extract and broadcast the final transaction
  const txHex = marketplace.transaction.extractTransaction(completePsbt);
  if (txHex) {
    const result = await marketplace.transaction.broadcastTransaction(
      txHex,
      'bitcoin' // or 'fractal'
    );
    
    console.log('NFT purchase successful!');
    console.log('Transaction ID:', result.txid);
    console.log('Explorer URL:', marketplace.transaction.getExplorerUrl(result.txid, 'bitcoin'));
  }
};

Cross-Platform Compatibility (New in v0.3.0)

The SDK now works seamlessly in both browser and Node.js environments:

import { marketplace, wallet } from '@ordchan/sdk';

// Browser environment: Use a browser wallet
const useBrowserWallet = async () => {
  // This will only attempt to connect if running in a browser
  try {
    const walletAdapter = new wallet.UniSatWalletAdapter();
    await walletAdapter.connect();
    console.log('Connected to UniSat wallet');
    return walletAdapter;
  } catch (error) {
    console.error('Browser wallet not available:', error);
    return null;
  }
};

// Node.js environment: Use a private key or seed phrase
const usePrivateKeyWallet = async () => {
  const walletAdapter = new wallet.PrivateKeyWalletAdapter({
    seedPhrase: 'your seed phrase here',
    // or privateKey: 'your WIF private key',
    network: 'bitcoin'
  });
  await walletAdapter.connect();
  console.log('Connected with private key wallet');
  return walletAdapter;
};

// Works in both environments
const getWalletAdapter = async () => {
  // Try browser wallet first
  const browserWallet = await useBrowserWallet().catch(() => null);
  if (browserWallet) return browserWallet;
  
  // Fall back to private key wallet
  return await usePrivateKeyWallet();
};

UTXO Management (New in v0.3.0)

The SDK provides comprehensive UTXO utilities:

import { marketplace } from '@ordchan/sdk';

// Find UTXOs containing a specific inscription
const findInscription = async () => {
  const inscriptionId = '1d33f2a46047fbb366652d003d8049bbadc6e38062ce1b9b57408a2a5d4373a7i0';
  const address = 'bc1q...';
  const network = 'bitcoin'; // or 'fractal'
  
  const utxo = await marketplace.utxo.findInscriptionUtxo(
    inscriptionId,
    address,
    network
  );
  
  if (utxo) {
    console.log(`Inscription found in UTXO: ${utxo.txid}:${utxo.vout}`);
    console.log(`Value: ${utxo.value} sats`);
  } else {
    console.log('Inscription not found in this address');
  }
};

// Find all UTXOs for an address
const findAllUtxos = async () => {
  const address = 'bc1q...';
  const utxos = await marketplace.utxo.findAllUtxos(address, 'bitcoin');
  console.log(`Found ${utxos.length} UTXOs with total value: ${
    utxos.reduce((sum, u) => sum + u.value, 0)
  } sats`);
};

// Select UTXOs for a transaction
const selectUtxos = () => {
  const availableUtxos = [/* array of UTXOs */];
  const amountNeeded = 50000; // 50,000 sats
  const minUtxosNeeded = 2; // Need at least 2 UTXOs for placeholder inputs
  
  const selectedUtxos = marketplace.utxo.selectUtxosForPayment(
    availableUtxos,
    amountNeeded,
    minUtxosNeeded
  );
  
  console.log(`Selected ${selectedUtxos.length} UTXOs with value: ${
    selectedUtxos.reduce((sum, u) => sum + u.value, 0)
  } sats`);
};

// Create placeholder UTXOs for complex transactions
const createPlaceholderUtxos = async () => {
  const wallet = new wallet.PrivateKeyWalletAdapter({
    seedPhrase: 'your seed phrase here'
  });
  await wallet.connect();
  
  const address = await wallet.getAddress();
  const utxos = await marketplace.utxo.findAllUtxos(address);
  
  // Create multiple small UTXOs from a larger one
  const txid = await marketplace.transaction.createPlaceholderUtxos(
    utxos,
    address,
    wallet.getPrivateKey(),
    5, // number of UTXOs to create
    5000, // value of each UTXO (5,000 sats)
    5, // fee rate (sats/byte)
    'bitcoin' // network
  );
  
  console.log(`Created placeholder UTXOs in transaction: ${txid}`);
};

Transaction Handling (New in v0.3.0)

The SDK provides comprehensive transaction utilities:

import { marketplace } from '@ordchan/sdk';

// Broadcast a transaction
const broadcastTx = async () => {
  const txHex = '020000000001...'; // Transaction hex
  const network = 'bitcoin'; // or 'fractal'
  
  try {
    const result = await marketplace.transaction.broadcastTransaction(txHex, network);
    console.log('Transaction broadcast successful!');
    console.log('Transaction ID:', result.txid);
    
    // Get explorer URL
    const url = marketplace.transaction.getExplorerUrl(result.txid, network);
    console.log('View transaction:', url);
  } catch (error) {
    console.error('Broadcast failed:', error);
  }
};

// Sign a PSBT with a private key
const signPsbt = () => {
  const psbtHex = '70736274ff...'; // PSBT hex
  const privateKey = Buffer.from('...'); // Private key buffer
  
  // Optionally specify sighash types for each input
  const sighashTypes = [
    0x01, // SIGHASH_ALL for input 0
    0x81  // SIGHASH_SINGLE|ANYONECANPAY for input 1
  ];
  
  const signedPsbtHex = marketplace.transaction.signPsbt(
    psbtHex,
    privateKey,
    sighashTypes // optional
  );
  
  console.log('Signed PSBT:', signedPsbtHex);
};

// Extract a transaction from a PSBT
const extractTx = () => {
  const psbtHex = '70736274ff...'; // PSBT hex
  
  // Try to extract a complete transaction
  const txHex = marketplace.transaction.extractTransaction(psbtHex);
  
  if (txHex) {
    console.log('Extracted transaction:', txHex);
  } else {
    // Try with allowIncomplete=true for partially signed PSBTs
    const incompleteTxHex = marketplace.transaction.extractTransaction(psbtHex, true);
    console.log('Extracted incomplete transaction:', incompleteTxHex);
  }
};

// Calculate transaction fee
const calculateFee = () => {
  const txHex = '020000000001...'; // Transaction hex
  const feeRate = 5; // sats/byte
  
  const estimatedFee = marketplace.transaction.estimateTransactionFee(txHex, feeRate);
  console.log(`Estimated fee: ${estimatedFee} sats`);
};

Ordinals Processing

The SDK includes powerful utilities for processing Bitcoin blocks and transactions to extract ordinals inscriptions:

// Initialize the SDK
const sdk = new OrdChanSDK({
  apiUrl: 'https://api.ordchan.com'
});

// Process a Bitcoin block to extract all ordinals inscriptions
const processBlock = async () => {
  const blockHash = '000000000000000000076c036ff5119e5c5a633a9e8e5ba71b7ad89e52a0dcec'; // Block 800000
  const messages = await sdk.ordinals.processBlock(blockHash);
  console.log(`Found ${messages.length} ordinals in block`);
  
  // Filter to only OrdChan protocol messages
  const ordchanMessages = sdk.ordinals.filterByProtocol(messages, ['ordchan']);
  console.log(`Found ${ordchanMessages.length} OrdChan messages`);
};

// Process a single transaction to extract ordinals
const processTransaction = async () => {
  const txid = 'f34c43b1158de337e8e4f74d09256a574e865d8ab280926a0cd40d4e7aabf9a2';
  const messages = await sdk.ordinals.processTransaction(txid);
  console.log(`Found ${messages.length} inscriptions in transaction`);
};

// Process a transaction directly from its raw hex
const processTransactionHex = async () => {
  // Get transaction hex from anywhere (from wallet, API, or manual construction)
  const txHex = '020000000001018c57c91a45a44ba....'; // Transaction hex data
  
  // Process directly without needing to broadcast or have txid
  const { txid, ordinals } = await sdk.ordinals.processTransactionFromHex(txHex);
  console.log(`Transaction ID: ${txid}`);
  console.log(`Found ${ordinals.length} inscriptions in transaction hex`);
  
  // You can also provide optional block information if available
  const result = await sdk.ordinals.processTransactionFromHex(txHex, {
    blockInfo: {
      blockHeight: 800000,
      blockHash: '000000000000000000076c036ff5119e5c5a633a9e8e5ba71b7ad89e52a0dcec',
      timestamp: 1685341196
    }
  });
  console.log(`Transaction ${result.txid} has ${result.ordinals.length} inscriptions`);
};

// Extract a message from an inscription ID
const extractMessage = async () => {
  const inscriptionId = 'f34c43b1158de337e8e4f74d09256a574e865d8ab280926a0cd40d4e7aabf9a2i0';
  const content = await sdk.ordinals.extractMessage(inscriptionId);
  console.log('Inscription content:', content);
};

See ORDINALS_PROCESSING.md for more details.

Transaction Data Access

The SDK provides methods to retrieve raw Bitcoin transaction data from various sources:

// Initialize the SDK with Bitcoin RPC configuration (optional)
const sdk = new OrdChanSDK({
  apiUrl: 'https://api.ordchan.com',
  // Optionally configure Bitcoin RPC access
  bitcoinRpc: {
    host: 'localhost',
    port: 8332,
    user: 'username',
    password: 'password'
    // Alternatively, use a cookie file
    // cookieFile: '~/.bitcoin/.cookie'
  },
  // Optionally configure fallbacks and preferred data sources
  dataSourceConfig: {
    preferBlockstream: false, // Prefer blockstream.info API over RPC
    preferMempool: true,      // Prefer mempool.space API over RPC
    fallbackToPublicApis: true // Use public APIs if RPC fails
  }
});

// Get raw transaction hex
const getRawTx = async (txid) => {
  try {
    const txHex = await sdk.transactions.getRawTransactionHex(txid);
    console.log(`Transaction hex (${txHex.length / 2} bytes):`);
    console.log(txHex.substring(0, 100) + '...');
    
    // Parse the transaction
    const tx = bitcoin.Transaction.fromHex(txHex);
    console.log(`Transaction has ${tx.ins.length} inputs and ${tx.outs.length} outputs`);
    
    return txHex;
  } catch (error) {
    console.error('Failed to get transaction hex:', error);
  }
};

The SDK will automatically try multiple sources to get transaction data:

  1. Local Bitcoin node (via RPC) if configured
  2. mempool.space API
  3. blockstream.info API
  4. blockchain.info API
  5. OrdChan API as a last resort

Documentation

For full API documentation, see the SDK Docs.

Examples

The repository includes several examples demonstrating how to use the SDK:

Version History

v0.3.0

  • Added comprehensive NFT marketplace functionality
  • Made wallet adapters compatible with both browser and Node.js
  • Added UTXO management utilities
  • Added transaction handling utilities
  • Fixed TypeScript compilation issues
  • Improved error handling and type safety

v0.2.3

  • Added ordinals processing utilities
  • Added transaction data access
  • Added username market functionality
  • Improved wallet adapters

v0.2.0

  • Initial public release
  • Basic board and thread functionality
  • Wallet integration

License

MIT