Overview
The SDK can pay for RPC calls with stablecoins through x402 or MPP. This payment lane does not require a Quicknode account, API key, or provisioned endpoint. Configure a payment wallet and the SDK handles the HTTP 402 Payment Required challenge, signs the payment, and resends the RPC request.
The micropayment APIs are available in SDK 0.8.0 for Rust, Python, and Ruby, and 3.8.0 for Node.js.
| Payment path | SDK entry point | Best for |
|---|---|---|
| x402 per request | rpc.call or rpc.callWithReceipt with scheme: "x402" | One-off EVM or Solana payments |
| MPP per request | rpc.call or rpc.callWithReceipt with scheme: "mpp" | One-off payments on Tempo |
| x402 credit drawdown | gatewayAuthenticate then gatewayDrawdownCall | Prepay once and consume credits over many calls |
| MPP payment channel | mppOpen then mppSessionCall | Deposit once and authorize calls with off-chain vouchers |
The payment network is independent of the blockchain you query. For example, Base Sepolia USDC can pay for an Ethereum Mainnet RPC call.
Store only the funds needed for RPC payments in this wallet. Do not log the payment configuration because it contains the raw private key. If a request fails with PaymentIndeterminateError, the payment might have settled; check the wallet before retrying.
Install
Install the SDK for your language. Rust payment support is feature-gated; the other language packages include it in their precompiled binaries.
- Node.js
Python
- Rust
- Ruby
npm install @quicknode/sdk
pip install quicknode-sdk
quicknode-sdk = { version = "0.8", features = ["payments", "payments-svm", "payments-tempo"] }
Use payments for x402 on EVM, add payments-svm for x402 on Solana, and add payments-tempo for MPP. The Tempo feature requires Rust 1.93 or newer.
gem install quicknode_sdk
Pay per request
Set the following payment fields on the RPC configuration:
| Field | Description |
|---|---|
scheme | x402 or mpp |
key | Raw private key: EVM/Tempo hex or Solana base58 64-byte secret |
payNetwork | Payment network as a CAIP-2 identifier, such as eip155:84532 |
asset | Token contract address or Solana mint accepted by the gateway |
maxAmount | Required spend ceiling in the asset's integer base units |
The examples below configure x402 on Base Sepolia. Change scheme, payNetwork, and asset to an offered MPP payment option to use MPP instead.
- Node.js
Python
- Rust
- Ruby
import { QuicknodeSdk } from '@quicknode/sdk'
const qn = new QuicknodeSdk({
rpc: {
payment: {
scheme: 'x402',
key: process.env.QN_PAYMENT_KEY!,
payNetwork: 'eip155:84532',
asset: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
maxAmount: '10000',
},
},
})
const blockNumber = await qn.rpc.call('eth_blockNumber', [], 'ethereum-mainnet')
console.log(blockNumber)
import asyncio
import os
from quicknode_sdk import PaymentConfig, QuicknodeSdk, RpcConfig, SdkFullConfig
async def main():
qn = QuicknodeSdk(SdkFullConfig(
api_key=None,
rpc=RpcConfig(payment=PaymentConfig(
scheme="x402",
key=os.environ["QN_PAYMENT_KEY"],
pay_network="eip155:84532",
asset="0x036CbD53842c5426634e7929541eC2318f3dCF7e",
max_amount="10000",
)),
))
block_number = await qn.rpc.call("eth_blockNumber", [], "ethereum-mainnet")
print(block_number)
if __name__ == "__main__":
asyncio.run(main())
use quicknode_sdk::{PaymentConfig, QuicknodeSdk, RpcConfig, SdkFullConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut config = SdkFullConfig::keyless();
config.rpc = Some(RpcConfig {
payment: Some(PaymentConfig {
scheme: "x402".into(),
key: std::env::var("QN_PAYMENT_KEY")?,
pay_network: "eip155:84532".into(),
asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e".into(),
max_amount: "10000".into(),
svm_rpc_url: None,
base_url_override: None,
}),
..Default::default()
});
let qn = QuicknodeSdk::new(&config)?;
let block_number = qn
.rpc
.call("eth_blockNumber", None, Some("ethereum-mainnet".into()), None)
.await?;
println!("{block_number}");
Ok(())
}
require "quicknode_sdk"
sdk = QuicknodeSdk::SDK.from_config(
api_key: nil,
rpc: {
payment: {
scheme: "x402",
key: ENV.fetch("QN_PAYMENT_KEY"),
pay_network: "eip155:84532",
asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
max_amount: "10000"
}
}
)
block_number = sdk.rpc.call(
method: "eth_blockNumber",
params: [],
network: "ethereum-mainnet"
)
puts block_number
Use callWithReceipt in Node.js, or call_with_receipt in the other bindings, when you also need settlement metadata. MPP returns the settlement transaction hash in the receipt; the x402 receipt is null.
maxAmount is a safety ceiling, not the amount to send. It is expressed in integer base units of the selected asset, and the SDK refuses any payment offer above it before signing.
Generate a wallet
The SDK can generate an EVM, Solana, or Tempo wallet offline. It returns the private key once and does not store or recover it.
- Node.js
Python
- Rust
- Ruby
import { generatePaymentWallet } from '@quicknode/sdk'
const wallet = generatePaymentWallet('evm')
console.log('Fund this address:', wallet.address)
// Persist wallet.key securely now. It cannot be recovered later.
from quicknode_sdk import generate_payment_wallet
wallet = generate_payment_wallet("evm")
print("Fund this address:", wallet["address"])
use quicknode_sdk::{generate_payment_wallet, ChainKind};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wallet = generate_payment_wallet(ChainKind::Evm)?;
println!("Fund this address: {}", wallet.address);
std::fs::write("payment.key", wallet.into_key())?;
Ok(())
}
require "quicknode_sdk"
wallet = QuicknodeSdk.generate_payment_wallet(chain: "evm")
puts "Fund this address: #{wallet[:address]}"
Use evm for x402 EVM payments and MPP on Tempo, or svm for x402 on Solana.
Use x402 credit drawdown
Credit drawdown authenticates the wallet once, purchases prepaid credits, and consumes one credit per successful RPC response. Persist the returned gateway session between processes.
const session = await qn.rpc.gatewayAuthenticate()
const balance = await qn.rpc.gatewayCredits(session)
console.log('Credits:', balance.credits)
const blockNumber = await qn.rpc.gatewayDrawdownCall(
'eth_blockNumber',
session,
'ethereum-mainnet'
)
For Base Sepolia testing, gatewayDrip(session) funds the payment wallet once. It returns the funding transaction hash, not a credit balance. Solana wallets must be funded separately.
Use an MPP payment channel
An MPP channel deposits funds into escrow once, then authorizes calls with cumulative off-chain vouchers. Persist the channel state after every successful operation.
const channel = await qn.rpc.mppOpen('1000000')
const newTotal = (
BigInt(channel.cumulativeSpent) + BigInt(channel.perCall)
).toString()
const blockNumber = await qn.rpc.mppSessionCall(
'eth_blockNumber',
'ethereum-mainnet',
channel,
newTotal
)
// After success, persist the channel with cumulativeSpent set to newTotal.
Use mppTopUp to add funds and mppClose to settle the channel and refund its unused deposit. mppStatus consumes one request unit because the gateway prices every session request; persist its updated cumulative spend too.
The gateway cannot reconstruct a lost local MPP channel record. Advance cumulativeSpent only after a successful call and persist the updated channel immediately.
Next steps
- Review x402 Payments for supported payment networks, assets, and gateway behavior.
- Review MPP Payments for charge and session payment details.