Channel Management
Guide for API providers on managing payment channels, including closure and withdrawals.
Channel Closure & Withdrawal
Automatic State-Based Closure (Recommended)
The new close_and_withdraw_from_state
function simplifies channel closure by automatically handling state management:
use pipegate::middleware::{
payment_channel::channel::{close_channel_from_state, ChannelState},
PaymentsState
};
async fn close_and_withdraw_from_state(state: &ChannelState) -> Result<TxHash, Error> {
let payment_state = PaymentsState::new();
let channel_state = payment_state
.channel_state
.clone()
.read()
.await
.as_ref()
.unwrap()
.clone();
let rpc_url = "https://base-sepolia-rpc.publicnode.com"
.parse()
.unwrap();
let private_key = env::var("PRIVATE_KEY")
.expect("PRIVATE_KEY must be set");
let raw_body = Bytes::from("0x");
// Automatically close channel and withdraw funds from current state
let tx_hash = close_channel_from_state(
&channel_state,
rpc_url,
private_key.as_str(),
U256::from(1), // channel_id
raw_body,
).await;
println!("Transaction Hash: {:?}", tx_hash);
Ok(tx_hash)
}
- Automatic Signature Handling: No need to manually track signatures
- State Synchronization: Uses the latest channel state automatically
- Simplified Implementation: Reduces boilerplate code
- Error Reduction: Less chance of using outdated channel information
Manual Channel Closure (Legacy)
For manual control or when you have specific channel details:
use pipegate::middleware::payment_channel::{
channel::{close_channel, ChannelState},
types::PaymentChannel,
};
async fn close_and_withdraw_manual(
payment_channel: PaymentChannel,
signature: PrimitiveSignature,
raw_body: Bytes
) -> Result<TxHash, Error> {
let rpc_url = "https://base-sepolia-rpc.publicnode.com"
.parse()
.unwrap();
let private_key = env::var("PRIVATE_KEY")
.expect("PRIVATE_KEY must be set");
// Close channel and withdraw funds with manual parameters
let tx_hash = close_channel(
rpc_url,
private_key.as_str(),
&payment_channel,
&signature,
raw_body
).await?;
Ok(tx_hash)
}
Channel State Management
// Get channel state
let channel = state.get_channel(channel_id).await?;
// Check channel balance
if channel.balance < required_amount {
return Err(AuthError::InsufficientBalance);
}
// Verify channel expiration
if channel.expiration < current_timestamp {
return Err(AuthError::ChannelExpired);
}
Best Practices
-
Use State-Based Closure
- Prefer
close_and_withdraw_from_state
for automatic state management - Reduces complexity and potential errors
- Automatically uses the latest channel information
- Prefer
-
Regular Withdrawals
- Monitor channel balances periodically
- Withdraw funds before channels expire
- Keep track of active channels
-
Error Handling
- Handle network errors gracefully
- Verify transaction completion
- Implement retry mechanisms for failed transactions
-
Security
- Secure private key storage (use environment variables)
- Validate channel states before operations
- Monitor for suspicious activity
-
State Management
- Be aware that server restarts will lose in-memory state
- Consider implementing state persistence for production
- Plan for graceful degradation when state is lost