iwa 0.0.0__py3-none-any.whl → 0.0.1a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- conftest.py +22 -0
- iwa/__init__.py +1 -0
- iwa/__main__.py +6 -0
- iwa/core/__init__.py +1 -0
- iwa/core/chain/__init__.py +68 -0
- iwa/core/chain/errors.py +47 -0
- iwa/core/chain/interface.py +514 -0
- iwa/core/chain/manager.py +38 -0
- iwa/core/chain/models.py +128 -0
- iwa/core/chain/rate_limiter.py +193 -0
- iwa/core/cli.py +210 -0
- iwa/core/constants.py +28 -0
- iwa/core/contracts/__init__.py +1 -0
- iwa/core/contracts/contract.py +297 -0
- iwa/core/contracts/erc20.py +79 -0
- iwa/core/contracts/multisend.py +71 -0
- iwa/core/db.py +317 -0
- iwa/core/keys.py +361 -0
- iwa/core/mnemonic.py +385 -0
- iwa/core/models.py +344 -0
- iwa/core/monitor.py +209 -0
- iwa/core/plugins.py +45 -0
- iwa/core/pricing.py +91 -0
- iwa/core/services/__init__.py +17 -0
- iwa/core/services/account.py +57 -0
- iwa/core/services/balance.py +113 -0
- iwa/core/services/plugin.py +88 -0
- iwa/core/services/safe.py +392 -0
- iwa/core/services/transaction.py +172 -0
- iwa/core/services/transfer/__init__.py +166 -0
- iwa/core/services/transfer/base.py +260 -0
- iwa/core/services/transfer/erc20.py +247 -0
- iwa/core/services/transfer/multisend.py +386 -0
- iwa/core/services/transfer/native.py +262 -0
- iwa/core/services/transfer/swap.py +326 -0
- iwa/core/settings.py +95 -0
- iwa/core/tables.py +60 -0
- iwa/core/test.py +27 -0
- iwa/core/tests/test_wallet.py +255 -0
- iwa/core/types.py +59 -0
- iwa/core/ui.py +99 -0
- iwa/core/utils.py +59 -0
- iwa/core/wallet.py +380 -0
- iwa/plugins/__init__.py +1 -0
- iwa/plugins/gnosis/__init__.py +5 -0
- iwa/plugins/gnosis/cow/__init__.py +6 -0
- iwa/plugins/gnosis/cow/quotes.py +148 -0
- iwa/plugins/gnosis/cow/swap.py +403 -0
- iwa/plugins/gnosis/cow/types.py +20 -0
- iwa/plugins/gnosis/cow_utils.py +44 -0
- iwa/plugins/gnosis/plugin.py +68 -0
- iwa/plugins/gnosis/safe.py +157 -0
- iwa/plugins/gnosis/tests/test_cow.py +227 -0
- iwa/plugins/gnosis/tests/test_safe.py +100 -0
- iwa/plugins/olas/__init__.py +5 -0
- iwa/plugins/olas/constants.py +106 -0
- iwa/plugins/olas/contracts/activity_checker.py +93 -0
- iwa/plugins/olas/contracts/base.py +10 -0
- iwa/plugins/olas/contracts/mech.py +49 -0
- iwa/plugins/olas/contracts/mech_marketplace.py +43 -0
- iwa/plugins/olas/contracts/service.py +215 -0
- iwa/plugins/olas/contracts/staking.py +403 -0
- iwa/plugins/olas/importer.py +736 -0
- iwa/plugins/olas/mech_reference.py +135 -0
- iwa/plugins/olas/models.py +110 -0
- iwa/plugins/olas/plugin.py +243 -0
- iwa/plugins/olas/scripts/test_full_mech_flow.py +259 -0
- iwa/plugins/olas/scripts/test_simple_lifecycle.py +74 -0
- iwa/plugins/olas/service_manager/__init__.py +60 -0
- iwa/plugins/olas/service_manager/base.py +113 -0
- iwa/plugins/olas/service_manager/drain.py +336 -0
- iwa/plugins/olas/service_manager/lifecycle.py +839 -0
- iwa/plugins/olas/service_manager/mech.py +322 -0
- iwa/plugins/olas/service_manager/staking.py +530 -0
- iwa/plugins/olas/tests/conftest.py +30 -0
- iwa/plugins/olas/tests/test_importer.py +128 -0
- iwa/plugins/olas/tests/test_importer_error_handling.py +349 -0
- iwa/plugins/olas/tests/test_mech_contracts.py +85 -0
- iwa/plugins/olas/tests/test_olas_contracts.py +249 -0
- iwa/plugins/olas/tests/test_olas_integration.py +561 -0
- iwa/plugins/olas/tests/test_olas_models.py +144 -0
- iwa/plugins/olas/tests/test_olas_view.py +258 -0
- iwa/plugins/olas/tests/test_olas_view_actions.py +137 -0
- iwa/plugins/olas/tests/test_olas_view_modals.py +120 -0
- iwa/plugins/olas/tests/test_plugin.py +70 -0
- iwa/plugins/olas/tests/test_plugin_full.py +212 -0
- iwa/plugins/olas/tests/test_service_lifecycle.py +150 -0
- iwa/plugins/olas/tests/test_service_manager.py +1065 -0
- iwa/plugins/olas/tests/test_service_manager_errors.py +208 -0
- iwa/plugins/olas/tests/test_service_manager_flows.py +497 -0
- iwa/plugins/olas/tests/test_service_manager_mech.py +135 -0
- iwa/plugins/olas/tests/test_service_manager_rewards.py +360 -0
- iwa/plugins/olas/tests/test_service_manager_validation.py +145 -0
- iwa/plugins/olas/tests/test_service_staking.py +342 -0
- iwa/plugins/olas/tests/test_staking_integration.py +269 -0
- iwa/plugins/olas/tests/test_staking_validation.py +109 -0
- iwa/plugins/olas/tui/__init__.py +1 -0
- iwa/plugins/olas/tui/olas_view.py +952 -0
- iwa/tools/check_profile.py +67 -0
- iwa/tools/release.py +111 -0
- iwa/tools/reset_env.py +111 -0
- iwa/tools/reset_tenderly.py +362 -0
- iwa/tools/restore_backup.py +82 -0
- iwa/tui/__init__.py +1 -0
- iwa/tui/app.py +174 -0
- iwa/tui/modals/__init__.py +5 -0
- iwa/tui/modals/base.py +406 -0
- iwa/tui/rpc.py +63 -0
- iwa/tui/screens/__init__.py +1 -0
- iwa/tui/screens/wallets.py +749 -0
- iwa/tui/tests/test_app.py +125 -0
- iwa/tui/tests/test_rpc.py +139 -0
- iwa/tui/tests/test_wallets_refactor.py +30 -0
- iwa/tui/tests/test_widgets.py +123 -0
- iwa/tui/widgets/__init__.py +5 -0
- iwa/tui/widgets/base.py +100 -0
- iwa/tui/workers.py +42 -0
- iwa/web/dependencies.py +76 -0
- iwa/web/models.py +76 -0
- iwa/web/routers/accounts.py +115 -0
- iwa/web/routers/olas/__init__.py +24 -0
- iwa/web/routers/olas/admin.py +169 -0
- iwa/web/routers/olas/funding.py +135 -0
- iwa/web/routers/olas/general.py +29 -0
- iwa/web/routers/olas/services.py +378 -0
- iwa/web/routers/olas/staking.py +341 -0
- iwa/web/routers/state.py +65 -0
- iwa/web/routers/swap.py +617 -0
- iwa/web/routers/transactions.py +153 -0
- iwa/web/server.py +155 -0
- iwa/web/tests/test_web_endpoints.py +713 -0
- iwa/web/tests/test_web_olas.py +430 -0
- iwa/web/tests/test_web_swap.py +103 -0
- iwa-0.0.1a2.dist-info/METADATA +234 -0
- iwa-0.0.1a2.dist-info/RECORD +186 -0
- iwa-0.0.1a2.dist-info/entry_points.txt +2 -0
- iwa-0.0.1a2.dist-info/licenses/LICENSE +21 -0
- iwa-0.0.1a2.dist-info/top_level.txt +4 -0
- tests/legacy_cow.py +248 -0
- tests/legacy_safe.py +93 -0
- tests/legacy_transaction_retry_logic.py +51 -0
- tests/legacy_tui.py +440 -0
- tests/legacy_wallets_screen.py +554 -0
- tests/legacy_web.py +243 -0
- tests/test_account_service.py +120 -0
- tests/test_balance_service.py +186 -0
- tests/test_chain.py +490 -0
- tests/test_chain_interface.py +210 -0
- tests/test_cli.py +139 -0
- tests/test_contract.py +195 -0
- tests/test_db.py +180 -0
- tests/test_drain_coverage.py +174 -0
- tests/test_erc20.py +95 -0
- tests/test_gnosis_plugin.py +111 -0
- tests/test_keys.py +449 -0
- tests/test_legacy_wallet.py +1285 -0
- tests/test_main.py +13 -0
- tests/test_mnemonic.py +217 -0
- tests/test_modals.py +109 -0
- tests/test_models.py +213 -0
- tests/test_monitor.py +202 -0
- tests/test_multisend.py +84 -0
- tests/test_plugin_service.py +119 -0
- tests/test_pricing.py +143 -0
- tests/test_rate_limiter.py +199 -0
- tests/test_reset_tenderly.py +202 -0
- tests/test_rpc_view.py +73 -0
- tests/test_safe_coverage.py +139 -0
- tests/test_safe_service.py +168 -0
- tests/test_service_manager_integration.py +61 -0
- tests/test_service_manager_structure.py +31 -0
- tests/test_service_transaction.py +176 -0
- tests/test_staking_router.py +71 -0
- tests/test_staking_simple.py +31 -0
- tests/test_tables.py +76 -0
- tests/test_transaction_service.py +161 -0
- tests/test_transfer_multisend.py +179 -0
- tests/test_transfer_native.py +220 -0
- tests/test_transfer_security.py +93 -0
- tests/test_transfer_structure.py +37 -0
- tests/test_transfer_swap_unit.py +155 -0
- tests/test_ui_coverage.py +66 -0
- tests/test_utils.py +53 -0
- tests/test_workers.py +91 -0
- tools/verify_drain.py +183 -0
- __init__.py +0 -2
- hello.py +0 -6
- iwa-0.0.0.dist-info/METADATA +0 -10
- iwa-0.0.0.dist-info/RECORD +0 -6
- iwa-0.0.0.dist-info/top_level.txt +0 -2
- {iwa-0.0.0.dist-info → iwa-0.0.1a2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Error handling tests for Olas ServiceManager."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import MagicMock, patch
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from iwa.plugins.olas.contracts.staking import StakingState
|
|
8
|
+
from iwa.plugins.olas.models import Service
|
|
9
|
+
from iwa.plugins.olas.service_manager import ServiceManager, ServiceState
|
|
10
|
+
|
|
11
|
+
VALID_ADDR = "0x1234567890123456789012345678901234567890"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture
|
|
15
|
+
def mock_wallet():
|
|
16
|
+
"""Create a mock wallet for tests."""
|
|
17
|
+
wallet = MagicMock()
|
|
18
|
+
wallet.master_account.address = VALID_ADDR
|
|
19
|
+
wallet.chain_interface.chain_name = "gnosis"
|
|
20
|
+
wallet.sign_and_send_transaction.return_value = (True, {"transactionHash": b"\x00" * 32})
|
|
21
|
+
wallet.key_storage.create_account.return_value.address = VALID_ADDR
|
|
22
|
+
wallet.key_storage.get_account.return_value.address = VALID_ADDR
|
|
23
|
+
return wallet
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def setup_manager(mock_wallet):
|
|
27
|
+
"""Setup a ServiceManager with mocked dependencies."""
|
|
28
|
+
with patch("iwa.plugins.olas.service_manager.base.Config") as mock_cfg_cls:
|
|
29
|
+
mock_cfg = mock_cfg_cls.return_value
|
|
30
|
+
mock_cfg.plugins = {"olas": MagicMock()}
|
|
31
|
+
mock_cfg.plugins["olas"].get_service.return_value = None
|
|
32
|
+
with patch(
|
|
33
|
+
"iwa.plugins.olas.service_manager.OLAS_CONTRACTS",
|
|
34
|
+
{
|
|
35
|
+
"gnosis": {
|
|
36
|
+
"OLAS_SERVICE_REGISTRY": VALID_ADDR,
|
|
37
|
+
"OLAS_SERVICE_MANAGER": VALID_ADDR,
|
|
38
|
+
"OLAS_MECH": VALID_ADDR,
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
):
|
|
42
|
+
with patch("iwa.plugins.olas.service_manager.base.ChainInterfaces") as mock_if_cls:
|
|
43
|
+
mock_if = mock_if_cls.return_value
|
|
44
|
+
mock_if.get.return_value.chain.name.lower.return_value = "gnosis"
|
|
45
|
+
mock_if.get.return_value.get_contract_address.return_value = VALID_ADDR
|
|
46
|
+
manager = ServiceManager(mock_wallet)
|
|
47
|
+
manager.registry = MagicMock()
|
|
48
|
+
manager.manager_contract = MagicMock()
|
|
49
|
+
manager.olas_config = mock_cfg.plugins["olas"]
|
|
50
|
+
manager.chain_name = "gnosis"
|
|
51
|
+
manager.registry.chain_interface.get_contract_address.return_value = VALID_ADDR
|
|
52
|
+
return manager
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_service_manager_mech_requests_failures(mock_wallet):
|
|
56
|
+
"""Test failure paths in mech requests."""
|
|
57
|
+
manager = setup_manager(mock_wallet)
|
|
58
|
+
|
|
59
|
+
# Service missing
|
|
60
|
+
manager.service = None
|
|
61
|
+
assert manager.send_mech_request(b"data") is None
|
|
62
|
+
|
|
63
|
+
manager.service = Service(
|
|
64
|
+
service_name="t",
|
|
65
|
+
chain_name="gnosis",
|
|
66
|
+
service_id=1,
|
|
67
|
+
agent_ids=[1],
|
|
68
|
+
multisig_address=VALID_ADDR,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Marketplace failures
|
|
72
|
+
with patch("iwa.plugins.olas.service_manager.mech.MechMarketplaceContract") as mock_mkt_cls:
|
|
73
|
+
mock_mkt = mock_mkt_cls.return_value
|
|
74
|
+
|
|
75
|
+
# No marketplace address
|
|
76
|
+
with patch("iwa.plugins.olas.service_manager.OLAS_CONTRACTS", {"gnosis": {}}):
|
|
77
|
+
assert manager.send_mech_request(b"data", use_marketplace=True) is None
|
|
78
|
+
|
|
79
|
+
# No priority_mech
|
|
80
|
+
assert manager.send_mech_request(b"data", use_marketplace=True, priority_mech=None) is None
|
|
81
|
+
|
|
82
|
+
# Invalid priority mech factory
|
|
83
|
+
mock_mkt.call.return_value = "0x0000000000000000000000000000000000000000"
|
|
84
|
+
assert (
|
|
85
|
+
manager.send_mech_request(b"data", use_marketplace=True, priority_mech=VALID_ADDR)
|
|
86
|
+
is None
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# No priority mech factory multisig
|
|
90
|
+
mock_mkt.call.side_effect = ["0x1234", "0x0000000000000000000000000000000000000000"]
|
|
91
|
+
assert (
|
|
92
|
+
manager.send_mech_request(b"data", use_marketplace=True, priority_mech=VALID_ADDR)
|
|
93
|
+
is None
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Legacy failures
|
|
97
|
+
# Legacy mech address missing
|
|
98
|
+
with patch("iwa.plugins.olas.service_manager.OLAS_CONTRACTS", {"gnosis": {}}):
|
|
99
|
+
assert manager.send_mech_request(b"data", use_marketplace=False) is None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_service_manager_lifecycle_failures(mock_wallet):
|
|
103
|
+
"""Test failure paths in lifecycle methods."""
|
|
104
|
+
manager = setup_manager(mock_wallet)
|
|
105
|
+
manager.service = Service(service_name="t", chain_name="gnosis", service_id=1, agent_ids=[1])
|
|
106
|
+
|
|
107
|
+
# register_agent failures
|
|
108
|
+
# Initial state mismatch for agent registration
|
|
109
|
+
manager.registry.get_service.return_value = {"state": ServiceState.PRE_REGISTRATION}
|
|
110
|
+
assert manager.register_agent() is False
|
|
111
|
+
|
|
112
|
+
# stake failures
|
|
113
|
+
# Initial state mismatch for staking
|
|
114
|
+
manager.service.staking_contract_address = VALID_ADDR
|
|
115
|
+
manager.registry.get_service.return_value = {"state": ServiceState.PRE_REGISTRATION}
|
|
116
|
+
mock_staking = MagicMock()
|
|
117
|
+
mock_staking.staking_token_address = VALID_ADDR
|
|
118
|
+
mock_staking.get_requirements.return_value = {
|
|
119
|
+
"staking_token": VALID_ADDR,
|
|
120
|
+
"min_staking_deposit": 50000000000000000000,
|
|
121
|
+
"num_agent_instances": 1,
|
|
122
|
+
"required_agent_bond": 50000000000000000000,
|
|
123
|
+
}
|
|
124
|
+
with patch("iwa.plugins.olas.service_manager.staking.ERC20Contract"):
|
|
125
|
+
assert manager.stake(mock_staking) is False
|
|
126
|
+
|
|
127
|
+
# unstake failures
|
|
128
|
+
# Service not staked
|
|
129
|
+
manager.service.staking_contract_address = None
|
|
130
|
+
mock_staking = MagicMock()
|
|
131
|
+
mock_staking.get_staking_state.return_value = StakingState.NOT_STAKED
|
|
132
|
+
assert manager.unstake(mock_staking) is False
|
|
133
|
+
|
|
134
|
+
# unbond failures
|
|
135
|
+
# Event missing in unbond
|
|
136
|
+
manager.registry.get_service.return_value = {"state": ServiceState.TERMINATED_BONDED}
|
|
137
|
+
mock_wallet.sign_and_send_transaction.return_value = (True, {"transactionHash": b"hex"})
|
|
138
|
+
manager.registry.extract_events.return_value = []
|
|
139
|
+
# manager.manager is what is used in unbond (line 523)
|
|
140
|
+
manager.manager = MagicMock()
|
|
141
|
+
assert manager.unbond() is False
|
|
142
|
+
|
|
143
|
+
# spin_up/wind_down failure log lines
|
|
144
|
+
manager.registry.get_service.return_value = {"state": ServiceState.DEPLOYED}
|
|
145
|
+
assert manager.spin_up() is True
|
|
146
|
+
|
|
147
|
+
manager.registry.get_service.return_value = {"state": ServiceState.PRE_REGISTRATION}
|
|
148
|
+
assert manager.wind_down() is True
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_service_manager_staking_status_failures(mock_wallet):
|
|
152
|
+
"""Test failure paths in get_staking_status."""
|
|
153
|
+
manager = setup_manager(mock_wallet)
|
|
154
|
+
|
|
155
|
+
# Service missing
|
|
156
|
+
manager.service = None
|
|
157
|
+
assert manager.get_staking_status() is None
|
|
158
|
+
|
|
159
|
+
manager.service = Service(service_name="t", chain_name="gnosis", service_id=1, agent_ids=[1])
|
|
160
|
+
# Staking contract missing
|
|
161
|
+
manager.service.staking_contract_address = None
|
|
162
|
+
status = manager.get_staking_status()
|
|
163
|
+
assert status.is_staked is False
|
|
164
|
+
|
|
165
|
+
# Exception in contract loading
|
|
166
|
+
manager.service.staking_contract_address = VALID_ADDR
|
|
167
|
+
with patch("iwa.plugins.olas.service_manager.staking.StakingContract") as mock_staking_cls:
|
|
168
|
+
mock_staking_cls.side_effect = Exception("fail")
|
|
169
|
+
status = manager.get_staking_status()
|
|
170
|
+
assert status.staking_state == "ERROR"
|
|
171
|
+
|
|
172
|
+
# Exception in get_service_info
|
|
173
|
+
mock_staking_cls.side_effect = None
|
|
174
|
+
mock_staking = mock_staking_cls.return_value
|
|
175
|
+
mock_staking.get_staking_state.return_value = StakingState.STAKED
|
|
176
|
+
mock_staking.get_service_info.side_effect = Exception("fail")
|
|
177
|
+
status = manager.get_staking_status()
|
|
178
|
+
assert status.is_staked is True
|
|
179
|
+
assert status.mech_requests_this_epoch == 0
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_service_manager_verify_event_exception(mock_wallet):
|
|
183
|
+
"""Test exception path in _execute_mech_tx."""
|
|
184
|
+
manager = setup_manager(mock_wallet)
|
|
185
|
+
manager.service = Service(
|
|
186
|
+
service_name="t",
|
|
187
|
+
chain_name="gnosis",
|
|
188
|
+
service_id=1,
|
|
189
|
+
agent_ids=[1],
|
|
190
|
+
multisig_address=VALID_ADDR,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# EOA path
|
|
194
|
+
|
|
195
|
+
with patch.object(manager.wallet.account_service, "resolve_account") as mock_resolve:
|
|
196
|
+
mock_resolve.return_value = MagicMock()
|
|
197
|
+
mock_resolve.return_value.__class__ = object
|
|
198
|
+
|
|
199
|
+
# Exception in extract_events
|
|
200
|
+
with patch.object(
|
|
201
|
+
manager.registry.chain_interface.web3.eth, "wait_for_transaction_receipt"
|
|
202
|
+
) as mock_wait:
|
|
203
|
+
mock_wait.return_value = {"logs": []}
|
|
204
|
+
manager.registry.extract_events.side_effect = Exception("fail")
|
|
205
|
+
assert (
|
|
206
|
+
manager._execute_mech_tx({"data": "0x"}, VALID_ADDR, manager.registry, "Event")
|
|
207
|
+
is None
|
|
208
|
+
)
|