Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ DEFAULT_POSTAGE_AMOUNT=1000000000
# X402_ENABLED=true

# Your wallet private key (keep secret!)
# SWARM_X402_PRIVATE_KEY=0x...
# X402_PRIVATE_KEY=0x...

# Network: "base-sepolia" (testnet, default) or "base" (mainnet)
# X402_NETWORK=base-sepolia
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ Uses python-dotenv for environment configuration:

**x402 Payment Configuration**:
- `X402_ENABLED`: Enable x402 payment support (default: false)
- `SWARM_X402_PRIVATE_KEY`: Wallet private key for signing payments
- `X402_PRIVATE_KEY`: Wallet private key for signing payments
- `X402_NETWORK`: `base-sepolia` (testnet) or `base` (mainnet)
- `X402_AUTO_PAY`: Enable auto-pay without prompts (default: false)
- `X402_MAX_AUTO_PAY_USD`: Maximum auto-pay amount per request (default: 1.00)
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ x402 enables pay-per-request payments using USDC on Base chain. When the gateway
pip install -e .[x402]

# Configure wallet (testnet)
export SWARM_X402_PRIVATE_KEY=0x... # Your wallet private key
export X402_PRIVATE_KEY=0x... # Your wallet private key
export X402_ENABLED=true
export X402_NETWORK=base-sepolia # Testnet (default)

Expand Down Expand Up @@ -145,7 +145,7 @@ swarm-prov-upload x402 info
| Environment Variable | Description | Default |
|---------------------|-------------|---------|
| `X402_ENABLED` | Enable x402 payments | `false` |
| `SWARM_X402_PRIVATE_KEY` | Wallet private key (keep secret!) | - |
| `X402_PRIVATE_KEY` | Wallet private key (keep secret!) | - |
| `X402_NETWORK` | `base-sepolia` (testnet) or `base` (mainnet) | `base-sepolia` |
| `X402_AUTO_PAY` | Auto-pay without prompts | `false` |
| `X402_MAX_AUTO_PAY_USD` | Maximum auto-pay amount per request | `1.00` |
Expand All @@ -164,7 +164,7 @@ swarm-prov-upload x402 info

1. **Get testnet ETH** (for gas): https://www.alchemy.com/faucets/base-sepolia
2. **Get testnet USDC**: https://faucet.circle.com/
3. **Configure wallet**: Set `SWARM_X402_PRIVATE_KEY` with your wallet's private key
3. **Configure wallet**: Set `X402_PRIVATE_KEY` with your wallet's private key

See [docs/x402-setup.md](docs/x402-setup.md) for detailed setup instructions.

Expand Down Expand Up @@ -794,7 +794,7 @@ See [examples/README.md](examples/README.md) for the full guide.
│ │ └─────────────────────────────┘ │ │ │ │
│ │ │ │ x402 Configuration: │ │
│ │ x402 Payment Models: │ │ • X402_ENABLED │ │
│ │ • X402PaymentOption │ │ • SWARM_X402_PRIVATE_KEY │ │
│ │ • X402PaymentOption │ │ • X402_PRIVATE_KEY │ │
│ │ • X402PaymentRequirements │ │ • X402_NETWORK │ │
│ │ • X402PaymentPayload │ │ • X402_AUTO_PAY │ │
│ │ │ │ • X402_MAX_AUTO_PAY_USD │ │
Expand Down
6 changes: 3 additions & 3 deletions docs/x402-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Add to your `.env` file:
X402_ENABLED=true

# Your wallet private key (KEEP SECRET!)
SWARM_X402_PRIVATE_KEY=0x...your_private_key_here...
X402_PRIVATE_KEY=0x...your_private_key_here...

# Network: base-sepolia (testnet) or base (mainnet)
X402_NETWORK=base-sepolia
Expand Down Expand Up @@ -217,9 +217,9 @@ pip install -e .[x402]

### "No private key configured"

Set the `SWARM_X402_PRIVATE_KEY` environment variable:
Set the `X402_PRIVATE_KEY` environment variable:
```bash
export SWARM_X402_PRIVATE_KEY=0x...
export X402_PRIVATE_KEY=0x...
```

### "Insufficient USDC balance"
Expand Down
4 changes: 2 additions & 2 deletions swarm_provenance_uploader/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,7 @@ def x402_info():
typer.echo(" - Export private key (starts with 0x)")

typer.echo("\n2. Set environment variable:")
typer.echo(" export SWARM_X402_PRIVATE_KEY=0x...")
typer.echo(" export X402_PRIVATE_KEY=0x...")

typer.echo("\n3. Get testnet funds (for testing):")
typer.echo(" - ETH (gas): https://www.alchemy.com/faucets/base-sepolia")
Expand Down Expand Up @@ -2349,7 +2349,7 @@ def main(
Use --backend local for direct Bee node communication.

For pay-per-request mode, use --x402 to enable x402 payments.
Requires SWARM_X402_PRIVATE_KEY environment variable.
Requires X402_PRIVATE_KEY environment variable.
"""
if backend:
if backend not in ("gateway", "local"):
Expand Down
2 changes: 1 addition & 1 deletion swarm_provenance_uploader/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

# Environment variable name that contains the private key
# The actual private key should be in this env var, not in config
X402_PRIVATE_KEY_ENV = os.getenv("X402_PRIVATE_KEY_ENV", "SWARM_X402_PRIVATE_KEY")
X402_PRIVATE_KEY_ENV = os.getenv("X402_PRIVATE_KEY_ENV", "X402_PRIVATE_KEY")

# Network: "base-sepolia" (testnet, default) or "base" (mainnet)
X402_NETWORK = os.getenv("X402_NETWORK", "base-sepolia")
Expand Down
2 changes: 1 addition & 1 deletion swarm_provenance_uploader/core/x402_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def __init__(
self._private_key = private_key or os.getenv("X402_PRIVATE_KEY") or os.getenv("SWARM_X402_PRIVATE_KEY")
if not self._private_key:
raise X402ConfigurationError(
"x402 private key not configured. Set X402_PRIVATE_KEY or SWARM_X402_PRIVATE_KEY environment variable."
"x402 private key not configured. Set X402_PRIVATE_KEY environment variable."
)

# Validate and derive address
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ def test_x402_info_shows_setup_guide(self):

assert result.exit_code == 0
assert "x402 Payment Setup Guide" in result.stdout
assert "SWARM_X402_PRIVATE_KEY" in result.stdout
assert "X402_PRIVATE_KEY" in result.stdout
assert "faucet" in result.stdout.lower()


Expand Down
12 changes: 6 additions & 6 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

For x402 tests:
- Base Sepolia wallet with USDC
- SWARM_X402_PRIVATE_KEY environment variable set
- X402_PRIVATE_KEY environment variable set

For blockchain tests:
- Local Hardhat node at http://localhost:8545 with DataProvenance deployed
Expand Down Expand Up @@ -91,7 +91,7 @@ def is_gateway_available():

def is_x402_configured():
"""Check if x402 wallet is configured."""
private_key = os.getenv("SWARM_X402_PRIVATE_KEY")
private_key = os.getenv("X402_PRIVATE_KEY")
return private_key is not None and private_key.startswith("0x")


Expand All @@ -107,7 +107,7 @@ def are_x402_deps_installed():

skip_if_no_x402 = pytest.mark.skipif(
not is_x402_configured() or not are_x402_deps_installed(),
reason="x402 not configured (SWARM_X402_PRIVATE_KEY not set or deps missing)"
reason="x402 not configured (X402_PRIVATE_KEY not set or deps missing)"
)


Expand Down Expand Up @@ -220,7 +220,7 @@ class TestX402Integration:
"""Integration tests for x402 payment functionality.

These tests require:
- SWARM_X402_PRIVATE_KEY environment variable set
- X402_PRIVATE_KEY environment variable set
- x402 dependencies installed (pip install -e .[x402])
- Base Sepolia wallet with USDC (from faucet.circle.com)
"""
Expand Down Expand Up @@ -420,7 +420,7 @@ def test_gateway_client_with_x402_enabled(self, gateway_url):
"""Test GatewayClient initializes with x402 enabled."""
from swarm_provenance_uploader.core.gateway_client import GatewayClient

private_key = os.getenv("SWARM_X402_PRIVATE_KEY")
private_key = os.getenv("X402_PRIVATE_KEY")

client = GatewayClient(
base_url=gateway_url,
Expand Down Expand Up @@ -476,7 +476,7 @@ def test_stamp_purchase_with_x402(self, gateway_url):
from swarm_provenance_uploader.core.x402_client import X402Client
from swarm_provenance_uploader.exceptions import PaymentTransactionFailedError

private_key = os.getenv("SWARM_X402_PRIVATE_KEY")
private_key = os.getenv("X402_PRIVATE_KEY")

# Get balance before payment
x402_client = X402Client(private_key=private_key, network="base-sepolia")
Expand Down
10 changes: 5 additions & 5 deletions tests/test_x402_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
@pytest.fixture
def mock_eth_deps():
"""Mock eth-account and web3 dependencies."""
with patch.dict(os.environ, {"SWARM_X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
with patch.dict(os.environ, {"X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
# Mock eth_account
mock_account = MagicMock()
mock_account.address = DUMMY_ADDRESS
Expand Down Expand Up @@ -263,7 +263,7 @@ def test_balance_sufficient(self, mock_eth_deps):

def test_balance_insufficient(self):
"""Tests balance check when insufficient."""
with patch.dict(os.environ, {"SWARM_X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
with patch.dict(os.environ, {"X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
# Mock eth_account
mock_account = MagicMock()
mock_account.address = DUMMY_ADDRESS
Expand Down Expand Up @@ -367,7 +367,7 @@ def test_create_payment_header_with_balance_check(self, mock_eth_deps):

def test_create_payment_header_insufficient_balance(self):
"""Tests payment header creation fails with insufficient balance."""
with patch.dict(os.environ, {"SWARM_X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
with patch.dict(os.environ, {"X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
# Mock eth_account
mock_account = MagicMock()
mock_account.address = DUMMY_ADDRESS
Expand Down Expand Up @@ -500,7 +500,7 @@ def test_private_key_without_0x_prefix(self):
"""Tests that private key without 0x prefix is handled."""
key_without_prefix = "a" * 64 # No 0x prefix

with patch.dict(os.environ, {"SWARM_X402_PRIVATE_KEY": key_without_prefix}):
with patch.dict(os.environ, {"X402_PRIVATE_KEY": key_without_prefix}):
mock_account = MagicMock()
mock_account.address = DUMMY_ADDRESS

Expand Down Expand Up @@ -535,7 +535,7 @@ class TestX402ClientErrorHandling:

def test_rpc_connection_failure(self):
"""Tests handling of RPC connection failures during balance check."""
with patch.dict(os.environ, {"SWARM_X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
with patch.dict(os.environ, {"X402_PRIVATE_KEY": DUMMY_PRIVATE_KEY}):
mock_account = MagicMock()
mock_account.address = DUMMY_ADDRESS

Expand Down