Skip to content

Commit a152c91

Browse files
committed
feat: add signer_required to SilverbackBot
1 parent 938721e commit a152c91

File tree

3 files changed

+83
-2
lines changed

3 files changed

+83
-2
lines changed

silverback/main.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,15 @@ class SilverbackBot(ManagerAccessMixin):
109109
... # Connection has been initialized, can call broker methods e.g. `bot.on_(...)`
110110
"""
111111

112-
def __init__(self, settings: Settings | None = None):
112+
def __init__(self, settings: Settings | None = None, signer_required: bool = False):
113113
"""
114114
Create bot
115115
116116
Args:
117117
settings (~:class:`silverback.settings.Settings` | None): Settings override.
118118
Defaults to environment settings.
119+
signer_required (bool): If True, raise at startup when no signer is configured.
120+
Defaults to False.
119121
"""
120122
if not settings:
121123
settings = Settings()
@@ -153,7 +155,11 @@ def __init__(self, settings: Settings | None = None):
153155

154156
atexit.register(provider_context.__exit__, None, None, None)
155157

158+
self.signer_required = signer_required
156159
self.signer = settings.get_signer()
160+
if self.signer_required and not self.signer:
161+
raise NoSignerLoaded()
162+
157163
if self.signer:
158164
# NOTE: Monkeypatch `AccountAPI.call` to update bot nonce tracking state
159165
original_call = self.signer.call
@@ -437,7 +443,7 @@ def broker_task_decorator(
437443

438444
# Register user function as task handler with our broker
439445
def add_taskiq_task(
440-
handler: Callable[..., Any | Awaitable[Any]]
446+
handler: Callable[..., Any | Awaitable[Any]],
441447
) -> AsyncTaskiqDecoratedTask:
442448
labels: dict[str, str] = dict()
443449

tests/conftest.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import contextlib
2+
from types import SimpleNamespace
3+
14
import pytest
25
from click.testing import CliRunner
36

@@ -12,3 +15,53 @@ def runner():
1215
@pytest.fixture
1316
def cli():
1417
return root_cli
18+
19+
20+
class Settings:
21+
def __init__(self, signer=None):
22+
self._signer = signer
23+
self.BOT_NAME = "bot"
24+
self.NEW_BLOCK_TIMEOUT = None
25+
self.FORK_MODE = False
26+
27+
def get_provider_context(self):
28+
return contextlib.nullcontext(
29+
SimpleNamespace(
30+
network=SimpleNamespace(
31+
name="mainnet",
32+
ecosystem=SimpleNamespace(name="ethereum"),
33+
),
34+
network_manager=SimpleNamespace(fork=contextlib.nullcontext()),
35+
)
36+
)
37+
38+
def get_broker(self):
39+
def register_task(*_a, **_k):
40+
return object()
41+
42+
def on_event(*_a, **_k):
43+
def deco(fn):
44+
return fn
45+
46+
return deco
47+
48+
return SimpleNamespace(register_task=register_task, on_event=on_event)
49+
50+
def get_signer(self):
51+
return self._signer
52+
53+
def model_dump(self):
54+
return {}
55+
56+
57+
@pytest.fixture
58+
def signer():
59+
return SimpleNamespace(nonce=0, call=lambda txn, *a, **k: {"ok": True})
60+
61+
62+
@pytest.fixture
63+
def settings():
64+
def _make(signer=None):
65+
return Settings(signer=signer)
66+
67+
return _make

tests/test_bot_init.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
from silverback import SilverbackBot
4+
from silverback.exceptions import NoSignerLoaded
5+
6+
7+
def test_signer_required_with_signer_available(settings, signer):
8+
bot = SilverbackBot(settings=settings(signer), signer_required=True)
9+
assert bot.signer_required is True
10+
assert bot.signer is signer
11+
assert hasattr(bot.signer, "call")
12+
13+
14+
def test_signer_required_raises_when_no_signer(settings):
15+
with pytest.raises(NoSignerLoaded):
16+
SilverbackBot(settings=settings(None), signer_required=True)
17+
18+
19+
def test_signer_not_required_default(settings):
20+
bot = SilverbackBot(settings=settings(None))
21+
assert bot.signer_required is False
22+
assert bot.signer is None

0 commit comments

Comments
 (0)