Advanced Usage
This section covers advanced topics for working with the @erc7824/nitrolite
SDK. These are intended for developers who need deeper control over the state channel operations or want to integrate with specialized systems.
Available Topics
Low-level Services
The NitroliteClient is built on top of specialized services that can be used directly for more fine-grained control:
- NitroliteService - Core service for interacting with the custody contract and managing channels
- Erc20Service - Service for interacting with ERC20 tokens
Account Abstraction Integration
- Abstract Accounts - Using NitroliteClient with ERC-4337 Account Abstraction for smart contract wallets
When to Use Advanced Features
Consider using the advanced features when:
- Building custom workflows that require more control than the high-level NitroliteClient API provides
- Integrating with smart contract wallets or other account abstraction systems
- Implementing specialized monitoring or management systems for state channels
- Developing cross-chain applications that require custom handling of state channel operations
- Optimizing gas usage through transaction batching and other techniques
Example: Direct Service Usage
While using the high-level NitroliteClient is recommended for most applications, here's how you can work directly with the services:
import {
NitroliteService,
Erc20Service,
getChannelId,
signState
} from '@erc7824/nitrolite';
// Initialize services
const nitroliteService = new NitroliteService(
publicClient,
addresses,
walletClient,
account.address
);
const erc20Service = new Erc20Service(
publicClient,
walletClient
);
// Check token allowance
const allowance = await erc20Service.getTokenAllowance(
tokenAddress,
account.address,
addresses.custody
);
// Approve tokens if needed
if (allowance < depositAmount) {
await erc20Service.approve(tokenAddress, addresses.custody, depositAmount);
}
// Deposit funds
await nitroliteService.deposit(tokenAddress, depositAmount);
// Create channel with custom parameters
const channelNonce = generateChannelNonce(account.address);
const channel = {
participants: [account.address, counterpartyAddress],
adjudicator: addresses.adjudicator,
challenge: 100n, // Challenge duration in seconds
nonce: channelNonce
};
// Prepare initial state
const initialState = {
intent: StateIntent.INITIALIZE,
version: 0n,
data: '0x1234', // Application-specific data
allocations: [
{ destination: account.address, token: tokenAddress, amount: 700000n },
{ destination: counterpartyAddress, token: tokenAddress, amount: 300000n }
],
sigs: [] // Will be filled with signatures
};
// Sign the state
const channelId = getChannelId(channel);
const stateHash = getStateHash(channelId, initialState);
const signature = await signState(walletClient, stateHash);
initialState.sigs = [signature];
// Create the channel
await nitroliteService.createChannel(channel, initialState);
Example: Complex Transaction Preparation
For applications using Account Abstraction, you can prepare complex transaction sequences:
import { NitroliteClient, NitroliteTransactionPreparer } from '@erc7824/nitrolite';
// Initialize client
const client = new NitroliteClient({/* config */});
// Access the transaction preparer directly
const txPreparer = client.txPreparer;
// Prepare a complete sequence (approve, deposit, create channel)
const allTxs = [];
// 1. Check and prepare token approval if needed
const allowance = await client.getTokenAllowance();
if (allowance < depositAmount) {
const approveTx = await txPreparer.prepareApproveTokensTransaction(depositAmount);
allTxs.push(approveTx);
}
// 2. Prepare deposit
const depositTx = await txPreparer.prepareDepositTransactions(depositAmount);
allTxs.push(...depositTx);
// 3. Prepare channel creation
const createChannelTx = await txPreparer.prepareCreateChannelTransaction({
initialAllocationAmounts: [700000n, 300000n],
stateData: '0x1234'
});
allTxs.push(createChannelTx);
// 4. Use with your Account Abstraction provider
await aaProvider.sendUserOperation({
userOperations: allTxs.map(tx => ({
target: tx.to,
data: tx.data,
value: tx.value || 0n
}))
});
These advanced techniques give you greater flexibility and control over the state channel operations, but they also require a deeper understanding of the underlying protocol.