Python SDK (paynode-sdk-python)
π€ For AI Agents (Client)
The PayNodeAgentClient defaults to Base Mainnet RPCs.
Recommended: On-chain (Router.pay())
Most merchants list On-chain first in their accepts array. Agent submits a transaction via PayNode Router.
import os
from paynode_sdk import PayNodeAgentClient
agent = PayNodeAgentClient(private_key=os.getenv("AGENT_PRIVATE_KEY"))
# SDK picks the first method from merchant's accepts array
response = agent.request_gate("https://api.merchant.com/data")
print(response.json())Alternative: EIP-3009 (Off-chain, Gasless)
If merchant lists EIP-3009 first, agent signs off-chain and merchant submits on-chain.
import os
from paynode_sdk import PayNodeAgentClient
agent = PayNodeAgentClient(private_key=os.getenv("AGENT_PRIVATE_KEY"))
# SDK auto-signs if merchant accepts EIP-3009
response = agent.request_gate("https://api.merchant.com/data")
print(response.json())Manual Control (Advanced)
For custom flows, call payment methods directly:
import os
from paynode_sdk import PayNodeAgentClient
agent = PayNodeAgentClient(private_key=os.getenv("AGENT_PRIVATE_KEY"))
# On-chain: agent pays gas, immediate settlement
tx_hash = agent.pay(
router_addr="0xRouterAddress...",
token_addr="0xUSDCAddress...",
merchant_addr="0xMerchantWallet...",
amount=1000000,
order_id="order_123"
)
# EIP-3009: agent signs, merchant pays gas
payload = agent.sign_transfer_with_authorization(
token_addr="0xUSDCAddress...",
to="0xMerchantWallet...",
amount=1000000,
valid_after=valid_after,
valid_before=valid_before,
nonce=nonce
)πͺ For Merchants (FastAPI)
Defaults to USDC on Base Mainnet.
from fastapi import FastAPI
from paynode_sdk import PayNodeMiddleware
app = FastAPI()
# Minimalist for Mainnet
app.add_middleware(
PayNodeMiddleware,
merchant_address="0xYourWallet...",
price="1.00", # 1.00 USDC
)π‘οΈ Token Whitelist
The Verifier includes a built-in ACCEPTED_TOKENS whitelist per chain to block fake-token attacks.
| Network | Chain ID | Accepted Token (USDC) |
|---|---|---|
| Base Mainnet | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Base Sepolia | 84532 | 0x65c088EfBDB0E03185Dbe8e258Ad0cf4Ab7946b0 (Sandbox) |
Customization
from paynode_sdk import PayNodeVerifier
from paynode_sdk.constants import ACCEPTED_TOKENS, BASE_RPC_URLS
# Auto-detect from chain_id (recommended)
verifier = PayNodeVerifier(
rpc_urls=BASE_RPC_URLS,
chain_id=8453,
# Automatically uses ACCEPTED_TOKENS[8453]
)
# Custom whitelist
verifier = PayNodeVerifier(
rpc_urls=["https://mainnet.base.org"],
chain_id=8453,
accepted_tokens=["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],
)
# Disable whitelist (testing only)
verifier = PayNodeVerifier(
rpc_urls=["http://localhost:8545"],
chain_id=8453,
accepted_tokens=[] # Empty = no whitelist check
)π Thread Safety & Concurrency
The Python SDK uses threading.Lock() for atomic nonce management. When multiple tools/threads send concurrent transactions, nonces are queued and incremented safely β avoiding nonce too low errors.
π Interactive Demo
Join the PayNode developer test loop using the packages/sdk-python/examples/ suite.
1. Configuration (.env)
The demo uses python-dotenv to load settings. Create an .env file:
AGENT_PRIVATE_KEY=your_private_key
MERCHANT_ADDRESS=your_wallet_address
PAYNODE_RPC_URL=https://sepolia.base.org
# Default Router (Base Sepolia)
PAYNODE_CONTRACT_ADDRESS=0x24cD8b68aaC209217ff5a6ef1Bf55a59f2c8Ca6F2. Run the Suite
# Start Merchant Server
python packages/sdk-python/examples/fastapi_server.py
# Run Agent Workspace
python packages/sdk-python/examples/agent_client.pyπ‘ Webhook Notifications
See the dedicated Webhooks page for async event-driven payment notifications.