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

@yellow-org/sdk-compat

v1.4.0

Published

Curated migration layer preserving selected Nitrolite SDK v0.5.3 app-facing APIs over the v1 runtime.

Readme

Nitrolite Compat SDK

License

@yellow-org/sdk-compat is a migration layer that preserves selected Nitrolite SDK v0.5.3 app-facing APIs over the v1 runtime.

The off-chain broker was renamed from "Clearnode" to "Nitronode" in v1.3.0. See MIGRATION-NITRONODE.md.

  • Keep supported v0.5.3-style app-facing calls in your code.
  • Run them through @yellow-org/sdk-compat, backed by @yellow-org/sdk.
  • Treat it as a migration aid, not a drop-in replacement for the full published v0.5.3 package.

Compatibility Scope

@yellow-org/sdk-compat is intentionally narrower than the published v0.5.3 package surface.

  • Preserved app-facing APIs: the NitroliteClient facade, selected auth helpers, app-session signing helpers, and many app-facing types remain available for supported migration paths.
  • Transitional helper surfaces: some legacy create*Message / parse*Response exports now emit real v1-compatible payloads inside the legacy req/sig envelope, while workflow-only helpers stay exported as fail-fast migration shims.
  • Unsupported full-package parity: low-level internals, broad root-export parity, and every legacy helper being runtime-faithful are not promised by this package.

Why

The v1 protocol changes wire format, authentication, WebSocket lifecycle, unit handling, asset resolution, and more. For apps built around the old surface, a direct migration can require scattered rewrites across transport, signing, and amount-handling paths.

The compat layer centralizes the supported migration paths into one package so app code can move to client-level methods incrementally instead of rewriting every call site at once.

Build Size

Measured on February 24, 2026 from the package directory using:

npm run build:prod
npm pack --dry-run --json

| Metric | Size | |---|---:| | npm tarball (size) | 16,503 bytes (16.1 KB) | | unpacked package (unpackedSize) | 73,292 bytes (71.6 KB) | | compiled JS in dist/*.js | 38,146 bytes (37.3 KB) | | type declarations in dist/*.d.ts | 20,293 bytes (19.8 KB) | | total emitted runtime + types (.js + .d.ts) | 58,439 bytes (57.1 KB) |

Migration Guide

Step-by-step guides for migrating supported app-facing paths from v0.5.3:

Installation

npm install @yellow-org/sdk-compat
# peer dependencies
npm install @yellow-org/sdk viem

Quick Start

1. Initialize the client

Replace new Client(ws, signer) with NitroliteClient.create():

import { NitroliteClient, blockchainRPCsFromEnv } from '@yellow-org/sdk-compat';

const client = await NitroliteClient.create({
  wsURL: 'wss://nitronode.example.com/ws',
  walletClient,          // viem WalletClient with account
  chainId: 11155111,     // Sepolia
  blockchainRPCs: blockchainRPCsFromEnv(),
});

2. Deposit & create a channel

In v1, channel creation is implicit on deposit — no separate createChannel() call needed:

const tokenAddress = '0x6E2C4707DA119425DF2C722E2695300154652F56'; // USDC on Sepolia
const amount = 11_000_000n; // 11 USDC in raw units (6 decimals)

await client.deposit(tokenAddress as Address, amount);

3. Query channels, balances, ledger entries

const channels = await client.getChannels();
const balances = await client.getBalances();
const entries  = await client.getLedgerEntries();
const sessions = await client.getAppSessionsList();
const assets   = await client.getAssetsList();

4. Transfer off-chain

The compat transfer(destination, allocations) preserves the v0.5.3-style array-of-allocations signature. Each TransferAllocation.amount is a raw asset-unit string using the asset's canonical decimals. The compat layer divides by asset decimals before delegating to the v1 SDK's transfer(wallet, asset, Decimal):

// 5 USDC = 5_000_000 raw asset units when USDC has 6 asset decimals
await client.transfer(recipientAddress, [
  { asset: 'usdc', amount: '5000000' },
]);

// For direct SDK access with human-readable Decimal:
// await client.innerClient.transfer('0xRecip...', 'usdc', new Decimal(5));

5. Close & clean up

await client.closeChannel();
await client.close();

Method Cheat Sheet

Channel Operations

| Method | Description | |---|---| | deposit(token, amount) | Deposit to channel (creates if needed) | | depositAndCreateChannel(token, amount) | Alias for deposit() | | withdrawal(token, amount) | Withdraw from channel | | closeChannel() | Close all open channels | | resizeChannel({ allocate_amount, token }) | Resize an existing channel | | challengeChannel({ state }) | Challenge a channel on-chain | | acknowledge(tokenAddress) | Acknowledge a pending state or create a channel | | checkTokenAllowance(chainId, tokenAddress) | Check ERC-20 allowance for the ChannelHub |

Queries

| Method | Description | |---|---| | getChannels() | List all ledger channels (open, closed, etc.) | | getBalances(wallet?) | Get ledger balances | | getLedgerEntries(wallet?) | Get transaction history | | getAppSessionsList(wallet?, status?) | List app sessions (filter by 'open'/'closed') | | getAssetsList() | List supported assets | | getAccountInfo() | Aggregate balance + channel count | | getConfig() | Node configuration | | getBlockchains() | List supported blockchains | | getEscrowChannel(escrowChannelId) | Query an escrow channel by ID | | getChannelData(channelId) | Full channel + state for a specific channel | | getLastAppSessionsListError() | Last getAppSessionsList() error message (if any) | | getOpenChannels() | Read current-chain open channel IDs from the ChannelHub |

App Sessions

| Method | Description | |---|---| | createAppSession(definition, allocations, quorumSigs, opts?) | Create an app session with quorum signatures (optional ownerSig via opts) | | closeAppSession(appSessionId, allocations, quorumSigs) | Close an app session with quorum signatures | | submitAppState(params) | Submit state update (operate/deposit/withdraw/close) | | getAppDefinition(appSessionId) | Get the definition for a session |

App-session allocation strings remain human-readable decimal strings such as '0.01'. They are not raw smallest-unit token strings.

App Session Signing Helpers

| Helper | Description | |---|---| | packCreateAppSessionHash(params) | Deterministic hash for createAppSession quorum signing | | packSubmitAppStateHash(params) | Deterministic hash for submitAppState quorum signing | | toWalletQuorumSignature(signature) | Prefixes wallet signature to compat app-session quorum format | | toSessionKeyQuorumSignature(signature) | Prefixes app-session key signature (0xa2) to compat quorum format |

Session Key Operations

Both state.user_sig (wallet authorization) and state.session_key_sig (proof of possession by the session-key holder) are required at submit time. The *Ownership helpers produce session_key_sig.

| Method | Description | |---|---| | signChannelSessionKeyState(state) | Wallet user_sig over channel session-key state | | signChannelSessionKeyOwnership(state, sessionKeySigner) | Session-key holder's session_key_sig for channel state | | submitChannelSessionKeyState(state) | Register/submit a channel session-key state (both sigs required) | | getLastChannelKeyStates(userAddress, sessionKey?, options?) | Fetch channel session-key states (active-only by default; { includeInactive: true } for expired/revoked) | | signSessionKeyState(state) | Wallet user_sig over app session-key state | | signAppSessionKeyOwnership(state, sessionKeySigner) | Session-key holder's session_key_sig for app state | | submitSessionKeyState(state) | Register/submit an app-session key state (both sigs required) | | getLastAppKeyStates(userAddress, sessionKey?, options?) | Fetch app-session key states (active-only by default; { includeInactive: true } for expired/revoked) | | getLastKeyStates(userAddress, sessionKey?) | Deprecated — 0.5.x alias for getLastAppKeyStates; no includeInactive option |

Transfers

| Method | Description | |---|---| | transfer(destination, allocations) | Off-chain transfer to another participant |

TransferAllocation.amount remains a raw asset-unit string using the asset's canonical decimals, for example '5000000' for 5 USDC when USDC has 6 asset decimals.

Asset Resolution

| Method | Description | |---|---| | resolveToken(tokenAddress) | Look up asset info by token address | | resolveAsset(symbol) | Look up asset info by symbol name | | resolveAssetDisplay(tokenAddress, chainId?) | Get display-friendly symbol + decimals | | getTokenDecimals(tokenAddress) | Get decimals for a token | | formatAmount(tokenAddress, rawAmount) | Convert raw bigint → human-readable string | | parseAmount(tokenAddress, humanAmount) | Convert human-readable string → raw bigint | | findOpenChannel(tokenAddress, chainId?) | Find an open channel for a given token |

Legacy On-Chain Helpers

| Method | Description | |---|---| | approveTokens(tokenAddress, amount) | Approve the current-chain ChannelHub using raw token units | | getTokenAllowance(tokenAddress) | Read current-chain ChannelHub allowance in raw token units | | getTokenBalance(tokenAddress) | Read current-chain wallet token balance in raw token units |

Unsupported Legacy Gaps

These legacy methods remain intentionally unsupported because the v1 runtime no longer offers an honest one-to-one mapping:

  • createChannel(...)
  • checkpointChannel(...)
  • getAccountBalance(...)
  • getChannelBalance(...)

Workflow-style RPC helpers such as createTransferMessage(...), createCreateChannelMessage(...), createCloseChannelMessage(...), and createResizeChannelMessage(...) are in the same category: they stay exported for migration, but now fail fast with migration guidance instead of silently approximating old behavior.

Lifecycle

| Method | Description | |---|---| | ping() | Health check | | close() | Close the WebSocket connection | | waitForClose() | Returns a promise that resolves when the connection is closed | | refreshAssets() | Re-fetch the asset map from the nitronode |

Accessing the v1 SDK Directly

The underlying v1 Client is exposed for advanced use cases not covered by the compat surface:

const v1Client = client.innerClient;
await v1Client.getHomeChannel(wallet, 'usdc');

Configuration

NitroliteClientConfig

interface NitroliteClientConfig {
  wsURL: string;                           // Nitronode WebSocket URL
  walletClient: WalletClient;              // viem WalletClient with account
  chainId: number;                         // Chain ID (e.g. 11155111 for Sepolia)
  blockchainRPCs?: Record<number, string>; // Optional chain ID → RPC URL map
  channelSessionKeySigner?: {
    sessionKeyPrivateKey: Hex;
    walletAddress: Address;
    metadataHash: Hex;
    authSig: Hex;
  };
  addresses?: ContractAddresses;           // Deprecated — ignored, addresses come from get_config
  challengeDuration?: bigint;              // Deprecated — ignored
}

Environment Variables

blockchainRPCsFromEnv() reads NEXT_PUBLIC_BLOCKCHAIN_RPCS:

NEXT_PUBLIC_BLOCKCHAIN_RPCS=11155111:https://rpc.sepolia.io,1:https://mainnet.infura.io/v3/KEY

Signers

WalletStateSigner

A v0.5.3-compatible signer class that wraps a WalletClient. Actual state signing in v1 is handled internally by ChannelDefaultSigner; this class exists so existing store types compile:

import { WalletStateSigner } from '@yellow-org/sdk-compat';

const signer = new WalletStateSigner(walletClient);

createECDSAMessageSigner

Creates a MessageSigner function from a private key, compatible with the v0.5.3 signing pattern:

import { createECDSAMessageSigner } from '@yellow-org/sdk-compat';

const sign = createECDSAMessageSigner(privateKey);
const signature = await sign(payload);

Error Handling

The compat layer provides typed error classes for common failure modes:

| Error Class | Code | Description | |---|---|---| | CompatError | (varies) | Base class for all compat errors | | AllowanceError | ALLOWANCE_INSUFFICIENT | Token approval needed | | UserRejectedError | USER_REJECTED | User cancelled in wallet | | InsufficientFundsError | INSUFFICIENT_FUNDS | Not enough balance | | NotInitializedError | NOT_INITIALIZED | Client not connected | | OngoingStateTransitionError | ONGOING_STATE_TRANSITION | Previous action still finalizing |

getUserFacingMessage(error)

Returns a human-friendly string suitable for UI display:

import { getUserFacingMessage, AllowanceError } from '@yellow-org/sdk-compat';

try {
  await client.deposit(token, amount);
} catch (err) {
  showToast(getUserFacingMessage(err));
  // → "Transaction was rejected. Please approve the transaction in your wallet to continue."
}

NitroliteClient.classifyError(error)

Converts raw SDK/wallet errors into the appropriate typed error:

try {
  await client.deposit(token, amount);
} catch (err) {
  const typed = NitroliteClient.classifyError(err);
  if (typed instanceof AllowanceError) {
    // prompt user to approve
  }
}

Event Polling

v0.5.3 used server-push WebSocket events. v1 uses a polling model. The EventPoller bridges this gap:

import { EventPoller } from '@yellow-org/sdk-compat';

const poller = new EventPoller(client, {
  onChannelUpdate: (channels) => updateUI(channels),
  onBalanceUpdate: (balances) => updateBalances(balances),
  onAssetsUpdate:  (assets)   => updateAssets(assets),
  onError:         (err)      => console.error(err),
}, 5000); // poll every 5 seconds

poller.start();

// Later:
poller.stop();
poller.setInterval(10000); // change interval

Amount conventions

The compat layer keeps the old amount conventions explicit instead of flattening them:

| Method group | Input type | Example: 100 tokens (18 decimals) | |---|---|---| | deposit, withdrawal | Raw bigint | 100_000_000_000_000_000_000n | | transfer | Raw asset-unit string via TransferAllocation.amount | '100000000000000000000' | | createAppSession, closeAppSession, submitAppState allocations | Human-readable decimal string | '100.0' |

For direct access to the v1 SDK's human-readable Decimal API, use client.innerClient.

RPC Stubs

The following functions remain exported primarily so legacy create*Message / parse*Response imports can keep compiling while an app migrates. Some create* helpers emit real live-v1 method names and payload shapes inside the legacy req / sig envelope. Workflow-only helpers fail fast with migration guidance instead of returning fake wire payloads. parse* helpers only do lightweight normalization of known response shapes. Prefer NitroliteClient methods directly for new integrations:

// Direct v1-compatible helper mappings:
createGetChannelsMessage, parseGetChannelsResponse,
createGetLedgerBalancesMessage, parseGetLedgerBalancesResponse,
parseGetLedgerEntriesResponse, createGetAppSessionsMessage, parseGetAppSessionsResponse,
createGetAppDefinitionMessage, parseGetAppDefinitionResponse,
createAppSessionMessage, parseCreateAppSessionResponse,
createCloseAppSessionMessage, parseCloseAppSessionResponse,
createSubmitAppStateMessage, parseSubmitAppStateResponse,
createPingMessage,

// Migration-only shims that fail fast:
createTransferMessage,
createCreateChannelMessage, parseCreateChannelResponse,
createCloseChannelMessage, parseCloseChannelResponse,
createResizeChannelMessage, parseResizeChannelResponse,

// Generic normalizers:
convertRPCToClientChannel, convertRPCToClientState,
parseAnyRPCResponse, NitroliteRPC

Auth Helpers

Compat exports auth helpers for apps still using the v0.5.3 auth request/verify flow:

createAuthRequestMessage(params)            // builds auth_request RPC message
createAuthVerifyMessage(signer, response)   // signs and builds auth_verify RPC message
createAuthVerifyMessageWithJWT(jwt)         // builds JWT-based auth_verify RPC message
createEIP712AuthMessageSigner(wallet, ...)  // creates EIP-712 signer for auth_verify challenge

Types Reference

All legacy compat types are re-exported from @yellow-org/sdk-compat:

Enums

  • RPCMethod — RPC method names (Ping, GetConfig, GetChannels, etc.)
  • RPCChannelStatus — Channel status values (Open, Closed, Resizing, Challenged, Closing)

Wire Types

  • MessageSigner(payload: Uint8Array) => Promise<string>
  • NitroliteRPCMessage{ req: [number, string, any, number]; sig: string }
  • RPCResponse{ requestId, method, params }
  • RPCBalance{ asset, amount }
  • RPCAsset{ token, chainId, symbol, decimals }
  • RPCChannelUpdate — Full channel update payload
  • RPCLedgerEntry — Ledger transaction entry
  • AccountID — String alias for account identifiers

Channel Operation Types

  • ContractAddresses{ custody, adjudicator }
  • Allocation{ destination, token, amount }
  • FinalState — Final channel state with signatures
  • ChannelData{ lastValidState, stateData }
  • CreateChannelResponseParams, CloseChannelResponseParams
  • ResizeChannelRequestParams
  • TransferAllocation{ asset, amount }

App Session Types

  • RPCAppDefinition{ application, protocol, participants, weights, quorum, challenge, nonce }
  • RPCAppSessionAllocation{ participant, asset, amount }
  • CloseAppSessionRequestParams

State Channel Primitives

  • Channel — Channel metadata (id, participants, adjudicator, challenge, nonce, version)
  • State — Channel state (channelId, version, data, allocations)
  • AppLogic<T> — Interface for custom app logic implementations

Nitronode Response Types

  • AccountInfo{ balances: LedgerBalance[], channelCount: bigint }
  • LedgerChannel — Full ledger channel record (id, participant, status, token, amount, chain_id, etc.)
  • LedgerBalance{ asset, amount }
  • LedgerEntry — Ledger entry with credit/debit
  • AppSession — App session record
  • ClearNodeAsset{ token, chainId, symbol, decimals }

Advanced Configuration

buildClientOptions

Converts a CompatClientConfig into v1 Option[] values passed to Client.create(). Useful if you need to customise the underlying SDK client beyond what NitroliteClient.create() exposes:

import { buildClientOptions, type CompatClientConfig } from '@yellow-org/sdk-compat';

const opts = buildClientOptions({
  wsURL: 'wss://nitronode.example.com/ws',
  blockchainRPCs: { 11155111: 'https://rpc.sepolia.io' },
});

Next.js Integration Notes

When using the compat package in a Next.js app with Turbopack:

  1. Add to transpilePackages in next.config.ts:
const nextConfig = {
  transpilePackages: ['@yellow-org/sdk', '@yellow-org/sdk-compat'],
};
  1. The package declares "sideEffects": false in its package.json, enabling tree-shaking of unused exports.

Peer Dependencies

| Package | Version | |---|---| | @yellow-org/sdk | >=1.2.0 | | viem | ^2.0.0 |

License

MIT