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.2.0

Published

Compatibility layer bridging Nitrolite SDK v0.5.3 API to v1.0.0, minimising migration effort for existing dApps.

Readme

Nitrolite Compat SDK

License

Compatibility layer that bridges the Nitrolite SDK v0.5.3 API to the v1.0.0 runtime, letting existing dApps upgrade to the new protocol with minimal code changes.

  • Keep v0.5.3-style app-facing calls in your code.
  • Run them through @yellow-org/sdk-compat, backed by @yellow-org/sdk.

Why

The v1.0.0 protocol introduces breaking changes across 14 dimensions — wire format, authentication, WebSocket lifecycle, unit system, asset resolution, and more. A direct migration touches 20+ files per app with deep, scattered rewrites.

The compat layer centralises this complexity into ~1,000 lines that absorb the protocol differences, reducing per-app integration effort by an estimated 56–70%.

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 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://clearnode.example.com/ws',
  walletClient,          // viem WalletClient with account
  chainId: 11155111,     // Sepolia
  blockchainRPCs: blockchainRPCsFromEnv(),
});

2. Deposit & create a channel

In v1.0.0, 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-unit string (smallest denomination). The compat layer divides by token decimals before delegating to the v1 SDK's transfer(wallet, asset, Decimal):

// 5 USDC = 5_000_000 raw units (6 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 | | getActionAllowances(wallet?) | Get gated action allowances for a wallet | | getEscrowChannel(escrowChannelId) | Query an escrow channel by ID | | getChannelData(channelId) | Full channel + state for a specific channel | | getLastAppSessionsListError() | Last getAppSessionsList() error message (if any) |

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 Registry

| Method | Description | |---|---| | getApps(options?) | List registered applications (filter by appId, owner, pagination) | | registerApp(appID, metadata, creationApprovalNotRequired) | Register a new application |

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

| Method | Description | |---|---| | signChannelSessionKeyState(state) | Sign a channel session-key state payload | | submitChannelSessionKeyState(state) | Register/submit a channel session-key state | | getLastChannelKeyStates(userAddress, sessionKey?) | Fetch channel session-key states for wallet/key | | signSessionKeyState(state) | Sign an app-session key state payload | | submitSessionKeyState(state) | Register/submit an app-session key state | | getLastKeyStates(userAddress, sessionKey?) | Fetch app-session key states for wallet/key |

Transfers

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

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 |

Security Token Locking

| Method | Description | |---|---| | lockSecurityTokens(targetWallet, chainId, amount) | Lock tokens into the Locking contract for a target address | | initiateSecurityTokensWithdrawal(chainId) | Start the unlock process for locked tokens | | cancelSecurityTokensWithdrawal(chainId) | Re-lock tokens, cancelling a pending unlock | | withdrawSecurityTokens(chainId, destination) | Withdraw unlocked tokens to a destination address | | approveSecurityToken(chainId, amount) | Approve the Locking contract to spend tokens | | getLockedBalance(chainId, wallet?) | Query locked balance (returns raw bigint) |

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 clearnode |

Accessing the v1.0.0 SDK Directly

The underlying v1.0.0 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;                           // Clearnode 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.0.0 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.0.0 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

Security Token Locking

Lock tokens into the on-chain Locking contract to provide security deposits. The locking token and its decimals are resolved from the contract at runtime — blockchainRPCs must be configured for the target chain or these methods will throw.

const chainId = 11155111; // Sepolia
// Yellow token on Sepolia has 18 decimals; 100 YELLOW = 100 * 10^18
const amount = 100_000_000_000_000_000_000n;

// Approve the Locking contract to spend tokens
await client.approveSecurityToken(chainId, amount);

// Lock tokens for a target address
await client.lockSecurityTokens(targetWallet, chainId, amount);

// Query locked balance (returns raw bigint in token's smallest unit)
const locked = await client.getLockedBalance(chainId);

// Initiate unlock (starts the unlock period)
await client.initiateSecurityTokensWithdrawal(chainId);

// Cancel unlock (re-lock tokens)
await client.cancelSecurityTokensWithdrawal(chainId);

// After unlock period elapses, withdraw to a destination
await client.withdrawSecurityTokens(chainId, destinationWallet);

Amount conventions

The compat layer accepts raw amounts (smallest token unit) and converts to human-readable Decimal before delegating to the v1 SDK.

| Method group | Input type | Example: 100 tokens (18 decimals) | |---|---|---| | deposit, withdrawal, lockSecurityTokens, approveSecurityToken, getLockedBalance | Raw bigint | 100_000_000_000_000_000_000n | | transfer | Raw string via TransferAllocation.amount | '100000000000000000000' |

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

RPC Stubs

The following functions exist so that any remaining v0.5.3 create*Message / parse*Response imports compile. create* helpers are mostly placeholders; parse* helpers perform lightweight normalization of known response shapes. Prefer calling NitroliteClient methods directly for new integrations:

// These compile but do nothing meaningful:
createGetChannelsMessage, parseGetChannelsResponse,
createGetLedgerBalancesMessage, parseGetLedgerBalancesResponse,
parseGetLedgerEntriesResponse, parseGetAppSessionsResponse,
createTransferMessage, createAppSessionMessage, parseCreateAppSessionResponse,
createCloseAppSessionMessage, parseCloseAppSessionResponse,
createCreateChannelMessage, parseCreateChannelResponse,
createCloseChannelMessage, parseCloseChannelResponse,
createResizeChannelMessage, parseResizeChannelResponse,
createPingMessage,
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)

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

Clearnode 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.0.0 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://clearnode.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.0.0 | | viem | ^2.0.0 |

License

MIT