Skip to main content
Version: 1.x

TypeScript Compat SDK

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.

Already integrated with @erc7824/nitrolite?

If your app is already built on @erc7824/nitrolite (v0.4 through v0.5.3), you can speed up the migration using the yellow-sdk-codemod tool. It handles the repetitive parts of the upgrade automatically: rewriting imports, migrating client constructors, renaming auth fields, and updating your package.json. Where the change requires context (collapsing RPC call chains, removing manual WebSocket setup), the codemod leaves a // TODO [codemod] comment with the exact replacement so you know what to do.

# Clone the codemod and install its dependencies
git clone https://github.com/layer-3/yellow-sdk-codemod.git
cd yellow-sdk-codemod && npm install

# Scan your project to see what needs changing (no files are modified)
npx tsx src/cli.ts scan --path /path/to/your-app/src

# Apply all transforms and update dependencies
npx tsx src/cli.ts run --path /path/to/your-app --update-deps

After running, search for TODO [codemod] in your codebase and work through the remaining items. See the codemod README for the full list of transforms and CLI options.

Why Use the Compat Layer​

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

Installation​

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

Quick Start​

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

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

// Deposit (creates channel if needed)
await client.deposit(tokenAddress, 11_000_000n);

// Query
const channels = await client.getChannels();
const balances = await client.getBalances();
const sessions = await client.getAppSessionsList();

// Transfer
await client.transfer(recipientAddress, [{ asset: 'usdc', amount: '5.0' }]);

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

Method Cheat Sheet​

Channel Operations​

MethodDescription
deposit(token, amount)Deposit to channel (creates if needed)
depositAndCreateChannel(token, amount)Alias for deposit()
withdrawal(token, amount)Withdraw from channel
closeChannel(params?)Close open channels (optionally for a specific token)
resizeChannel({ allocate_amount, token })Resize an existing channel
challengeChannel({ state })Challenge a channel on-chain
createChannel()No-op in v1 (channel creation is implicit on deposit())

Queries​

MethodDescription
getChannels()List all ledger channels
getChannelData(channelId)Full channel + state for a specific channel
getBalances(wallet?)Get ledger balances
getLedgerEntries(wallet?)Get transaction history
getAppSessionsList(wallet?, status?)List app sessions
getLastAppSessionsListError()Last error from getAppSessionsList() (if any)
getAssetsList()List supported assets
getAccountInfo()Aggregate balance + channel count
getConfig()Node configuration

Transfers​

MethodDescription
transfer(destination, allocations)Off-chain transfer to another participant

App Sessions​

MethodDescription
createAppSession(definition, allocations, quorumSigs?)Create an app session
closeAppSession(appSessionId, allocations, quorumSigs?)Close an app session
submitAppState(params)Submit state update (operate/deposit/withdraw/close)
getAppDefinition(appSessionId)Get session definition

App Session Signing Helpers​

HelperDescription
packCreateAppSessionHash(params)Deterministic hash for createAppSession quorum signing
packSubmitAppStateHash(params)Deterministic hash for submitAppState quorum signing
toWalletQuorumSignature(signature)Prefix wallet signature for app-session quorum format
toSessionKeyQuorumSignature(signature)Prefix session key signature (0xa2) for quorum format

Session Keys​

MethodDescription
signChannelSessionKeyState(state)Sign a channel session-key state
submitChannelSessionKeyState(state)Register channel session-key
getLastChannelKeyStates(userAddress, sessionKey?)Get active channel session-key states
signSessionKeyState(state)Sign an app-session key state
submitSessionKeyState(state)Register app-session key
getLastKeyStates(userAddress, sessionKey?)Get active app-session key states

Asset Resolution​

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

Lifecycle​

MethodDescription
ping()Health check
close()Close the WebSocket connection
refreshAssets()Re-fetch the asset map from the clearnode

Properties​

PropertyTypeDescription
innerClientClient (readonly)The underlying v1.0.0 SDK Client
userAddressAddress (readonly)The connected wallet address

Configuration​

interface NitroliteClientConfig {
wsURL: string; // Clearnode WebSocket URL
walletClient: WalletClient; // viem WalletClient with account
chainId: number; // Chain ID (e.g. 11155111)
blockchainRPCs?: Record<number, string>; // Chain ID → RPC URL map
channelSessionKeySigner?: { // Optional session key for quick approvals
sessionKeyPrivateKey: Hex;
walletAddress: Address;
metadataHash: Hex;
authSig: Hex;
};
}

Environment Variables​

blockchainRPCsFromEnv() reads from NEXT_PUBLIC_BLOCKCHAIN_RPCS:

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

Accessing the v1.0.0 SDK​

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');
await v1Client.checkpoint('usdc');
await v1Client.approveToken(chainId, 'usdc', amount);

Error Handling​

Error ClassCodeDescription
AllowanceErrorALLOWANCE_INSUFFICIENTToken approval needed
UserRejectedErrorUSER_REJECTEDUser cancelled in wallet
InsufficientFundsErrorINSUFFICIENT_FUNDSNot enough balance
NotInitializedErrorNOT_INITIALIZEDClient not connected
import { getUserFacingMessage, AllowanceError } from '@yellow-org/sdk-compat';

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

Event Polling​

v0.5.3 used WebSocket push events. v1.0.0 uses polling. 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);

poller.start();

Next.js Integration​

Add to transpilePackages in next.config.ts:

const nextConfig = {
transpilePackages: ['@yellow-org/sdk', '@yellow-org/sdk-compat'],
};

Migration Guides​