Production-ready Python SDK for Base blockchain with 80% fewer RPC calls, zero-cost ERC-20 decoding, and built-in resilience
Project description
๐ต BasePy SDK - Production-Ready Python SDK for Base Blockchain
The most efficient and reliable way to build on Base (Ethereum Layer 2)
๐ 80% fewer RPC calls - Proven in production
๐ฐ Zero-cost ERC-20 decoding - Extract all token transfers FREE
๐ก๏ธ Battle-tested resilience - Circuit breaker, auto-retry, rate limiting
โก Production-grade - Thread-safe, cached, monitored
๐ฏ Why BasePy?
The Problem with Web3.py
When building production applications on Base, raw Web3.py has limitations:
โ Repetitive boilerplate - Every token balance needs 3+ RPC calls
โ No retry logic - Network errors crash your app
โ No rate limiting - Get blocked by RPC providers
โ Manual optimization - You implement caching yourself
โ Base L2 complexity - Manual L1+L2 fee calculations
The BasePy Solution
โ
Smart batching - Get entire portfolio in 2 RPC calls (vs 10+)
โ
Automatic retry - Exponential backoff with circuit breaker
โ
Built-in rate limiting - Never get blocked
โ
Intelligent caching - 500x faster repeated queries
โ
Base L2 native - L1+L2 fees calculated automatically
โ
Zero-cost features - ERC-20 decoding from existing data
๐ Performance Comparison
Real-world performance (Base Mainnet, December 2024):
| Task | BasePy SDK | Web3.py | Improvement |
|---|---|---|---|
| Portfolio (ETH + 3 tokens) | 2 RPC calls, 1.66s | 10+ RPC calls | 80% fewer calls โ |
| Decode ERC-20 transfers | 0 additional RPC calls | 1+ RPC calls per token | 100% free โ |
| Token metadata (cached) | <1ms response | 300-500ms | 500x faster โ |
| Multicall (4 operations) | 1 RPC call | 4 sequential calls | 75% reduction โ |
Real Cost Impact:
For 1M portfolio checks at typical RPC pricing:
- Web3.py: ~$100 (10 calls ร $0.01/1000)
- BasePy: ~$20 (2 calls ร $0.01/1000)
- You save: $80 per million requests (80% reduction) ๐ฐ
๐ฆ Installation
pip install basepy-sdk
Requirements:
- Python 3.8+
- web3.py >= 6.0.0
- eth-account >= 0.9.0
๐ Quick Start
30 Seconds to Your First Request
from basepy import BaseClient
# Connect to Base Mainnet (or Sepolia testnet)
client = BaseClient() # Mainnet
# client = BaseClient(chain_id=84532) # Sepolia testnet
# Get complete portfolio (ETH + all common tokens)
portfolio = client.get_portfolio_balance("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1")
print(f"Wallet: {portfolio['address']}")
print(f"ETH: {portfolio['eth']['balance_formatted']:.6f}")
print(f"\nTokens with balance:")
for token_addr, info in portfolio['tokens'].items():
if info['balance'] > 0:
print(f" {info['symbol']:6s}: {info['balance_formatted']:>12.6f}")
Output:
Wallet: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1
ETH: 1.234567
Tokens with balance:
USDC : 1000.500000
DAI : 250.000000
RPC calls: 2 (vs 10+ with Web3.py) ๐
๐ Core Features
1. ๐ช Smart Portfolio Tracking
Get ETH + all token balances with minimal RPC calls:
from basepy import BaseClient
client = BaseClient()
# Get portfolio with common Base tokens
portfolio = client.get_portfolio_balance(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
include_common_tokens=True # USDC, DAI, WETH, etc.
)
# Or specify exact tokens
usdc = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
dai = "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
portfolio = client.get_portfolio_balance(
address="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
token_addresses=[usdc, dai]
)
print(f"Total assets: {portfolio['total_assets']}")
print(f"Tokens with balance: {portfolio['non_zero_tokens']}")
Cost: ~2 RPC calls (regardless of token count!) โก
2. ๐ Zero-Cost Transaction Analysis
Extract all ERC-20 transfers without additional RPC calls:
from basepy import BaseClient, Transaction
client = BaseClient()
tx = Transaction(client)
# Get complete transaction details
details = tx.get_full_transaction_details(
"0x123...",
include_token_metadata=True
)
print(f"Status: {details['status']}")
print(f"ETH transferred: {details['eth_value_formatted']} ETH")
print(f"Token transfers: {details['transfer_count']}")
for transfer in details['token_transfers']:
print(f" {transfer['symbol']}: {transfer['amount_formatted']}")
Advanced Analysis:
# Decode ALL ERC-20 transfers (zero cost!)
transfers = tx.decode_erc20_transfers("0x123...")
# Calculate balance changes for an address
changes = tx.get_balance_changes("0x123...", your_address)
print(f"ETH change: {changes['eth_change_formatted']:.6f} ETH")
for token, info in changes['token_changes'].items():
print(f"{info['symbol']}: {info['change_formatted']}")
# Classify transaction type
classification = tx.classify_transaction("0x123...")
print(f"Type: {classification['type']}") # 'swap', 'transfer', etc.
print(f"Complexity: {classification['complexity']}")
Cost: FREE - uses existing receipt data! ๐
3. ๐ธ Send Transactions (Wallet Required)
Simple, production-ready transaction sending:
from basepy import BaseClient, Wallet, Transaction
# Initialize with wallet
client = BaseClient()
wallet = Wallet.from_private_key("0xYourPrivateKey...", client=client)
tx = Transaction(client, wallet)
# Send ETH with automatic gas optimization
tx_hash = tx.send_eth(
to_address="0xRecipient...",
amount=0.1, # 0.1 ETH
gas_strategy='fast', # 'slow', 'standard', 'fast', 'instant'
wait_for_receipt=True # Wait for confirmation
)
print(f"Sent! TX: {tx_hash}")
# Send ERC-20 tokens
from basepy.abis import ERC20_ABI
usdc = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
tx_hash = tx.send_erc20(
token_address=usdc,
to_address="0xRecipient...",
amount=100 * 10**6, # 100 USDC (6 decimals)
abi=ERC20_ABI,
gas_strategy='standard'
)
Features:
- โ Automatic gas estimation with buffer
- โ Nonce management with collision detection
- โ Transaction simulation before sending
- โ Automatic retry with exponential backoff
- โ Balance validation
4. โก Batch & Multicall Operations
Execute multiple operations efficiently:
# Batch get balances
addresses = ["0xAddr1...", "0xAddr2...", "0xAddr3..."]
balances = client.batch_get_balances(addresses)
# Multicall - Multiple contract calls in 1 RPC request
from basepy.abis import ERC20_ABI
usdc = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
calls = [
{'contract': usdc, 'abi': ERC20_ABI, 'function': 'name'},
{'contract': usdc, 'abi': ERC20_ABI, 'function': 'symbol'},
{'contract': usdc, 'abi': ERC20_ABI, 'function': 'decimals'},
{'contract': usdc, 'abi': ERC20_ABI, 'function': 'totalSupply'},
]
results = client.multicall(calls)
print(results) # ['USD Coin', 'USDC', 6, 1234567890...]
Cost: 1 RPC call (vs 4 sequential calls) ๐
5. โฝ Base L2 Fee Calculation
Get complete transaction cost breakdown:
# Estimate total cost (L1 + L2)
cost = client.estimate_total_fee({
'from': wallet.address,
'to': recipient,
'value': 10**18, # 1 ETH
'data': '0x'
})
print(f"L2 execution cost: {cost['l2_fee_eth']:.6f} ETH")
print(f"L1 data cost: {cost['l1_fee_eth']:.6f} ETH")
print(f"Total cost: {cost['total_fee_eth']:.6f} ETH")
# Check if wallet can afford transaction
affordable = wallet.can_afford_transaction(
to=recipient,
value=0.1,
buffer_percent=10
)
print(f"Can afford: {affordable}")
6. ๐ก๏ธ Production-Ready Resilience
Built-in reliability features (no configuration needed):
from basepy import BaseClient, Config
# Advanced configuration (optional)
config = Config()
config.MAX_RETRIES = 5
config.CACHE_TTL = 15 # seconds
config.RATE_LIMIT_REQUESTS = 100 # per minute
config.CIRCUIT_BREAKER_THRESHOLD = 5
client = BaseClient(config=config, environment='production')
# Monitor performance
stats = client.get_metrics()
print(f"Total requests: {sum(stats['requests'].values())}")
print(f"Cache hit rate: {stats['cache_hit_rate']:.1%}")
print(f"Avg latency: {stats['avg_latencies']}")
# Health check
health = client.health_check()
print(f"Status: {health['status']}")
print(f"Block number: {health['block_number']}")
Automatic Features:
- โ Exponential backoff retry
- โ Multiple RPC endpoint failover
- โ Token bucket rate limiting
- โ Circuit breaker pattern
- โ Intelligent TTL caching
- โ Thread-safe operations
- โ Performance monitoring
7. ๐ Complete Wallet Management
from basepy import BaseClient, Wallet
client = BaseClient()
# Create new wallet
wallet = Wallet.create(client)
# Import from private key
wallet = Wallet.from_private_key("0x...", client)
# Import from mnemonic (BIP-39)
wallet = Wallet.from_mnemonic(
"your twelve word mnemonic phrase here...",
client=client,
account_path="m/44'/60'/0'/0/0" # Derivation path
)
# Import from keystore
wallet = Wallet.from_keystore(
path="keystore.json",
password="your-password",
client=client
)
# Export to keystore
wallet.to_keystore(
password="secure-password",
output_path="backup.json"
)
# Wallet operations with caching
balance = wallet.get_balance(use_cache=True)
nonce = wallet.get_nonce(use_cache=True)
portfolio = wallet.get_portfolio(use_cache=True)
# Sign messages (EIP-191)
signature = wallet.sign_message("Hello, Base!")
# Sign typed data (EIP-712)
typed_data = {...}
signature = wallet.sign_typed_data(typed_data)
๐ BasePy vs Web3.py
Feature Comparison
| Feature | BasePy | Web3.py | Winner |
|---|---|---|---|
| Portfolio balance | get_portfolio_balance() (2 calls) |
Manual loops (10+ calls) | BasePy (80% fewer) |
| ERC-20 decoding | decode_erc20_transfers() (0 calls) |
Manual parsing (1+ calls/token) | BasePy (100% free) |
| Multicall | Native multicall() (1 call) |
Sequential (N calls) | BasePy (Nโ1) |
| Retry logic | โ Automatic exponential backoff | โ Manual implementation | BasePy |
| Rate limiting | โ Token bucket built-in | โ Not included | BasePy |
| Circuit breaker | โ Automatic failover | โ Not available | BasePy |
| Caching | โ Intelligent TTL (500x speedup) | โ Manual implementation | BasePy |
| RPC failover | โ Multi-endpoint auto-switch | โ Manual switching | BasePy |
| Thread safety | โ Fully thread-safe | โ ๏ธ Partial | BasePy |
| Base L2 fees | โ Native L1+L2 calculation | โ Manual calculation | BasePy |
| Wallet management | โ Complete (create, import, export, sign) | โ ๏ธ Basic signing only | BasePy |
| Transaction mgmt | โ Nonce collision handling, simulation | โ ๏ธ Basic | BasePy |
| Monitoring | โ Built-in metrics & health checks | โ Not included | BasePy |
| Production ready | โ Battle-tested | โ ๏ธ Requires hardening | BasePy |
Code Comparison
Get portfolio balance:
# โ Web3.py - Verbose, 10+ RPC calls
from web3 import Web3
w3 = Web3(Web3.HTTPProvider(rpc_url))
eth_balance = w3.eth.get_balance(address)
tokens_data = {}
for token in [usdc, dai, weth]:
contract = w3.eth.contract(address=token, abi=ERC20_ABI)
balance = contract.functions.balanceOf(address).call() # Call 1
symbol = contract.functions.symbol().call() # Call 2
decimals = contract.functions.decimals().call() # Call 3
tokens_data[token] = {'balance': balance, 'symbol': symbol, 'decimals': decimals}
# Total: 1 + (3 ร N tokens) = 10+ calls for 3 tokens
# โ
BasePy - Simple, 2 RPC calls
from basepy import BaseClient
client = BaseClient()
portfolio = client.get_portfolio_balance(address, [usdc, dai, weth])
# Total: 2 calls (1 for ETH, 1 multicall for all tokens)
Decode token transfers:
# โ Web3.py - Manual, error-prone
receipt = w3.eth.get_transaction_receipt(tx_hash)
transfers = []
for log in receipt['logs']:
if len(log['topics']) == 3 and log['topics'][0].hex() == TRANSFER_SIG:
token = log['address']
from_addr = '0x' + log['topics'][1].hex()[-40:]
to_addr = '0x' + log['topics'][2].hex()[-40:]
amount = int(log['data'].hex(), 16)
transfers.append({'token': token, 'from': from_addr, 'to': to_addr, 'amount': amount})
# โ
BasePy - Zero extra calls, automatic
from basepy import Transaction
tx = Transaction(client)
transfers = tx.decode_erc20_transfers(tx_hash) # Done!
๐ Complete Examples
Example 1: DeFi Portfolio Tracker
from basepy import BaseClient
def track_portfolio(wallet_address):
client = BaseClient()
portfolio = client.get_portfolio_balance(wallet_address)
print(f"๐ Portfolio for {wallet_address}\n")
print(f"๐ฐ ETH: {portfolio['eth']['balance_formatted']:.6f}")
print(f"\n๐ช Tokens ({portfolio['non_zero_tokens']} with balance):")
for token_addr, info in portfolio['tokens'].items():
if info['balance'] > 0:
print(f" {info['symbol']:8s}: {info['balance_formatted']:>15.6f}")
print(f"\n๐ Summary:")
print(f" Total assets: {portfolio['total_assets']}")
print(f" RPC calls used: ~2 (vs {portfolio['total_assets'] * 3}+ with Web3.py)")
track_portfolio("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1")
Example 2: Transaction Monitor
from basepy import BaseClient, Transaction
def analyze_transaction(tx_hash):
client = BaseClient()
tx = Transaction(client)
# Get full details
details = tx.get_full_transaction_details(tx_hash, include_token_metadata=True)
# Calculate cost
cost = tx.get_transaction_cost(tx_hash)
print(f"๐ Transaction: {tx_hash}")
print(f"Status: {'โ
Success' if details['status'] == 'confirmed' else 'โ Failed'}")
print(f"Block: {details['block_number']}")
print(f"Gas used: {details['gas_used']:,}")
print(f"Total cost: {cost['total_cost_eth']:.6f} ETH")
print(f" L2 execution: {cost['l2_cost_eth']:.6f} ETH")
print(f" L1 data: {cost['l1_cost_eth']:.6f} ETH")
if details['eth_value'] > 0:
print(f"\n๐ธ ETH Transfer: {details['eth_value_formatted']} ETH")
if details['transfer_count'] > 0:
print(f"\n๐ช Token Transfers ({details['transfer_count']}):")
for t in details['token_transfers']:
print(f" {t['symbol']}: {t['amount_formatted']}")
# Classify
classification = tx.classify_transaction(tx_hash)
print(f"\n๐ท๏ธ Type: {classification['type']}")
print(f"Complexity: {classification['complexity']}")
analyze_transaction("0x...")
Example 3: Production Bot with Monitoring
from basepy import BaseClient, Wallet, Transaction
import time
def trading_bot():
# Initialize with monitoring
client = BaseClient(environment='production')
wallet = Wallet.from_private_key(private_key, client)
tx = Transaction(client, wallet)
print("๐ค Trading bot started...")
while True:
try:
# Check health
health = client.health_check()
if health['status'] != 'healthy':
print(f"โ ๏ธ Unhealthy: {health}")
time.sleep(60)
continue
# Get portfolio
portfolio = wallet.get_portfolio(use_cache=True)
# Your trading logic here...
# Monitor performance
metrics = client.get_metrics()
print(f"๐ Cache hit rate: {metrics['cache_hit_rate']:.1%}")
print(f"๐ Avg latency: {metrics['avg_latencies']}")
time.sleep(10)
except Exception as e:
print(f"โ Error: {e}")
time.sleep(30)
trading_bot()
See examples/ for more real-world code!
๐๏ธ Project Structure
basepy-sdk/
โโโ basepy/
โ โโโ __init__.py # Main exports
โ โโโ client.py # BaseClient with all RPC operations
โ โโโ wallet.py # Complete wallet management
โ โโโ transactions.py # Transaction operations
โ โโโ abis.py # Contract ABIs and constants
โ โโโ utils.py # Utility functions
โ โโโ exceptions.py # Custom exceptions
โ
โโโ examples/
โ โโโ basic_usage.py # Simple examples
โ โโโ portfolio_tracker.py # DeFi portfolio tracker
โ โโโ transaction_monitor.py # TX analysis
โ โโโ wallet_demo.py # Complete wallet demo
โ
โโโ tests/
โ โโโ test_client.py # Client tests
โ โโโ test_wallet.py # Wallet tests
โ โโโ test_transactions.py # Transaction tests
โ
โโโ README.md # This file
โโโ LICENSE # MIT License
โโโ setup.py # Package setup
โโโ pyproject.toml # Modern Python config
โโโ requirements.txt # Dependencies
โ๏ธ Configuration
Basic Configuration
from basepy import BaseClient, Config
# Use defaults (recommended)
client = BaseClient()
# Or customize
config = Config()
config.MAX_RETRIES = 5
config.CACHE_TTL = 15
config.RATE_LIMIT_REQUESTS = 100
config.CIRCUIT_BREAKER_THRESHOLD = 5
client = BaseClient(config=config)
Environment-Based Config
# Development (verbose logging)
client = BaseClient(environment='development')
# Production (optimized)
client = BaseClient(environment='production')
Custom RPC Endpoints
# Use your own RPC endpoints
custom_rpcs = [
"https://mainnet.base.org",
"https://base.llamarpc.com",
"https://base.meowrpc.com",
]
client = BaseClient(chain_id=8453, rpc_urls=custom_rpcs)
๐งช Testing
# Install with dev dependencies
pip install -e ".[dev]"
# Run all tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=basepy --cov-report=html
# Run specific test file
pytest tests/test_client.py -v
# Run with benchmarks
pytest tests/test_client.py --benchmark-only
๐ Performance Benchmarks
Tested on Base Mainnet (December 2024):
| Operation | Avg Time | RPC Calls | vs Web3.py |
|---|---|---|---|
| Portfolio (3 tokens) | 1.66s | 2 | 80% fewer calls |
| Decode ERC-20 transfers | <10ms | 0 | 100% free |
| Token metadata (cached) | <1ms | 0 | 500x faster |
| Multicall (4 functions) | ~1s | 1 | 75% fewer calls |
| Health check | ~0.5s | 2 | N/A |
Benchmarks run with pytest-benchmark on Base Mainnet
๐ฃ๏ธ Roadmap
โ Completed (v1.0)
- Core RPC operations
- ERC-20 token support
- Portfolio tracking (80% fewer calls)
- Zero-cost transaction decoding
- Complete wallet management
- Automatic retry & failover
- Rate limiting & circuit breaker
- Intelligent caching
- Base L2 fee calculation
- Thread-safe operations
- Performance monitoring
- Comprehensive testing
๐ Planned (v1.1-1.2)
- ERC-721 (NFT) support
- ERC-1155 (Multi-token) support
- WebSocket support for events
- ENS resolution
- Price oracle integration
- GraphQL support
๐ฎ Future (v2.0+)
- Multi-chain support (Optimism, Arbitrum)
- Advanced DeFi integrations
- MEV protection
- Account abstraction (ERC-4337)
๐ค Contributing
We welcome contributions! Here's how to get started:
# Fork and clone
git clone https://github.com/yourusername/basepy-sdk.git
cd basepy-sdk
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Format code
black basepy/
flake8 basepy/
# Type check
mypy basepy/
Please see CONTRIBUTING.md for detailed guidelines.
๐ License
MIT License - see LICENSE file for details.
TL;DR: Free to use in commercial and personal projects. Just keep the license notice.
๐ Resources
- GitHub: https://github.com/yourusername/basepy-sdk
- Documentation: Full API Reference
- Examples: examples/
- Base Docs: https://docs.base.org
- Issues: https://github.com/yourusername/basepy-sdk/issues
๐ Support
Need help? We're here:
- GitHub Issues: Report bugs or request features
- Discord: Join our community
- Email: support@basepy.dev
- Twitter: @basepy_sdk
๐ Acknowledgments
Built with โค๏ธ for the Base ecosystem:
- Powered by Web3.py
- Inspired by the Ethereum and Base communities
- Thanks to all contributors and users
โญ Star Us!
If BasePy makes your development easier, please star the repository!
It helps others discover the project and motivates us to keep improving.
๐ฏ Quick Links
- ๐ฆ Installation
- ๐ Quick Start
- ๐ Core Features
- ๐ Examples
- ๐ vs Web3.py
- โ๏ธ Configuration
- ๐งช Testing
- ๐ค Contributing
Built for developers who want to focus on building, not debugging RPC calls ๐ต
Making Base blockchain development 10x easier, 10x faster, and 80% cheaper
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file basepy_sdk-1.1.0.tar.gz.
File metadata
- Download URL: basepy_sdk-1.1.0.tar.gz
- Upload date:
- Size: 352.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
295a2d1fe3bb3bb89b9e5f7d48b8d14ef6cace2da0675e3a42cdcb6a6c0d7ac6
|
|
| MD5 |
c4016f4669bcdee7a48a235299607d70
|
|
| BLAKE2b-256 |
331cda00c2e0a0357280e5a875a5de12569c1e352fc3442086f5023af8cd5b80
|
File details
Details for the file basepy_sdk-1.1.0-py3-none-any.whl.
File metadata
- Download URL: basepy_sdk-1.1.0-py3-none-any.whl
- Upload date:
- Size: 72.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1cccf7a44ba1f8fc1ec0e1e71ca1f96714dc6b0b2529c95b3e967b0eeb69b5d
|
|
| MD5 |
f4405131ba8e9f2c529333b9a9981e7f
|
|
| BLAKE2b-256 |
fe450fba096cc4a74911962fa7a56118f488ac18d5252f232a9de37550dc0ca1
|