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:
| Error | Common cause | Recovery |
|---|---|---|
| Insufficient allowance | checkpoint() needs ERC-20 approval before the first deposit. | Call approveToken(chainId, asset, amount), then retry checkpoint(asset). |
| Ongoing transition | A 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 RPC | withBlockchainRPC(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 supported | The 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 found | The 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
- Void: No channel exists
- Create:
deposit()creates channel on-chain viacheckpoint() - Open: Channel active; can deposit, withdraw, transfer
- Challenged: Dispute initiated (advanced)
- 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
- API Reference: Full method documentation
- Configuration: Client options and error handling
- Examples: Complete working examples