Django middleware for the x402 'Payment Required' protocol
Project description
django-x402
Django middleware for the x402 "Payment Required" protocol.
Spec Compliance
This implementation follows the x402 exact scheme specification with full support for:
✅ EIP-3009 TransferWithAuthorization - Proper signature verification and transaction encoding
✅ EIP-712 Typed Data Signing - Full domain separation and signature validation
✅ Balance Verification (optional) - Check payer has sufficient ERC20 tokens
✅ Nonce Tracking - Prevent replay attacks by tracking used nonces
✅ Transaction Simulation - Pre-flight validation before broadcasting
Requirements
- Python 3.10 or higher
- Django 5.2 or higher
Install
pip install django-x402
Install from Git (latest/main)
pip install 'django-x402 @ git+https://github.com/yourbuddyconner/django-x402.git@main'
Pin to a tagged release:
pip install 'django-x402 @ git+https://github.com/yourbuddyconner/django-x402.git@v0.1.0'
Configure
Add to MIDDLEWARE after auth/session middleware:
MIDDLEWARE = [
# ...
"django_x402.middleware.X402Middleware",
]
X402 = {
"paths": ["/api/premium/"],
"network": "base-sepolia",
"price": "$0.01",
"pay_to_address": "0xYourAddress",
"mime_type": "application/json",
"description": "Premium API call",
"max_deadline_seconds": 60,
"discoverable": True,
"output_schema": {"type": "json"},
# Facilitator modes: "remote" | "local" | "hybrid"
# Default is "remote" when facilitator_config is provided, else "local"
# "remote" configuration
# "facilitator_config": {"url": "https://your-facilitator"},
# "local" configuration with enhanced verification (spec compliance)
# "mode": "local",
# "local": {
# "private_key_env": "X402_SIGNER_KEY",
# "rpc_url_env": "X402_RPC_URL",
# "verify_balance": True, # Check ERC20 balances
# "simulate_before_send": True, # Simulate transactions before broadcasting
# "wait_for_receipt": False, # Wait for tx confirmation
# },
# Settle policy: "block-on-failure" (default) or "log-and-continue"
# "settle_policy": "block-on-failure",
# Optional replay cache toggle (in-memory)
# "replay_cache_backend": "memory",
}
Security Features
When using local facilitator mode:
- Nonce Tracking: Automatically prevents replay attacks by tracking used nonces in memory
- Balance Verification: Optional check to ensure payer has sufficient funds before accepting payment (requires
verify_balance: True) - Transaction Simulation: Pre-flight validation using eth_call before broadcasting (enabled by default, disable with
simulate_before_send: False)
Development
Run tests:
python -m venv .venv && source .venv/bin/activate
pip install -e '.[tests]'
pytest -q
Optional: Integration test with Anvil (Base mainnet fork)
- Create a
.envwith your fork URL (Base mainnet via a provider):
export ANVIL_FORK_URL="https://base-mainnet.g.alchemy.com/v2/<API_KEY>"
export FORK_URL="$ANVIL_FORK_URL"
- Start Anvil via Docker Compose:
docker compose -f docker-compose.anvil.yml up -d
- Run the integration test (skipped unless
ANVIL_FORK_URLis set):
# Option 1: Use the test environment file
source test.env
pytest tests/test_integration_anvil.py -xvs
# Option 2: Use the helper script (automatically starts/stops Anvil)
./run_integration_test.sh
# Option 3: Set environment variables manually
export ANVIL_FORK_URL="https://mainnet.base.org"
export ANVIL_RPC_URL="http://localhost:8545"
export X402_SIGNER_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
export X402_RPC_URL="http://localhost:8545"
pytest tests/test_integration_anvil.py -xvs
The test.env file contains all necessary environment variables for running the integration tests. The run_integration_test.sh script provides a convenient way to run the tests with automatic Anvil lifecycle management.
Links
- x402 protocol and reference implementation: coinbase/x402
- x402 Specification: Protocol Specification
- EIP-712: Typed structured data hashing/signing: eips.ethereum.org/EIPS/eip-712
- EIP-3009: Transfer With Authorization: eips.ethereum.org/EIPS/eip-3009
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 django_x402-0.0.1.tar.gz.
File metadata
- Download URL: django_x402-0.0.1.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7625bae5f0d55af2ae10eeb64de10046ac9c6c2a03f840d88b50dae372a512af
|
|
| MD5 |
5d99d956a1b7c499c1a44fc6040fd757
|
|
| BLAKE2b-256 |
ef1fa2cddabb0960b732f6faabe27d3ebb0fda108f6ae138d216e6381cbd0cba
|
File details
Details for the file django_x402-0.0.1-py3-none-any.whl.
File metadata
- Download URL: django_x402-0.0.1-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a042ffbbab98fe839237d90218d988b708aa6594328a5dc85ff76ef1b91ee31f
|
|
| MD5 |
418b3d6d8f9daf980986fc76fc41294e
|
|
| BLAKE2b-256 |
af75403ff2fe10efe851436c4159a111c0d76c83ec70d68dc090089d7c2a5d6f
|