Skip to main content
Version: 1.x

Examples

Basic Deposit and Transfer

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

async function basicExample() {
const { stateSigner, txSigner } = createSigners(process.env.PRIVATE_KEY!);

const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner,
withBlockchainRPC(80002n, process.env.RPC_URL!)
);

try {
console.log('User:', client.getUserAddress());

await client.setHomeBlockchain('usdc', 80002n);

// Step 1: Build and co-sign deposit state
const depositState = await client.deposit(80002n, 'usdc', new Decimal(100));
console.log('Deposit state version:', depositState.version);

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

// Check balance
const balances = await client.getBalances(client.getUserAddress());
console.log('Balances:', balances);

// Transfer 50 USDC (off-chain, no checkpoint needed)
const transferState = await client.transfer(
'0xRecipient...',
'usdc',
new Decimal(50)
);
console.log('Transfer state version:', transferState.version);
} finally {
await client.close();
}
}

Multi-Chain Operations

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

async function multiChainExample() {
const { stateSigner, txSigner } = createSigners(process.env.PRIVATE_KEY!);

const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner,
withBlockchainRPC(80002n, process.env.POLYGON_RPC!),
withBlockchainRPC(11155111n, process.env.SEPOLIA_RPC!)
);

try {
await client.setHomeBlockchain('usdc', 80002n);
await client.setHomeBlockchain('eth', 11155111n);

// Deposit on different chains
await client.deposit(80002n, 'usdc', new Decimal(100));
await client.checkpoint('usdc');

await client.deposit(11155111n, 'eth', new Decimal(0.1));
await client.checkpoint('eth');

const balances = await client.getBalances(client.getUserAddress());
balances.forEach(b => console.log(`${b.asset}: ${b.balance}`));
} finally {
await client.close();
}
}

Transaction History with Pagination

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

async function queryTransactions() {
const { stateSigner, txSigner } = createSigners(process.env.PRIVATE_KEY!);
const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner
);

try {
const wallet = client.getUserAddress();
const result = await client.getTransactions(wallet, {
page: 1,
pageSize: 10,
});

console.log(`Total: ${result.metadata.totalCount}`);
console.log(`Page ${result.metadata.page} of ${result.metadata.pageCount}`);

result.transactions.forEach((tx, i) => {
console.log(`${i + 1}. ${tx.txType}: ${tx.amount} ${tx.asset}`);
});
} finally {
await client.close();
}
}

App Session Workflow

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

async function appSessionExample() {
const { stateSigner, txSigner } = createSigners(process.env.PRIVATE_KEY!);
const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner,
withBlockchainRPC(80002n, process.env.RPC_URL!)
);

try {
const definition = {
applicationId: 'chess-v1',
participants: [
{ walletAddress: client.getUserAddress(), signatureWeight: 1 },
{ walletAddress: '0xOpponent...', signatureWeight: 1 },
],
quorum: 2,
nonce: 1n,
};

const { appSessionId } = await client.createAppSession(
definition,
'{}',
['sig1', 'sig2']
);
console.log('Session created:', appSessionId);

// Deposit to app session
const appUpdate = {
appSessionId,
intent: 1,
version: 1n,
allocations: [{
participant: client.getUserAddress(),
asset: 'usdc',
amount: new Decimal(50),
}],
sessionData: '{}',
};

const nodeSig = await client.submitAppSessionDeposit(
appUpdate,
['sig1'],
'usdc',
new Decimal(50)
);
console.log('Deposit signature:', nodeSig);

const { sessions } = await client.getAppSessions({
wallet: client.getUserAddress(),
});
console.log(`Found ${sessions.length} sessions`);
} finally {
await client.close();
}
}

Browser Wallet Integration (viem)

The example-app demonstrates using viem WalletClient (e.g. MetaMask) instead of private keys. You need to implement the StateSigner and TransactionSigner interfaces:

import {
Client,
ChannelDefaultSigner,
type StateSigner,
type TransactionSigner,
withBlockchainRPC,
} from '@yellow-org/sdk';
import { createWalletClient, custom, type WalletClient } from 'viem';
import { sepolia } from 'viem/chains';

// Adapt viem WalletClient to SDK's StateSigner (EIP-191 signatures)
class WalletStateSigner implements StateSigner {
constructor(private wc: WalletClient) {}

async sign(payload: Uint8Array): Promise<string> {
return this.wc.signMessage({
account: this.wc.account!,
message: { raw: payload },
});
}

getAddress(): string {
return this.wc.account!.address;
}
}

// Adapt viem WalletClient to SDK's TransactionSigner
class WalletTransactionSigner implements TransactionSigner {
constructor(private wc: WalletClient) {}

async sign(payload: Uint8Array): Promise<string> {
return this.wc.signTypedData({
account: this.wc.account!,
domain: { name: 'Nitrolite', version: '1', chainId: 1 },
types: { Nitrolite: [{ name: 'operation', type: 'bytes' }] },
primaryType: 'Nitrolite',
message: { operation: `0x${Buffer.from(payload).toString('hex')}` },
});
}

getAddress(): string {
return this.wc.account!.address;
}
}

async function connectWithWallet() {
const walletClient = createWalletClient({
chain: sepolia,
transport: custom(window.ethereum!),
});

const [address] = await walletClient.requestAddresses();
const stateSigner = new ChannelDefaultSigner(new WalletStateSigner(walletClient));
const txSigner = new WalletTransactionSigner(walletClient);

const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner,
withBlockchainRPC(11155111n, 'https://rpc.sepolia.io'),
);

return client;
}

Allowance Handling

On-chain operations like checkpoint() require ERC-20 token approval. The example-app pattern detects allowance errors and retries after approval:

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

const MAX_APPROVE = new Decimal('1000000000');

async function depositWithApproval(
client: Client,
chainId: bigint,
asset: string,
amount: Decimal,
) {
await client.deposit(chainId, asset, amount);

try {
await client.checkpoint(asset);
} catch (error: any) {
const msg = error?.message ?? '';
if (msg.includes('allowance') || msg.includes('insufficient')) {
await client.approveToken(chainId, asset, MAX_APPROVE);
await client.checkpoint(asset);
} else {
throw error;
}
}
}

Channel Session Keys

Session keys let users delegate signing authority so operations don't require repeated wallet prompts. From the example-app:

import {
Client,
ChannelSessionKeyStateSigner,
getChannelSessionKeyAuthMetadataHashV1,
type ChannelSessionKeyStateV1,
} from '@yellow-org/sdk';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';

async function setupSessionKey(client: Client) {
const skPrivateKey = generatePrivateKey();
const skAccount = privateKeyToAccount(skPrivateKey);
const userAddress = client.getUserAddress();

const assets = ['usdc'];
const expiresAt = String(Math.floor(Date.now() / 1000) + 86400); // 24h

// Check existing version
const existing = await client.getLastChannelKeyStates(userAddress, skAccount.address);
const version = existing.length > 0
? String(Number(existing[0].version) + 1)
: '1';

const state: ChannelSessionKeyStateV1 = {
user_address: userAddress,
session_key: skAccount.address,
version,
assets,
expires_at: expiresAt,
user_sig: '0x',
};

// Sign and submit
const sig = await client.signChannelSessionKeyState(state);
state.user_sig = sig;
await client.submitChannelSessionKeyState(state);

// Compute metadata hash for creating a session-key-based signer
const metadataHash = getChannelSessionKeyAuthMetadataHashV1(
BigInt(version),
assets,
BigInt(expiresAt),
);

// Rebuild client with session key signer (no more wallet prompts)
const sessionSigner = new ChannelSessionKeyStateSigner(
skPrivateKey,
userAddress as `0x${string}`,
metadataHash,
sig,
);

return { sessionSigner, skPrivateKey, metadataHash, authSig: sig };
}

Connection Monitoring

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

async function monitorConnection() {
const { stateSigner, txSigner } = createSigners(process.env.PRIVATE_KEY!);

const client = await Client.create(
'wss://clearnode.example.com/ws',
stateSigner,
txSigner,
withErrorHandler((error) => {
console.error('Connection error:', error);
})
);

client.waitForClose().then(() => {
console.log('Connection closed, reconnecting...');
});

const config = await client.getConfig();
console.log('Connected to:', config.nodeAddress);

await new Promise(resolve => setTimeout(resolve, 30000));
await client.close();
}