Payment Channels
Payment channels are ideal for frequent API calls, allowing you to deposit once and make multiple requests without additional gas fees.
How it works & Architecture
For API Users
Create Payment Channel
import { ClientInterceptor } from "pipegate-sdk";
const pipeGate = new ClientInterceptor();
// Update these params with what you get from the API provider
const channelParams = {
recipient: "0x...", // API provider's address
duration: 2592000, // 30 days
tokenAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // USDC
amount: "100", // 100 USDC
};
const channel = await pipeGate.createPaymentChannel(channelParams);
await pipeGate.addNewChannel(channel.channelId, channel);
or If you want to use the cast CLI tool, refer to the steps here
Setup API Client
const api = axios.create({
baseURL: "https://api.example.com",
});
api.interceptors.request.use(
pipeGate.createPaymentChannelRequestInterceptor(channelId).request
);
api.interceptors.response.use(
pipeGate.createPaymentChannelResponseInterceptor().response
);
Monitor Channel State
const channelState = pipeGate.getChannelState(channelId);
console.log("Balance:", channelState?.balance);
console.log("Expiration:", channelState?.expiration);
For API Providers
Configure Middleware
use pipegate::middleware::payment_channel::{channel::ChannelState, types::PaymentChannelConfig};
use pipegate::utils::{Address, Url, U256};
let rpc_url: Url = "https://base-rpc.publicnode.com".parse().unwrap();
let state = ChannelState::new();
let config = PaymentChannelConfig {
recipient: Address::from_str("YOUR_ADDRESS").unwrap(),
token_address: Address::from_str("USDC_ADDRESS").unwrap(),
amount: U256::from(1000), // 0.001 USDC in this case
rpc_url: rpc_url.to_string(),
};
Attach Middleware layer
use pipegate::middleware::payment_channel::{PaymentChannelMiddlewareLayer};
let app = Router::new()
.route("/", get(root))
.layer(PaymentChannelMiddlewareLayer::new(state, config));
Register Price in Channel Factory
Terminal
# Set your price per request (1000 = 0.001 USDC)
cast send $FACTORY_ADDRESS "register(uint256)" 1000 \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
Handle Channel Closure
// Close channel and withdraw funds
let tx_hash = close_channel(
rpc_url,
private_key.as_str(),
&payment_channel,
&signature,
raw_body,
);
or use CLI to close the channel
Terminal
# Close the channel to withdraw 1 USDC with a nonce of 1000, along with the signature received during the API calls
cast send $FACTORY_ADDRESS "close(uint256 channelBalance,uint256 nonce,bytes calldata rawBody,bytes calldata signature)" 1000 1000 0x0 $SIGNATURE \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
Example for channel closure can be found here
Best Practices
- Always monitor channel balance
- Set appropriate channel duration
- Handle channel expiration gracefully
- Implement proper error handling