"""The ERC-4337 bundler is off unless BUNDLER_ENABLED, and only then needs a key.""" import pytest from httpx import ASGITransport, AsyncClient from bootnode.config import Settings, get_settings from bootnode.main import app BODY = {"jsonrpc": "2.0", "method": "eth_supportedEntryPoints", "params": [], "id": 1} def production(**kw) -> Settings: return Settings(_env_file=None, app_env="production", **kw) def test_production_starts_without_bundler_key_when_bundler_off(): production(jwt_secret="j", api_key_salt="s").validate_production() def test_production_requires_bundler_key_when_bundler_on(): s = production(jwt_secret="j", api_key_salt="s", bundler_enabled=True) with pytest.raises(RuntimeError, match=r"secrets: BUNDLER_PRIVATE_KEY$"): s.validate_production() def test_production_accepts_bundler_on_with_key(): production( jwt_secret="j", api_key_salt="s", bundler_enabled=True, bundler_private_key="0x1" ).validate_production() def test_production_still_requires_jwt_secret_and_api_key_salt(): with pytest.raises(RuntimeError, match=r"secrets: JWT_SECRET, API_KEY_SALT$"): production().validate_production() @pytest.fixture async def client(): async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as ac: yield ac async def test_bundler_route_is_503_when_off(client: AsyncClient): assert get_settings().bundler_enabled is False for path in ("/v1/bundler/ethereum", "/v1/bundler/ethereum/sepolia"): r = await client.post(path, json=BODY) assert r.status_code == 503 assert r.json()["detail"] == "ERC-4337 bundler is disabled on this deployment" async def test_bundler_route_reaches_auth_when_on(client: AsyncClient, monkeypatch): monkeypatch.setattr(get_settings(), "bundler_enabled", True) r = await client.post("/v1/bundler/ethereum", json=BODY) assert r.status_code == 401