Skip to main content
Version: 1.x

Getting Started with @yellow-org/sdk

The TypeScript SDK for Nitronode payment channels provides both high-level and low-level operations in a unified client.

:::tip Migrating from v0.5.3? If you are migrating from the published @erc7824/[email protected] package, you do not have to use the compat layer. Migrate directly to @yellow-org/sdk when you can update call sites now, or use @yellow-org/sdk-compat first when you need a smaller staged migration. Older internal docs may refer to the same 0.5.3 codebase as @layer-3/nitrolite; use the published package name when auditing app dependencies. :::

Installation

npm install @yellow-org/sdk
# or
yarn add @yellow-org/sdk
# or
pnpm add @yellow-org/sdk

Requirements

  • Node.js 20.0.0 or later
  • TypeScript 5.3.0 or later (for development)
  • A running Nitronode instance or access to a public node
  • A blockchain RPC endpoint for on-chain operations via checkpoint()

Quick Start

:::info Sandbox URL - coming soon Use your Nitronode WebSocket URL in the Client.create() call below. The public sandbox URL is intentionally shown as <sandbox-url-coming-soon> until the canonical host is pinned. :::

import { Client, createSigners, withBlockchainRPC } from '@yellow-org/sdk';
import Decimal from 'decimal.js';

async function main() {
// 1. Create signers from private key
const { stateSigner, txSigner } = createSigners(
process.env.PRIVATE_KEY as `0x${string}`
);

// 2. Create unified client
const client = await Client.create(
'<sandbox-url-coming-soon>',
stateSigner,
txSigner,
withBlockchainRPC(80002n, 'https://polygon-amoy.alchemy.com/v2/KEY')
);

try {
// 3. Build and co-sign deposit state off-chain
const state = await client.deposit(80002n, 'usdc', new Decimal(100));
console.log('Deposit state version:', state.version);

// 4. Settle on-chain via checkpoint
const txHash = await client.checkpoint('usdc');
console.log('On-chain tx:', txHash);

// 5. Transfer (off-chain only, no checkpoint needed)
const transferState = await client.transfer(
'0xRecipient...',
'usdc',
new Decimal(50)
);

// 6. Low-level operations on the same client
const config = await client.getConfig();
const balances = await client.getBalances(client.getUserAddress());
} finally {
await client.close();
}
}

main().catch(console.error);

Creating a Client

The Client is the single entry point for all operations.

import {
Client,
createSigners,
withBlockchainRPC,
withHandshakeTimeout,
} from '@yellow-org/sdk';

// Step 1: Create signers from private key
const { stateSigner, txSigner } = createSigners('0x1234...');

// Step 2: Create unified client
const client = await Client.create(
wsURL,
stateSigner, // For signing channel states
txSigner, // For signing blockchain transactions
withBlockchainRPC(chainId, rpcURL), // Required for checkpoint()
withHandshakeTimeout(10000), // Optional: connection timeout
);

// Step 3: (Optional) Set home blockchain for assets
// Required for transfer() operations that may trigger channel creation
await client.setHomeBlockchain('usdc', 80002n);

Errors and Recovery

The SDK README keeps the full error catalogue. These are the failures most builders should handle in their first integration:

ErrorCommon causeRecovery
Insufficient allowancecheckpoint() needs ERC-20 approval before the first deposit.Call approveToken(chainId, asset, amount), then retry checkpoint(asset).
Ongoing transitionA previous state transition is waiting for acknowledgement or settlement.Query the latest state, acknowledge pending funds when needed, or wait for the in-flight checkpoint.
Missing RPCwithBlockchainRPC(chainId, rpcURL) was not configured for an on-chain operation.Add the RPC option for every chain you deposit, withdraw, approve, or checkpoint on.
Asset not supportedThe Nitronode config does not list the requested asset on the selected chain.Call getAssets(chainId) and use one of the returned asset symbols.
Channel not foundThe wallet has no home channel or no signed state for that asset yet.Deposit first, or call setHomeBlockchain(asset, chainId) before a transfer that may create the home channel.

Signer Types

The SDK provides two signer types:

EthereumMsgSigner (for channel states)

Signs channel state updates with EIP-191 "Ethereum Signed Message" prefix. Used for all off-chain operations.

import { EthereumMsgSigner } from '@yellow-org/sdk';
import { privateKeyToAccount } from 'viem/accounts';

// From private key
const signer = new EthereumMsgSigner('0x...');

// From viem account
const account = privateKeyToAccount('0x...');
const signer2 = new EthereumMsgSigner(account);

EthereumRawSigner (for blockchain transactions)

Signs raw hashes directly without prefix. Used for on-chain operations like deposits, withdrawals, and channel creation.

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

const signer = new EthereumRawSigner('0x...');

createSigners() Helper

Creates both signers from a single private key:

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

const { stateSigner, txSigner } = createSigners('0x...');

Key Concepts

Two-Step Pattern

Payment channels use versioned states signed by both user and node:

// Step 1: Build and co-sign state off-chain
const state = await client.deposit(chainId, 'usdc', amount);

// Step 2: Settle on-chain (when needed)
const txHash = await client.checkpoint('usdc');

Channel Lifecycle

  1. Void: No channel exists
  2. Create: deposit() creates channel on-chain via checkpoint()
  3. Open: Channel active; can deposit, withdraw, transfer
  4. Challenged: Dispute initiated (advanced)
  5. Closed: Channel finalized (advanced)

TypeScript Conventions

// Use bigint literals for chain IDs
const polygonAmoy = 80002n;

// Use Decimal.js for amounts
import Decimal from 'decimal.js';
const amount = new Decimal(100);

// Viem Address type for wallet addresses
import type { Address } from 'viem';
const wallet: Address = '0x1234...';

Next Steps