iwa 0.0.1a2__py3-none-any.whl → 0.0.1a3__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.
- iwa/core/chain/interface.py +51 -61
- iwa/core/chain/models.py +7 -7
- iwa/core/chain/rate_limiter.py +21 -10
- iwa/core/cli.py +27 -2
- iwa/core/constants.py +6 -5
- iwa/core/contracts/contract.py +16 -4
- iwa/core/ipfs.py +149 -0
- iwa/core/keys.py +259 -29
- iwa/core/mnemonic.py +3 -13
- iwa/core/models.py +28 -6
- iwa/core/pricing.py +4 -4
- iwa/core/secrets.py +77 -0
- iwa/core/services/safe.py +3 -3
- iwa/core/utils.py +6 -1
- iwa/core/wallet.py +4 -0
- iwa/plugins/gnosis/safe.py +2 -2
- iwa/plugins/gnosis/tests/test_safe.py +1 -1
- iwa/plugins/olas/constants.py +8 -0
- iwa/plugins/olas/contracts/mech.py +30 -2
- iwa/plugins/olas/plugin.py +2 -2
- iwa/plugins/olas/tests/test_plugin_full.py +3 -3
- iwa/plugins/olas/tests/test_staking_integration.py +2 -2
- iwa/tools/__init__.py +1 -0
- iwa/tools/check_profile.py +6 -5
- iwa/tools/list_contracts.py +136 -0
- iwa/tools/release.py +9 -3
- iwa/tools/reset_env.py +2 -2
- iwa/tools/reset_tenderly.py +26 -24
- iwa/tools/wallet_check.py +150 -0
- iwa/web/dependencies.py +4 -4
- iwa/web/routers/state.py +1 -0
- iwa/web/tests/test_web_endpoints.py +3 -2
- iwa/web/tests/test_web_swap_coverage.py +156 -0
- {iwa-0.0.1a2.dist-info → iwa-0.0.1a3.dist-info}/METADATA +6 -3
- {iwa-0.0.1a2.dist-info → iwa-0.0.1a3.dist-info}/RECORD +50 -43
- iwa-0.0.1a3.dist-info/entry_points.txt +6 -0
- tests/test_chain.py +1 -1
- tests/test_chain_interface_coverage.py +92 -0
- tests/test_contract.py +2 -0
- tests/test_keys.py +58 -15
- tests/test_migration.py +52 -0
- tests/test_mnemonic.py +1 -1
- tests/test_pricing.py +7 -7
- tests/test_safe_coverage.py +1 -1
- tests/test_safe_service.py +3 -3
- tests/test_staking_router.py +13 -1
- tools/verify_drain.py +1 -1
- iwa/core/settings.py +0 -95
- iwa-0.0.1a2.dist-info/entry_points.txt +0 -2
- {iwa-0.0.1a2.dist-info → iwa-0.0.1a3.dist-info}/WHEEL +0 -0
- {iwa-0.0.1a2.dist-info → iwa-0.0.1a3.dist-info}/licenses/LICENSE +0 -0
- {iwa-0.0.1a2.dist-info → iwa-0.0.1a3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Tests for swap router coverage."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from fastapi.testclient import TestClient
|
|
7
|
+
|
|
8
|
+
# PATCH Wallet before importing app to avoid global instantiation triggering KeyStorage security check
|
|
9
|
+
with patch("iwa.core.wallet.Wallet") as MockWallet:
|
|
10
|
+
# Ensure the mock returns a flexible object
|
|
11
|
+
MockWallet.return_value = MagicMock()
|
|
12
|
+
# Import app inside the patch context or after patching (if patch was global, but here it's context)
|
|
13
|
+
# Actually, importing here means 'app' is only available in this scope?
|
|
14
|
+
# No, we need 'app' for TestClient.
|
|
15
|
+
from iwa.web.server import app
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def client():
|
|
20
|
+
"""Create a test client with patched dependnecies."""
|
|
21
|
+
# Patch init_db to prevent real KeyStorage init during lifespan
|
|
22
|
+
with patch("iwa.web.server.init_db"):
|
|
23
|
+
# Also patch ChainInterfaces to avoid block tracking init
|
|
24
|
+
with patch("iwa.core.chain.ChainInterfaces"):
|
|
25
|
+
with TestClient(app) as c:
|
|
26
|
+
yield c
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.fixture
|
|
30
|
+
def mock_cow_plugin():
|
|
31
|
+
"""Mock the CowSwap plugin."""
|
|
32
|
+
with patch("iwa.web.routers.swap.CowSwap") as mock_cow:
|
|
33
|
+
mock_instance = MagicMock()
|
|
34
|
+
mock_cow.return_value = mock_instance
|
|
35
|
+
yield mock_instance
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_get_quote_errors(client, mock_cow_plugin):
|
|
39
|
+
"""Test error handling in get_quote."""
|
|
40
|
+
# The router instantiates CowSwap inside the endpoint (or dependency)
|
|
41
|
+
# We mocked CowSwap class.
|
|
42
|
+
# The endpoint calls get_max_buy_amount_wei or get_max_sell_amount_wei
|
|
43
|
+
|
|
44
|
+
# We need to ensure authentication passes.
|
|
45
|
+
# verify_auth depends on X-API-Key or Password.
|
|
46
|
+
# Use dependency override for auth if needed, or just rely on default allow if no password set.
|
|
47
|
+
|
|
48
|
+
mock_cow_plugin.get_max_buy_amount_wei.side_effect = Exception("CowSwap API Error")
|
|
49
|
+
|
|
50
|
+
response = client.get(
|
|
51
|
+
"/api/swap/quote",
|
|
52
|
+
params={
|
|
53
|
+
"account": "master",
|
|
54
|
+
"sell_token": "WXDAI",
|
|
55
|
+
"buy_token": "OLAS",
|
|
56
|
+
"amount": "100",
|
|
57
|
+
"mode": "sell",
|
|
58
|
+
"chain": "gnosis",
|
|
59
|
+
},
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
assert response.status_code == 400
|
|
63
|
+
assert "CowSwap API Error" in response.json()["detail"]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_swap_tokens_success(client):
|
|
67
|
+
"""Test successful token swap."""
|
|
68
|
+
# We need to mock wallet.transfer_service.swap returns a coroutine (AsyncMock)
|
|
69
|
+
with patch(
|
|
70
|
+
"iwa.web.routers.swap.wallet.transfer_service.swap", new_callable=AsyncMock
|
|
71
|
+
) as mock_swap:
|
|
72
|
+
mock_swap.return_value = {
|
|
73
|
+
"status": "open",
|
|
74
|
+
"uid": "0x123",
|
|
75
|
+
"sellToken": "0xSell",
|
|
76
|
+
"buyToken": "0xBuy",
|
|
77
|
+
"sellAmount": "1000",
|
|
78
|
+
"buyAmount": "990",
|
|
79
|
+
"validTo": 1234567890,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
response = client.post(
|
|
83
|
+
"/api/swap",
|
|
84
|
+
json={
|
|
85
|
+
"account": "master",
|
|
86
|
+
"sell_token": "WXDAI",
|
|
87
|
+
"buy_token": "OLAS",
|
|
88
|
+
"amount_eth": 10.0,
|
|
89
|
+
"order_type": "sell",
|
|
90
|
+
"chain": "gnosis",
|
|
91
|
+
},
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
assert response.status_code == 200, response.json()
|
|
95
|
+
assert response.json()["status"] == "success"
|
|
96
|
+
assert response.json()["order"]["uid"] == "0x123"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_swap_tokens_error(client):
|
|
100
|
+
"""Test error when swapping tokens."""
|
|
101
|
+
with patch(
|
|
102
|
+
"iwa.web.routers.swap.wallet.transfer_service.swap", new_callable=AsyncMock
|
|
103
|
+
) as mock_swap:
|
|
104
|
+
mock_swap.side_effect = Exception("Swap Failed")
|
|
105
|
+
|
|
106
|
+
response = client.post(
|
|
107
|
+
"/api/swap",
|
|
108
|
+
json={
|
|
109
|
+
"account": "master",
|
|
110
|
+
"sell_token": "WXDAI",
|
|
111
|
+
"buy_token": "OLAS",
|
|
112
|
+
"amount_eth": 10.0,
|
|
113
|
+
"order_type": "sell",
|
|
114
|
+
"chain": "gnosis",
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
assert response.status_code == 400
|
|
119
|
+
assert "Swap Failed" in response.json()["detail"]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def test_get_orders_history(client):
|
|
123
|
+
"""Test retrieving order history."""
|
|
124
|
+
# Mock requests.get globally since it's imported inside the function
|
|
125
|
+
with patch("requests.get") as mock_get:
|
|
126
|
+
mock_get.return_value.status_code = 200
|
|
127
|
+
mock_get.return_value.json.return_value = [
|
|
128
|
+
{
|
|
129
|
+
"uid": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
|
130
|
+
"status": "open",
|
|
131
|
+
"creationDate": "2023-01-01T00:00:00Z",
|
|
132
|
+
"validTo": 9999999999,
|
|
133
|
+
"sellToken": "0xSell",
|
|
134
|
+
"buyToken": "0xBuy",
|
|
135
|
+
"sellAmount": "1000000000000000000",
|
|
136
|
+
"buyAmount": "900000000000000000",
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
# We also need to mock Account resolution and ChainInterfaces
|
|
141
|
+
with patch("iwa.web.routers.swap.wallet.account_service.resolve_account") as mock_resolve:
|
|
142
|
+
mock_resolve.return_value.address = "0xUser"
|
|
143
|
+
|
|
144
|
+
with patch("iwa.web.routers.swap.ChainInterfaces") as mock_chain_interfaces:
|
|
145
|
+
mock_chain = MagicMock()
|
|
146
|
+
mock_chain.chain.chain_id = 100
|
|
147
|
+
mock_chain.chain.get_token_name.return_value = "TOKEN"
|
|
148
|
+
mock_chain_interfaces.return_value.get.return_value = mock_chain
|
|
149
|
+
|
|
150
|
+
response = client.get("/api/swap/orders", params={"account": "master"})
|
|
151
|
+
|
|
152
|
+
assert response.status_code == 200
|
|
153
|
+
data = response.json()
|
|
154
|
+
assert "orders" in data
|
|
155
|
+
assert len(data["orders"]) == 1
|
|
156
|
+
assert data["orders"][0]["status"] == "open"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iwa
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.0.1a3
|
|
4
|
+
Summary: A secure, modular, and plugin-based framework for crypto agents and ops
|
|
5
5
|
Requires-Python: <4.0,>=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
@@ -33,6 +33,8 @@ Requires-Dist: nest-asyncio>=1.6.0
|
|
|
33
33
|
Requires-Dist: aiohttp>=3.13.3
|
|
34
34
|
Requires-Dist: pynacl>=1.6.2
|
|
35
35
|
Requires-Dist: urllib3>=2.6.3
|
|
36
|
+
Requires-Dist: multiformats>=0.3.1
|
|
37
|
+
Requires-Dist: requests>=2.32.0
|
|
36
38
|
Dynamic: license-file
|
|
37
39
|
|
|
38
40
|
# Iwa
|
|
@@ -160,7 +162,8 @@ just test
|
|
|
160
162
|
### Security Checks
|
|
161
163
|
|
|
162
164
|
```bash
|
|
163
|
-
just security
|
|
165
|
+
just security # Runs gitleaks, bandit, and pip-audit
|
|
166
|
+
just wallet-check # Verifies password, keys, and mnemonic integrity
|
|
164
167
|
```
|
|
165
168
|
|
|
166
169
|
### Docker
|
|
@@ -2,37 +2,38 @@ conftest.py,sha256=rsm8Mz8_KAmrbtXYDF8IgxtKpQiHbWNTovK-bbNhQ0Q,491
|
|
|
2
2
|
iwa/__init__.py,sha256=vu12UytYNREtMRvIWp6AfV1GgUe53XWwCMhYyqKAPgo,19
|
|
3
3
|
iwa/__main__.py,sha256=eJU5Uxeu9Y7shWg5dt5Mcq0pMC4wFVNWjeYGKSf4Apw,88
|
|
4
4
|
iwa/core/__init__.py,sha256=GJv4LJOXeZ3hgGvbt5I6omkoFkP2A9qhHjpDlOep9ik,24
|
|
5
|
-
iwa/core/cli.py,sha256=
|
|
6
|
-
iwa/core/constants.py,sha256=
|
|
5
|
+
iwa/core/cli.py,sha256=aY-kgljUGzEPaJqHfL2nzozR5kcQm1OjnF4UmKoEuYs,7420
|
|
6
|
+
iwa/core/constants.py,sha256=JBjGyxpAdsn8mBOWHljllmAw45oGNgi8qqkH_vYkcrg,982
|
|
7
7
|
iwa/core/db.py,sha256=WI-mP0tQAmwFPeEi9w7RCa_Mcf_zBfd_7JcbHJwU1aU,10377
|
|
8
|
-
iwa/core/
|
|
9
|
-
iwa/core/
|
|
10
|
-
iwa/core/
|
|
8
|
+
iwa/core/ipfs.py,sha256=aHjq_pflgwDVHl8g5EMQv0q2RAmMs-a0pOTVsj_L5xE,4980
|
|
9
|
+
iwa/core/keys.py,sha256=ckacVZxm_02V9hlmHIxz-CkxjXdGHqvGGAXfO6EeHCw,22365
|
|
10
|
+
iwa/core/mnemonic.py,sha256=LiG1VmpydQoHQ0pHUJ1OIlrWJry47VSMnOqPM_Yk-O8,12930
|
|
11
|
+
iwa/core/models.py,sha256=kBQ0cBe6uFmL2QfW7mjKiMFeZxhT-FRN-RyK3Ko0vE8,12849
|
|
11
12
|
iwa/core/monitor.py,sha256=OmhKVMkfhvtxig3wDUL6iGwBIClTx0YUqMncCao4SqI,7953
|
|
12
13
|
iwa/core/plugins.py,sha256=FLvOG4S397fKi0aTH1fWBEtexn4yvGv_QzGWqFrhSKE,1102
|
|
13
|
-
iwa/core/pricing.py,sha256=
|
|
14
|
-
iwa/core/
|
|
14
|
+
iwa/core/pricing.py,sha256=yC_zMT30KBZStLvQ0OEm6KmL6jn_B3kP2iBOVc5avU4,3211
|
|
15
|
+
iwa/core/secrets.py,sha256=U7DZKrwKuSOFV00Ij3ISrrO1cWn_t1GBW_0PyAqjcD4,2588
|
|
15
16
|
iwa/core/tables.py,sha256=y7Cg67PAGHYVMVyAjbo_CQ9t2iz7UXE-OTuUHRyFRTo,2021
|
|
16
17
|
iwa/core/test.py,sha256=gey0dql5eajo1itOhgkSrgfyGWue2eSfpr0xzX3vc38,643
|
|
17
18
|
iwa/core/types.py,sha256=EfDfIwLajTNK-BP9K17QLOIsGCs8legplKI_bUD_NjM,1992
|
|
18
19
|
iwa/core/ui.py,sha256=DglmrI7XhUmOpLn9Nog9Cej4r-VT0JGFkuSNBx-XorQ,3131
|
|
19
|
-
iwa/core/utils.py,sha256=
|
|
20
|
-
iwa/core/wallet.py,sha256=
|
|
20
|
+
iwa/core/utils.py,sha256=Jc5yvyltYhnnPC9GdvNh_fW6bRuMen0XiG1nQcIuvhQ,2160
|
|
21
|
+
iwa/core/wallet.py,sha256=ZxztWOK8MzIih7nGT52BUvE6Z5a9AA056IV_gqMPQpA,12972
|
|
21
22
|
iwa/core/chain/__init__.py,sha256=XJMmn0ed-_aVkY2iEMKpuTxPgIKBd41dexSVmEZTa-o,1604
|
|
22
23
|
iwa/core/chain/errors.py,sha256=9SEbhxZ-qASPkzt-DoI51qq0GRJVqRgqgL720gO7a64,1275
|
|
23
|
-
iwa/core/chain/interface.py,sha256=
|
|
24
|
+
iwa/core/chain/interface.py,sha256=3tyMvnOZCTTvM0Y3YgxuN6zlXyJ1EIZUoyVosGtsUI8,20228
|
|
24
25
|
iwa/core/chain/manager.py,sha256=cFEzh6pK5OyVhjhpeMAqhc9RnRDQR1DjIGiGKp-FXBI,1159
|
|
25
|
-
iwa/core/chain/models.py,sha256=
|
|
26
|
-
iwa/core/chain/rate_limiter.py,sha256=
|
|
26
|
+
iwa/core/chain/models.py,sha256=ZVhzde2yHS50qYKkgpeWzFRtjnp2HiFU_D10SrD8RYI,4035
|
|
27
|
+
iwa/core/chain/rate_limiter.py,sha256=gU7TmWdH9D_wbXKT1X7mIgoIUCWVuebgvRhxiyLGAmI,6613
|
|
27
28
|
iwa/core/contracts/__init__.py,sha256=P5GFY_pnuI02teqVY2U0t98bn1_SSPAbcAzRMpCdTi4,34
|
|
28
|
-
iwa/core/contracts/contract.py,sha256=
|
|
29
|
+
iwa/core/contracts/contract.py,sha256=ERWViqZNqhsmf-tKVxn5XfQTJ8S_1MXVk0Tjq8davd0,11228
|
|
29
30
|
iwa/core/contracts/erc20.py,sha256=VqriOdUXej0ilTgpukpm1FUF_9sSrVMAPuEpIvyZ2SQ,2646
|
|
30
31
|
iwa/core/contracts/multisend.py,sha256=tSdBCWe7LSdBoKZ7z2QebmRFK4M2ln7H3kmJBeEb4Ho,2431
|
|
31
32
|
iwa/core/services/__init__.py,sha256=ab5pYzmu3LrZLTO5N-plx6Rp4R0hBEnbbzsgz84zWGM,498
|
|
32
33
|
iwa/core/services/account.py,sha256=01MoEvl6FJlMnMB4fGwsPtnGa4kgA-d5hJeKu_ACg7Y,1982
|
|
33
34
|
iwa/core/services/balance.py,sha256=mPE12CuOFfCaJXaQXWOcQM1O03ZF3ghpy_-oOjNk_GE,4104
|
|
34
35
|
iwa/core/services/plugin.py,sha256=GNNlbtELyHl7MNVChrypF76GYphxXduxDog4kx1MLi8,3277
|
|
35
|
-
iwa/core/services/safe.py,sha256=
|
|
36
|
+
iwa/core/services/safe.py,sha256=ULrzawkqcKjq-ffA0evndfp4OXi_VPVR9Yozvow8rFk,14587
|
|
36
37
|
iwa/core/services/transaction.py,sha256=RsZmkTLAZbmH9oimuJ9qXes23e5Z9mf1WnMxyNiYMCM,6928
|
|
37
38
|
iwa/core/services/transfer/__init__.py,sha256=ZJfshFxJRsp8rkOqfVvd1cqEzIJ9tqBJh8pc0l90GLk,5576
|
|
38
39
|
iwa/core/services/transfer/base.py,sha256=sohz-Ss2i-pGYGl4x9bD93cnYKcSvsXaXyvyRawvgQs,9043
|
|
@@ -45,22 +46,22 @@ iwa/plugins/__init__.py,sha256=zy-DjOZn8GSgIETN2X_GAb9O6yk71t6ZRzeUgoZ52KA,23
|
|
|
45
46
|
iwa/plugins/gnosis/__init__.py,sha256=dpx0mE84eV-g5iZaH5nKivZJnoKWyRFX5rhdjowBwuU,114
|
|
46
47
|
iwa/plugins/gnosis/cow_utils.py,sha256=iSvbfgTr2bCqRsUznKCWqmoTnyuX-WZX4oh0E-l3XBU,2263
|
|
47
48
|
iwa/plugins/gnosis/plugin.py,sha256=AgkgOGYfnrcjWrPUiAvySMj6ITnss0SFXiEi6Z6fnMs,1885
|
|
48
|
-
iwa/plugins/gnosis/safe.py,sha256=
|
|
49
|
+
iwa/plugins/gnosis/safe.py,sha256=MUjb3VyoRVU5NlcLLtVfzPd-LmANfvHtsgqbG8YOa44,5505
|
|
49
50
|
iwa/plugins/gnosis/cow/__init__.py,sha256=lZN5QpIYWL67rE8r7z7zS9dlr8OqFrYeD9T4-RwUghU,224
|
|
50
51
|
iwa/plugins/gnosis/cow/quotes.py,sha256=u2xFKgL7QTKqCkSPMv1RHaXvZ6WzID4haaZDMVS42Bs,5177
|
|
51
52
|
iwa/plugins/gnosis/cow/swap.py,sha256=XZdvJbTbh54hxer7cKkum7lNQ-03gddMK95K3MenaFE,15209
|
|
52
53
|
iwa/plugins/gnosis/cow/types.py,sha256=-9VRiFhAkmN1iIJ95Pg7zLFSeXtkkW00sl13usxi3o8,470
|
|
53
54
|
iwa/plugins/gnosis/tests/test_cow.py,sha256=iVy5ockMIcPZWsX4WGXU91DhBsYEZ5NOxtFzAQ2sK3o,8440
|
|
54
|
-
iwa/plugins/gnosis/tests/test_safe.py,sha256=
|
|
55
|
+
iwa/plugins/gnosis/tests/test_safe.py,sha256=BY6MJZqONrvIIougRpOQQsTNDOAjUsKXToTcwdMby44,3084
|
|
55
56
|
iwa/plugins/olas/__init__.py,sha256=_NhBczzM61fhGYwGhnWfEeL8Jywyy_730GASe2BxzeQ,106
|
|
56
|
-
iwa/plugins/olas/constants.py,sha256=
|
|
57
|
+
iwa/plugins/olas/constants.py,sha256=mFUMDB46WbM9Y8sw7c-i9TRyJVrDNZXdCXa64M5tI6A,6608
|
|
57
58
|
iwa/plugins/olas/importer.py,sha256=f8KlZ9dGcNbpg8uoTYbO9sDvbluZoslhpWFLqPjPnLA,26717
|
|
58
59
|
iwa/plugins/olas/mech_reference.py,sha256=CaSCpQnQL4F7wOG6Ox6Zdoy-uNEQ78YBwVLILQZKL8Q,5782
|
|
59
60
|
iwa/plugins/olas/models.py,sha256=xC5hYakX53pBT6zZteM9cyiC7t6XRLLpobjQmDYueOo,3520
|
|
60
|
-
iwa/plugins/olas/plugin.py,sha256=
|
|
61
|
+
iwa/plugins/olas/plugin.py,sha256=wncoujfR1YXhJeCYwLxaX5J50OzoA3KUG8q02DRWDtA,9231
|
|
61
62
|
iwa/plugins/olas/contracts/activity_checker.py,sha256=UDbCgFOyuEhHf1qoUwCUdLc8oK8ksuAYE-ZgKrMBnwg,3415
|
|
62
63
|
iwa/plugins/olas/contracts/base.py,sha256=y73aQbDq6l4zUpz_eQAg4MsLkTAEqjjupXlcvxjfgCI,240
|
|
63
|
-
iwa/plugins/olas/contracts/mech.py,sha256=
|
|
64
|
+
iwa/plugins/olas/contracts/mech.py,sha256=dXYtyORc-oiu9ga5PtTquOFkoakb6BLGKvlUsteygIg,2767
|
|
64
65
|
iwa/plugins/olas/contracts/mech_marketplace.py,sha256=hMADl5MQGvT2wLRKu4vHGe4RrAZVq8Y2M_EvXWWz528,1554
|
|
65
66
|
iwa/plugins/olas/contracts/service.py,sha256=OHXi4TBaVlRRZJA15XKnTMN8huGDWRZWU1TOZf589_E,6731
|
|
66
67
|
iwa/plugins/olas/contracts/staking.py,sha256=pxT62Cal1kkDfZdhbPk2YxyM2Xbf8-oFa40lL0Y8HBk,14520
|
|
@@ -83,7 +84,7 @@ iwa/plugins/olas/tests/test_olas_view.py,sha256=kh3crsriyoRiZC6l8vzGllocvQnYmqzi
|
|
|
83
84
|
iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=jAxr9bjFNAaxGf1btIrxdMaHgJ0PWX9aDwVU-oPGMpk,5109
|
|
84
85
|
iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvqGt49H6fLSYGxn02c8o,5562
|
|
85
86
|
iwa/plugins/olas/tests/test_plugin.py,sha256=UIEgW_VMivqJllOAd3mmTltM0DF_ZBK79ecpIiBricI,2429
|
|
86
|
-
iwa/plugins/olas/tests/test_plugin_full.py,sha256=
|
|
87
|
+
iwa/plugins/olas/tests/test_plugin_full.py,sha256=RdDY_fYGkpfP3s742yBBh-gPr5uc1dfhZsrpGCrCeu8,8224
|
|
87
88
|
iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=dhIDzgcXh1VV-S6VGXtNqtdxxIdXY1F1hRcPL6RBxno,5649
|
|
88
89
|
iwa/plugins/olas/tests/test_service_manager.py,sha256=dsnj1DfSYptIZkiPaLHGM9utbX9XOAy0axuzu-3kofg,41818
|
|
89
90
|
iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=BtN-89gwaFpy3RJIDt98U0TT0lksg9NHvoSpSBHSXag,8229
|
|
@@ -92,15 +93,18 @@ iwa/plugins/olas/tests/test_service_manager_mech.py,sha256=qG6qu5IPRNypXUsblU2OE
|
|
|
92
93
|
iwa/plugins/olas/tests/test_service_manager_rewards.py,sha256=hIVckGl5rEr-KHGNUxxVopal0Tpw4EZharBt0MbaCVA,11798
|
|
93
94
|
iwa/plugins/olas/tests/test_service_manager_validation.py,sha256=dagFvq8eQk3HKYpajp_2uJ4AUi_74kIAMfTiN4qAZ58,5263
|
|
94
95
|
iwa/plugins/olas/tests/test_service_staking.py,sha256=XkC8H_qVumOQ1i4_vidEdXqkK5stInd2tgT50l0SRMk,12201
|
|
95
|
-
iwa/plugins/olas/tests/test_staking_integration.py,sha256=
|
|
96
|
+
iwa/plugins/olas/tests/test_staking_integration.py,sha256=zQdhhSLz5h2OvQ6GOJ-Yl_Y17itPML4Pr9VPkjWoz9c,9420
|
|
96
97
|
iwa/plugins/olas/tests/test_staking_validation.py,sha256=J7DgDdIiVTkKv_7obtSHQ2lgfUGPmUwuPjTUkiT4cbs,4198
|
|
97
98
|
iwa/plugins/olas/tui/__init__.py,sha256=5ZRsbC7J3z1xfkZRiwr4bLEklf78rNVjdswe2p7SlS8,28
|
|
98
99
|
iwa/plugins/olas/tui/olas_view.py,sha256=qcPxhurDPJjHWln6R64ZVAJ2h82IXzw48unhRvQVZqQ,36448
|
|
99
|
-
iwa/tools/
|
|
100
|
-
iwa/tools/
|
|
101
|
-
iwa/tools/
|
|
102
|
-
iwa/tools/
|
|
100
|
+
iwa/tools/__init__.py,sha256=jQyuwDQGRigSe7S9JMb4yK3CXPgZFJNffzt6N2v9PU0,21
|
|
101
|
+
iwa/tools/check_profile.py,sha256=0LAv9wx4wMM610mX88-6tIoDi2I5LDzh0W9nkprt42s,2177
|
|
102
|
+
iwa/tools/list_contracts.py,sha256=m5-m_zDuKENlCf6LiDFRh0gKcwVhrP-XNzsyy_upwV0,4864
|
|
103
|
+
iwa/tools/release.py,sha256=-Z9GG6Y-K6KG32K0VUf_MruiUdJxG6W7ToOMzhyCH7Y,3963
|
|
104
|
+
iwa/tools/reset_env.py,sha256=FKN0wuh9Xq00c94B2kEFehHPKcWldxYqgU45yJwg5Cg,3140
|
|
105
|
+
iwa/tools/reset_tenderly.py,sha256=w1-KujdqRpimrgiREvoRwVXsGsGoYisCLmYTcsJ6Np8,11295
|
|
103
106
|
iwa/tools/restore_backup.py,sha256=_LJbmKv9SlekLUQFdjI3aHCvAc6uePobJe3bQEFyatk,2455
|
|
107
|
+
iwa/tools/wallet_check.py,sha256=IQLgb8oCt4oG6FMEAqzUxM57DLv_UE24dFUSVxtBo_Y,4774
|
|
104
108
|
iwa/tui/__init__.py,sha256=XYIZNQNy-fZC1NHHM0sd9qUO0vE1slml-cm0CpQ4NLY,27
|
|
105
109
|
iwa/tui/app.py,sha256=XDQ4nAPGBwhrEmdL_e3V8oYSOho8pY7jsd3C_wk92UU,4163
|
|
106
110
|
iwa/tui/rpc.py,sha256=4q2zcBu7XXDU9c66UYtfbXiNdQyS_uLa9xOs3UmPOO0,2131
|
|
@@ -115,11 +119,11 @@ iwa/tui/tests/test_wallets_refactor.py,sha256=71G3HLbhTtgDy3ffVbYv0MFYRgdYd-NWGB
|
|
|
115
119
|
iwa/tui/tests/test_widgets.py,sha256=C9UgIGeWRaQ459JygFEQx-7hOi9mWrSUDDIMZH1ge50,3994
|
|
116
120
|
iwa/tui/widgets/__init__.py,sha256=UzD6nJbwv9hOtkWl9I7faXm1a-rcu4xFRxrf4KBwwY4,161
|
|
117
121
|
iwa/tui/widgets/base.py,sha256=G844GU61qSS6AgY5NxmOVHTghbgHlyTfo8hhE2VUrqQ,3379
|
|
118
|
-
iwa/web/dependencies.py,sha256=
|
|
122
|
+
iwa/web/dependencies.py,sha256=xy99q7mJr-kCyh2hZAI0beaOtXVfppJbNmLhhbdam-g,2130
|
|
119
123
|
iwa/web/models.py,sha256=MSD9WPy_Nz_amWgoo2KSDTn4ZLv_AV0o0amuNtSf-68,3035
|
|
120
124
|
iwa/web/server.py,sha256=_7kDO-1J9znIGcOzdUuCBEePoAfjdubAmp6mxX7k2g8,5100
|
|
121
125
|
iwa/web/routers/accounts.py,sha256=j6xFkKGeLkjpUG48vW8ZFsWzLxl-Vi5et7rcTsOJkiI,3942
|
|
122
|
-
iwa/web/routers/state.py,sha256=
|
|
126
|
+
iwa/web/routers/state.py,sha256=aEfeGFAOyaS6kWhXuWLrdvEbnQAeonKIWxJrQkqJ1GY,2198
|
|
123
127
|
iwa/web/routers/swap.py,sha256=mU9StUZpJPvD8De412nmwlCYHRnGR4ISVl1YKF3gIb8,22656
|
|
124
128
|
iwa/web/routers/transactions.py,sha256=ZDKaqCTt1ZylzxyfFQHxFPwzD-j9H0jUByYFSWvggBA,5654
|
|
125
129
|
iwa/web/routers/olas/__init__.py,sha256=Jo6Dm1e8fHafCD800fbxsxeFz3tvuEEKXEf5-9tj5Qg,947
|
|
@@ -128,10 +132,11 @@ iwa/web/routers/olas/funding.py,sha256=Jko_uZynE9cahf7ObjHfR54_9jNeU2m2hOJ8PUxeg
|
|
|
128
132
|
iwa/web/routers/olas/general.py,sha256=gsL-bkOWTHLxw65Bt3T61123QUZpjxwbNkrx5Qo7s5E,830
|
|
129
133
|
iwa/web/routers/olas/services.py,sha256=5W4Cvj5HQjxmEokPfVpaV1v_YKwOcm6SQfyXsgwpBZo,14766
|
|
130
134
|
iwa/web/routers/olas/staking.py,sha256=9FH-yNUuG2KJxaI6HYn3d6fY5QvXd8UPCx01mDFYSgQ,12090
|
|
131
|
-
iwa/web/tests/test_web_endpoints.py,sha256=
|
|
135
|
+
iwa/web/tests/test_web_endpoints.py,sha256=vZUGmrudkQHA8gBmSyO8i2SgZpsr1He-YRm2JFAs9lg,23979
|
|
132
136
|
iwa/web/tests/test_web_olas.py,sha256=oN__4nUT_H_j-_ALEqSp-si5xMbY0Bcxhvhuhxsg4Q8,16292
|
|
133
137
|
iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
|
|
134
|
-
iwa
|
|
138
|
+
iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
|
|
139
|
+
iwa-0.0.1a3.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
|
|
135
140
|
tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
|
|
136
141
|
tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
|
|
137
142
|
tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
|
|
@@ -140,33 +145,35 @@ tests/legacy_wallets_screen.py,sha256=9hZnX-VhKgwH9w8MxbNdboRyNxLDhOakLKJECsw_vh
|
|
|
140
145
|
tests/legacy_web.py,sha256=q2ERIriaDHT3Q8axG2N3ucO7f2VSvV_WkuPR00DVko4,8577
|
|
141
146
|
tests/test_account_service.py,sha256=g_AIVT2jhlvUtbFTaCd-d15x4CmXJQaV66tlAgnaXwY,3745
|
|
142
147
|
tests/test_balance_service.py,sha256=86iEkPd2M1-UFy3qOxV1EguQOEYbboy2-2mAyS3ctGs,6549
|
|
143
|
-
tests/test_chain.py,sha256=
|
|
148
|
+
tests/test_chain.py,sha256=uXbNl9wD4e2qV1xs_MO74Soj3iaH-5xoxge4rD3FypU,16986
|
|
144
149
|
tests/test_chain_interface.py,sha256=Wu0q0sREtmYBp7YvWrBIrrSTtqeQj18oJp2VmMUEMec,8312
|
|
150
|
+
tests/test_chain_interface_coverage.py,sha256=cmZGxpBjf8pT9PwtECMqBbrUMaAJu6v3D8C18nfPyQ0,3248
|
|
145
151
|
tests/test_cli.py,sha256=WW6EDeHLws5-BqFNOy11pH_D5lttuyspD5hrDCFpR0Q,3968
|
|
146
|
-
tests/test_contract.py,sha256=
|
|
152
|
+
tests/test_contract.py,sha256=XigxdTziO5SJVbg8_mWPQdbkTIQBA-W8d3WPij4KTyQ,7738
|
|
147
153
|
tests/test_db.py,sha256=dmbrupj0qlUeiiycZ2mzMFjf7HrDa6tcqMPY8zpiKIk,5710
|
|
148
154
|
tests/test_drain_coverage.py,sha256=jtN5tIXzSTlS2IjwLS60azyMYsjFDlSTUa98JM1bMic,6786
|
|
149
155
|
tests/test_erc20.py,sha256=kNEw1afpm5EbXRNXkjpkBNZIy7Af1nqGlztKH5IWAwU,3074
|
|
150
156
|
tests/test_gnosis_plugin.py,sha256=XMoHBCTrnVBq9bXYPzMUIrhr95caucMVRxooCjKrzjg,3454
|
|
151
|
-
tests/test_keys.py,sha256=
|
|
157
|
+
tests/test_keys.py,sha256=BUKaZmnEzs7HzUCiEIMiLd2aJRegLOflOkVlC9s3XXs,17405
|
|
152
158
|
tests/test_legacy_wallet.py,sha256=8u83TTJv2zmdfBaLXIhsrbBREqm7EA1KH6J6ZjTyzuc,49604
|
|
153
159
|
tests/test_main.py,sha256=y2xr7HjCt4rHsxm8y6n24FKCteSHPyxC3DFuMcUgX1Y,475
|
|
154
|
-
tests/
|
|
160
|
+
tests/test_migration.py,sha256=fYoxzI3KqGh0cPV0bFcbvGrAnKcNlvnwjggG_uD0QGo,1789
|
|
161
|
+
tests/test_mnemonic.py,sha256=BFtXMMg17uHWh_H-ZwAOn0qzgbUCqL8BRLkgRjzfzxo,7379
|
|
155
162
|
tests/test_modals.py,sha256=R_lXa7wnnGewAP5jJvVZDyQyY1FbE98IeO2B7y3x86c,2945
|
|
156
163
|
tests/test_models.py,sha256=1bEfPiDVgEdtwFEzwecSPAHjCF8kjOPSMeQExJ7eCJ4,7107
|
|
157
164
|
tests/test_monitor.py,sha256=P_hF61VMlCX2rh9yu_a6aKhlgXOAcCMGOZRntjcqrd0,7255
|
|
158
165
|
tests/test_multisend.py,sha256=IvXpwnC5xSDRCyCDGcMdO3L-eQegvdjAzHZB0FoVFUI,2685
|
|
159
166
|
tests/test_plugin_service.py,sha256=ZEe37kV_sv4Eb04032O1hZIoo9yf5gJo83ks7Grzrng,3767
|
|
160
|
-
tests/test_pricing.py,sha256=
|
|
167
|
+
tests/test_pricing.py,sha256=fTrqBZ4-4W1REl-zy7RN2UKcqYi0UIbmRFB9Ni0iAf0,4685
|
|
161
168
|
tests/test_rate_limiter.py,sha256=DOIlrBP2AtVFHCpznIoFn2FjFc33emG7M_FffLh4MGE,7314
|
|
162
169
|
tests/test_reset_tenderly.py,sha256=GVoqbDT3n4_GnlKF5Lx-8ew15jT8I2hIPdTulQDb6dI,7215
|
|
163
170
|
tests/test_rpc_view.py,sha256=sgZ53KEHl8VGb7WKYa0VI7Cdxbf8JH1SdroHYbWHjfQ,2031
|
|
164
|
-
tests/test_safe_coverage.py,sha256=
|
|
165
|
-
tests/test_safe_service.py,sha256=
|
|
171
|
+
tests/test_safe_coverage.py,sha256=J09TlcPYVms9bqDtVRPs9TnA102obUuApHXsmEDVJsI,5098
|
|
172
|
+
tests/test_safe_service.py,sha256=HsUJZxwLCfObdHkCwfesfp8XBiv5gCx9JIJLsHuWgDg,5899
|
|
166
173
|
tests/test_service_manager_integration.py,sha256=I_BLUzEKrVTyg_8jqsUK0oFD3aQVPCRJ7z0gY8P-j04,2354
|
|
167
174
|
tests/test_service_manager_structure.py,sha256=zK506ucCXCBHcjPYKrKEuK1bgq0xsbawyL8Y-wahXf8,868
|
|
168
175
|
tests/test_service_transaction.py,sha256=Jzb6oADMrlxNdgVvr3urpYz5NCRNO6h6bUTUQDKeTxQ,6224
|
|
169
|
-
tests/test_staking_router.py,sha256=
|
|
176
|
+
tests/test_staking_router.py,sha256=l7IqP9t6eGMgiW0PKW6tmdP2Wb6Fz9diRDjptjzKiLA,2621
|
|
170
177
|
tests/test_staking_simple.py,sha256=NHyZ1pcVQEJGFiGseC5m6Y9Y6FJGnRIFJUwhd1hAV9g,1138
|
|
171
178
|
tests/test_tables.py,sha256=1KQHgxuizoOrRxpubDdnzk9iaU5Lwyp3bcWP_hZD5uU,2686
|
|
172
179
|
tests/test_transaction_service.py,sha256=NhTuzZnmIbMRbiO1lXutzFNhjdyGDb4QNXbm9U4D7yM,5154
|
|
@@ -178,9 +185,9 @@ tests/test_transfer_swap_unit.py,sha256=v_tld2oF2jFf_qdrCxIPQFlAymQqHT2dcw2Z05qW
|
|
|
178
185
|
tests/test_ui_coverage.py,sha256=N-7uhPlKOXCKyS32VjwG3JQRnAS1PoAJxR-InaOZtCQ,2423
|
|
179
186
|
tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
|
|
180
187
|
tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
|
|
181
|
-
tools/verify_drain.py,sha256=
|
|
182
|
-
iwa-0.0.
|
|
183
|
-
iwa-0.0.
|
|
184
|
-
iwa-0.0.
|
|
185
|
-
iwa-0.0.
|
|
186
|
-
iwa-0.0.
|
|
188
|
+
tools/verify_drain.py,sha256=1On4GmXWETA-CHfFjd7qAqIQuSgKIaEomKKXM7S8wfk,6881
|
|
189
|
+
iwa-0.0.1a3.dist-info/METADATA,sha256=-4t7aijBftawVnWhycmYbHbEL6UNF7QH3abhJ5jCCbE,7296
|
|
190
|
+
iwa-0.0.1a3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
191
|
+
iwa-0.0.1a3.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
|
|
192
|
+
iwa-0.0.1a3.dist-info/top_level.txt,sha256=dv1_pfdxeIecM4tOc2ECj1aiCTQMDDYD9Y1UCOMmWlI,25
|
|
193
|
+
iwa-0.0.1a3.dist-info/RECORD,,
|
tests/test_chain.py
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from iwa.core.chain.interface import ChainInterface
|
|
6
|
+
|
|
7
|
+
# from iwa.core.chain.errors import RPCError, MaxRetriesExceededError <-- These don't exist
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def mock_web3():
|
|
12
|
+
with patch("iwa.core.chain.interface.Web3") as mock_w3:
|
|
13
|
+
yield mock_w3
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_rpc_rotation_exhaustion(mock_web3):
|
|
17
|
+
"""Test that generic Exception is raised when all RPCs fail."""
|
|
18
|
+
# Setup chain interface with valid Chain object
|
|
19
|
+
# We must mock SupportedChain or use Gnosis
|
|
20
|
+
from iwa.core.chain.models import Gnosis
|
|
21
|
+
|
|
22
|
+
chain_obj = Gnosis()
|
|
23
|
+
chain_obj.rpcs = ["rpc1", "rpc2"]
|
|
24
|
+
|
|
25
|
+
chain = ChainInterface(chain_obj)
|
|
26
|
+
|
|
27
|
+
# Mock Web3 to simulate connection error on every call
|
|
28
|
+
chain.web3 = MagicMock()
|
|
29
|
+
chain.web3.eth.get_block.side_effect = Exception("Connection Error")
|
|
30
|
+
|
|
31
|
+
# We also need to prevent rotation from working or make rotation also fail
|
|
32
|
+
# Since we only have 2 RPCs, eventually it will give up.
|
|
33
|
+
|
|
34
|
+
with pytest.raises(Exception, match="Connection Error"):
|
|
35
|
+
chain.with_retry(lambda: chain.web3.eth.get_block("latest"))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_rate_limiting_backoff(mock_web3):
|
|
39
|
+
"""Test that rate limiting triggers sleep."""
|
|
40
|
+
from iwa.core.chain.models import Gnosis
|
|
41
|
+
|
|
42
|
+
chain_obj = Gnosis()
|
|
43
|
+
chain_obj.rpcs = ["rpc1"]
|
|
44
|
+
|
|
45
|
+
chain = ChainInterface(chain_obj)
|
|
46
|
+
|
|
47
|
+
# Mock _get_web3 to return a mock provider
|
|
48
|
+
chain._get_web3 = MagicMock()
|
|
49
|
+
mock_provider = MagicMock()
|
|
50
|
+
# ChainInterface uses self.web3 which is set by _init_web3 called in init
|
|
51
|
+
# We need to mock self.web3 on the instance
|
|
52
|
+
chain.web3 = mock_provider
|
|
53
|
+
|
|
54
|
+
# First call raises rate limit, second succeeds
|
|
55
|
+
mock_provider.eth.get_block.side_effect = [Exception("429 Too Many Requests"), {"number": 100}]
|
|
56
|
+
|
|
57
|
+
# ChainInterface calls get_block on self.web3.eth?
|
|
58
|
+
# No, ChainInterface doesn't have get_block method in the snippet I saw!
|
|
59
|
+
# It has with_retry().
|
|
60
|
+
# Test assumes get_block exists. It might not!
|
|
61
|
+
# Viewing interface.py lines 1-504: NO get_block method.
|
|
62
|
+
# It has with_retry, init_block_tracking, etc.
|
|
63
|
+
# So calling chain.get_block will fail with AttributeError!
|
|
64
|
+
# I should test with_retry instead.
|
|
65
|
+
|
|
66
|
+
def my_op():
|
|
67
|
+
return chain.web3.eth.get_block("latest")
|
|
68
|
+
|
|
69
|
+
with patch("time.sleep") as mock_sleep:
|
|
70
|
+
block = chain.with_retry(my_op)
|
|
71
|
+
|
|
72
|
+
assert block["number"] == 100
|
|
73
|
+
mock_sleep.assert_called() # Should sleep on 429
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_custom_rpc_headers(mock_web3):
|
|
77
|
+
"""Test that custom headers are applied to HTTPProvider."""
|
|
78
|
+
# iwa.core.chain.interface uses Web3.HTTPProvider
|
|
79
|
+
# We patch iwa.core.chain.interface.Web3
|
|
80
|
+
with patch("iwa.core.chain.interface.Web3"):
|
|
81
|
+
# We need a chain definition
|
|
82
|
+
from iwa.core.chain.models import Ethereum
|
|
83
|
+
|
|
84
|
+
chain_obj = Ethereum()
|
|
85
|
+
chain_obj.rpcs = ["https://rpc.com"]
|
|
86
|
+
|
|
87
|
+
# ChainInterface doesn't seem to accept rpc_headers in __init__
|
|
88
|
+
# __init__(self, chain: Union[SupportedChain, str] = None)
|
|
89
|
+
# Checking interface.py source... line 29 init.
|
|
90
|
+
# It does NOT take rpc_headers arg.
|
|
91
|
+
# So this feature might be missing or automated via Config?
|
|
92
|
+
pass # Feature doesn't exist in __init__, removing test.
|
tests/test_contract.py
CHANGED
|
@@ -44,6 +44,8 @@ def test_init_abi_dict(mock_chain_interface):
|
|
|
44
44
|
def test_call(mock_chain_interface, mock_abi_file):
|
|
45
45
|
contract = MockContract("0xAddress", "gnosis")
|
|
46
46
|
contract.contract.functions.testFunc.return_value.call.return_value = "result"
|
|
47
|
+
# with_retry now wraps the call - make it execute the lambda
|
|
48
|
+
mock_chain_interface.with_retry.side_effect = lambda fn, **kwargs: fn()
|
|
47
49
|
assert contract.call("testFunc") == "result"
|
|
48
50
|
|
|
49
51
|
|