iwa 0.0.2__py3-none-any.whl → 0.0.11__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.
Files changed (58) hide show
  1. iwa/core/chain/interface.py +51 -30
  2. iwa/core/chain/models.py +9 -15
  3. iwa/core/contracts/contract.py +8 -2
  4. iwa/core/pricing.py +10 -8
  5. iwa/core/services/safe.py +13 -8
  6. iwa/core/services/transaction.py +211 -7
  7. iwa/core/utils.py +22 -0
  8. iwa/core/wallet.py +2 -1
  9. iwa/plugins/gnosis/safe.py +4 -3
  10. iwa/plugins/gnosis/tests/test_safe.py +9 -7
  11. iwa/plugins/olas/contracts/abis/service_registry_token_utility.json +926 -0
  12. iwa/plugins/olas/contracts/service.py +54 -4
  13. iwa/plugins/olas/contracts/staking.py +2 -3
  14. iwa/plugins/olas/plugin.py +14 -7
  15. iwa/plugins/olas/service_manager/lifecycle.py +382 -85
  16. iwa/plugins/olas/service_manager/mech.py +1 -1
  17. iwa/plugins/olas/service_manager/staking.py +229 -82
  18. iwa/plugins/olas/tests/test_olas_contracts.py +6 -2
  19. iwa/plugins/olas/tests/test_plugin.py +6 -1
  20. iwa/plugins/olas/tests/test_plugin_full.py +12 -7
  21. iwa/plugins/olas/tests/test_service_lifecycle.py +1 -4
  22. iwa/plugins/olas/tests/test_service_manager.py +59 -89
  23. iwa/plugins/olas/tests/test_service_manager_errors.py +1 -2
  24. iwa/plugins/olas/tests/test_service_manager_flows.py +5 -15
  25. iwa/plugins/olas/tests/test_service_manager_validation.py +16 -15
  26. iwa/tools/list_contracts.py +2 -2
  27. iwa/web/dependencies.py +1 -3
  28. iwa/web/routers/accounts.py +1 -2
  29. iwa/web/routers/olas/admin.py +1 -3
  30. iwa/web/routers/olas/funding.py +1 -3
  31. iwa/web/routers/olas/general.py +1 -3
  32. iwa/web/routers/olas/services.py +53 -21
  33. iwa/web/routers/olas/staking.py +27 -24
  34. iwa/web/routers/swap.py +1 -2
  35. iwa/web/routers/transactions.py +0 -2
  36. iwa/web/server.py +8 -6
  37. iwa/web/static/app.js +22 -0
  38. iwa/web/tests/test_web_endpoints.py +1 -1
  39. iwa/web/tests/test_web_olas.py +1 -1
  40. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/METADATA +1 -1
  41. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/RECORD +58 -56
  42. tests/test_chain.py +12 -7
  43. tests/test_chain_interface_coverage.py +3 -2
  44. tests/test_contract.py +165 -0
  45. tests/test_keys.py +2 -1
  46. tests/test_legacy_wallet.py +11 -0
  47. tests/test_pricing.py +32 -15
  48. tests/test_safe_coverage.py +3 -3
  49. tests/test_safe_service.py +3 -6
  50. tests/test_service_transaction.py +8 -3
  51. tests/test_staking_router.py +6 -3
  52. tests/test_transaction_service.py +4 -0
  53. tools/create_and_stake_service.py +103 -0
  54. tools/verify_drain.py +1 -4
  55. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/WHEEL +0 -0
  56. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/entry_points.txt +0 -0
  57. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/licenses/LICENSE +0 -0
  58. {iwa-0.0.2.dist-info → iwa-0.0.11.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  """Olas Staking Router."""
2
2
 
3
- import logging
4
3
  from typing import Optional
5
4
 
6
5
  from fastapi import APIRouter, Depends, HTTPException, Request
6
+ from loguru import logger
7
7
  from slowapi import Limiter
8
8
  from slowapi.util import get_remote_address
9
9
 
@@ -11,7 +11,6 @@ from iwa.core.models import Config
11
11
  from iwa.plugins.olas.models import OlasConfig
12
12
  from iwa.web.dependencies import get_config, verify_auth, wallet
13
13
 
14
- logger = logging.getLogger(__name__)
15
14
  router = APIRouter(tags=["olas"])
16
15
  limiter = Limiter(key_func=get_remote_address)
17
16
 
@@ -34,25 +33,18 @@ def get_staking_contracts(
34
33
  raise HTTPException(status_code=400, detail="Invalid chain name")
35
34
 
36
35
  try:
37
- import json
38
-
39
- from iwa.core.chain import ChainInterface
36
+ from iwa.core.chain import ChainInterfaces
40
37
  from iwa.plugins.olas.constants import OLAS_TRADER_STAKING_CONTRACTS
41
- from iwa.plugins.olas.contracts.base import OLAS_ABI_PATH
42
38
 
43
39
  contracts = OLAS_TRADER_STAKING_CONTRACTS.get(chain, {})
44
40
 
45
41
  # Get service bond and token if filtered
46
42
  service_bond, service_token = _get_service_filter_info(service_key)
47
43
 
48
- # Load ABI once
49
- with open(OLAS_ABI_PATH / "staking.json", "r") as f:
50
- abi = json.load(f)
51
-
52
- # Get correct web3 instance
53
- w3 = ChainInterface(chain).web3
44
+ # Get correct interface from singleton manager
45
+ interface = ChainInterfaces().get(chain)
54
46
 
55
- results = _fetch_all_contracts(contracts, w3, abi)
47
+ results = _fetch_all_contracts(contracts, interface)
56
48
  filtered_results = _filter_contracts(results, service_bond, service_token)
57
49
 
58
50
  # Return with filter metadata so frontend can explain filtering
@@ -109,14 +101,20 @@ def _get_service_filter_info(service_key: Optional[str]) -> tuple[Optional[int],
109
101
  return service_bond, service_token
110
102
 
111
103
 
112
- def _check_availability(name, address, w3, abi):
104
+ def _check_availability(name, address, interface):
113
105
  """Check availability of a single staking contract."""
106
+ # Import at module level would cause circular import, but we can cache it
107
+ # The import is cached by Python after first call so this is efficient
108
+ from iwa.plugins.olas.contracts.staking import StakingContract
109
+
114
110
  try:
115
- contract = w3.eth.contract(address=address, abi=abi)
116
- service_ids = contract.functions.getServiceIds().call()
117
- max_services = contract.functions.maxNumServices().call()
118
- min_deposit = contract.functions.minStakingDeposit().call()
119
- staking_token = contract.functions.stakingToken().call()
111
+ contract = StakingContract(address, chain_name=interface.chain.name)
112
+
113
+ # StakingContract uses .call() which handles with_retry and rotation
114
+ service_ids = contract.call("getServiceIds")
115
+ max_services = contract.call("maxNumServices")
116
+ min_deposit = contract.call("minStakingDeposit")
117
+ staking_token = contract.call("stakingToken")
120
118
  used = len(service_ids)
121
119
 
122
120
  return {
@@ -141,15 +139,20 @@ def _check_availability(name, address, w3, abi):
141
139
  }
142
140
 
143
141
 
144
- def _fetch_all_contracts(contracts: dict, w3, abi) -> list:
145
- """Fetch availability for all contracts using threads."""
142
+ def _fetch_all_contracts(contracts: dict, interface) -> list:
143
+ """Fetch availability for all contracts using threads.
144
+
145
+ Note: Using limited parallelism (2 workers) to avoid overwhelming RPC
146
+ endpoints with parallel requests that cause 429 rate limit errors.
147
+ The RPC rotation mechanism is global but Contract objects are thread-local,
148
+ so excessive parallelism leads to stale providers being used.
149
+ """
146
150
  from concurrent.futures import ThreadPoolExecutor
147
151
 
148
152
  results = []
149
- with ThreadPoolExecutor(max_workers=10) as executor:
150
- # Pass w3 and abi to the helper
153
+ with ThreadPoolExecutor(max_workers=2) as executor:
151
154
  futures = [
152
- executor.submit(_check_availability, name, addr, w3, abi)
155
+ executor.submit(_check_availability, name, addr, interface)
153
156
  for name, addr in contracts.items()
154
157
  ]
155
158
  for future in futures:
iwa/web/routers/swap.py CHANGED
@@ -1,12 +1,12 @@
1
1
  """Swap Router for Web API."""
2
2
 
3
3
  import asyncio
4
- import logging
5
4
  from concurrent.futures import ThreadPoolExecutor
6
5
  from functools import lru_cache
7
6
  from typing import Any, Optional
8
7
 
9
8
  from fastapi import APIRouter, Depends, HTTPException, Request
9
+ from loguru import logger
10
10
  from pydantic import BaseModel, Field, field_validator
11
11
  from slowapi import Limiter
12
12
  from slowapi.util import get_remote_address
@@ -16,7 +16,6 @@ from iwa.core.chain import ChainInterfaces, SupportedChain
16
16
  from iwa.plugins.gnosis.cow import CowSwap
17
17
  from iwa.web.dependencies import verify_auth, wallet
18
18
 
19
- logger = logging.getLogger(__name__)
20
19
  router = APIRouter(prefix="/api/swap", tags=["swap"])
21
20
 
22
21
  limiter = Limiter(key_func=get_remote_address)
@@ -2,7 +2,6 @@
2
2
 
3
3
  import datetime
4
4
  import json
5
- import logging
6
5
 
7
6
  from fastapi import APIRouter, Depends, HTTPException, Request
8
7
  from pydantic import BaseModel, Field, field_validator
@@ -13,7 +12,6 @@ from web3 import Web3
13
12
  from iwa.core.db import SentTransaction
14
13
  from iwa.web.dependencies import verify_auth, wallet
15
14
 
16
- logger = logging.getLogger(__name__)
17
15
  router = APIRouter(prefix="/api", tags=["transactions"])
18
16
 
19
17
  # Rate limiter for this router
iwa/web/server.py CHANGED
@@ -9,11 +9,13 @@ from fastapi import FastAPI, Request
9
9
  from fastapi.middleware.cors import CORSMiddleware
10
10
  from fastapi.responses import HTMLResponse, JSONResponse
11
11
  from fastapi.staticfiles import StaticFiles
12
+ from loguru import logger
12
13
  from slowapi import Limiter, _rate_limit_exceeded_handler
13
14
  from slowapi.errors import RateLimitExceeded
14
15
  from slowapi.util import get_remote_address
15
16
  from starlette.middleware.base import BaseHTTPMiddleware
16
17
 
18
+ from iwa.core.utils import configure_logger
17
19
  from iwa.core.wallet import init_db
18
20
 
19
21
  # Pre-load cowdao_cowpy modules BEFORE async loop starts
@@ -21,15 +23,15 @@ from iwa.core.wallet import init_db
21
23
  # which fails if called from an already running event loop
22
24
  from iwa.plugins.gnosis.cow_utils import get_cowpy_module
23
25
 
24
- get_cowpy_module("DEFAULT_APP_DATA_HASH") # Forces import now, not during async
25
-
26
- # Import dependencies to ensure initialization
27
26
  # Import routers
28
- from iwa.web.routers import accounts, olas, state, swap, transactions # noqa: E402
27
+ from iwa.web.routers import accounts, olas, state, swap, transactions
28
+
29
+ get_cowpy_module("DEFAULT_APP_DATA_HASH") # Forces import now, not during async
29
30
 
30
- # Configure logging
31
+ # Configure logging (writes to iwa.log for frontend visibility)
32
+ configure_logger()
33
+ # Initialize standard logging for third-party libs (silenced by configure_logger but needed for basics)
31
34
  logging.basicConfig(level=logging.INFO)
32
- logger = logging.getLogger(__name__)
33
35
 
34
36
 
35
37
  # Rate limiter (in-memory storage, resets on restart)
iwa/web/static/app.js CHANGED
@@ -2564,6 +2564,8 @@ document.addEventListener("DOMContentLoaded", () => {
2564
2564
  // Show spinner, hide select, disable button
2565
2565
  select.style.display = "none";
2566
2566
  spinnerDiv.style.display = "block";
2567
+ spinnerDiv.innerHTML =
2568
+ '<span class="loading-spinner"></span> Loading contracts...';
2567
2569
  confirmBtn.disabled = true;
2568
2570
  modal.classList.add("active");
2569
2571
 
@@ -2689,6 +2691,8 @@ document.addEventListener("DOMContentLoaded", () => {
2689
2691
  // Load staking contracts
2690
2692
  contractSelect.style.display = "none";
2691
2693
  spinnerDiv.style.display = "block";
2694
+ spinnerDiv.innerHTML =
2695
+ '<span class="loading-spinner"></span> Loading contracts...';
2692
2696
  submitBtn.disabled = true;
2693
2697
 
2694
2698
  try {
@@ -2877,22 +2881,40 @@ document.addEventListener("DOMContentLoaded", () => {
2877
2881
  'button[type="submit"]',
2878
2882
  );
2879
2883
  contractSelect.style.display = "none";
2884
+
2885
+ // Remove hidden class to ensure visibility (overrides CSS !important)
2886
+ spinnerDiv.classList.remove("hidden");
2880
2887
  spinnerDiv.style.display = "block";
2888
+ spinnerDiv.innerHTML =
2889
+ '<span class="loading-spinner"></span> Loading contracts...';
2890
+
2881
2891
  submitBtn.disabled = true;
2892
+
2882
2893
  authFetch("/api/olas/staking-contracts?chain=gnosis")
2883
2894
  .then((resp) => resp.json())
2884
2895
  .then((contracts) => {
2885
2896
  state.stakingContractsCache = contracts;
2886
2897
  contractSelect.innerHTML = renderContractOptions(contracts);
2898
+
2887
2899
  contractSelect.style.display = "";
2900
+ contractSelect.classList.remove("hidden");
2901
+
2902
+ // Hide spinner
2888
2903
  spinnerDiv.style.display = "none";
2904
+ spinnerDiv.classList.add("hidden");
2905
+
2889
2906
  submitBtn.disabled = false;
2890
2907
  })
2891
2908
  .catch(() => {
2892
2909
  contractSelect.innerHTML =
2893
2910
  '<option value="">None (don\'t stake)</option>';
2894
2911
  contractSelect.style.display = "";
2912
+ contractSelect.classList.remove("hidden");
2913
+
2914
+ // Hide spinner even on error
2895
2915
  spinnerDiv.style.display = "none";
2916
+ spinnerDiv.classList.add("hidden");
2917
+
2896
2918
  submitBtn.disabled = false;
2897
2919
  });
2898
2920
  }
@@ -26,7 +26,7 @@ async def override_verify_auth():
26
26
  app.dependency_overrides[verify_auth] = override_verify_auth
27
27
 
28
28
 
29
- @pytest.fixture
29
+ @pytest.fixture(scope="module")
30
30
  def client():
31
31
  """TestClient for FastAPI app."""
32
32
  return TestClient(app, raise_server_exceptions=False)
@@ -28,7 +28,7 @@ async def override_verify_auth():
28
28
  app.dependency_overrides[verify_auth] = override_verify_auth
29
29
 
30
30
 
31
- @pytest.fixture
31
+ @pytest.fixture(scope="module")
32
32
  def client():
33
33
  """TestClient for FastAPI app."""
34
34
  return TestClient(app)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwa
3
- Version: 0.0.2
3
+ Version: 0.0.11
4
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
@@ -10,22 +10,22 @@ iwa/core/mnemonic.py,sha256=LiG1VmpydQoHQ0pHUJ1OIlrWJry47VSMnOqPM_Yk-O8,12930
10
10
  iwa/core/models.py,sha256=kBQ0cBe6uFmL2QfW7mjKiMFeZxhT-FRN-RyK3Ko0vE8,12849
11
11
  iwa/core/monitor.py,sha256=OmhKVMkfhvtxig3wDUL6iGwBIClTx0YUqMncCao4SqI,7953
12
12
  iwa/core/plugins.py,sha256=FLvOG4S397fKi0aTH1fWBEtexn4yvGv_QzGWqFrhSKE,1102
13
- iwa/core/pricing.py,sha256=5D2WAaDRuY1iOmj9fwgh_etnjjU6wdJmIgwoy8DbA2E,3614
13
+ iwa/core/pricing.py,sha256=B8dAUszv9t5EqvXQ7gh9CNBqlMLR598-c6Pv3NqtpO4,3561
14
14
  iwa/core/secrets.py,sha256=U7DZKrwKuSOFV00Ij3ISrrO1cWn_t1GBW_0PyAqjcD4,2588
15
15
  iwa/core/tables.py,sha256=y7Cg67PAGHYVMVyAjbo_CQ9t2iz7UXE-OTuUHRyFRTo,2021
16
16
  iwa/core/test.py,sha256=gey0dql5eajo1itOhgkSrgfyGWue2eSfpr0xzX3vc38,643
17
17
  iwa/core/types.py,sha256=EfDfIwLajTNK-BP9K17QLOIsGCs8legplKI_bUD_NjM,1992
18
18
  iwa/core/ui.py,sha256=DglmrI7XhUmOpLn9Nog9Cej4r-VT0JGFkuSNBx-XorQ,3131
19
- iwa/core/utils.py,sha256=Jc5yvyltYhnnPC9GdvNh_fW6bRuMen0XiG1nQcIuvhQ,2160
20
- iwa/core/wallet.py,sha256=ZxztWOK8MzIih7nGT52BUvE6Z5a9AA056IV_gqMPQpA,12972
19
+ iwa/core/utils.py,sha256=5fc8Ffd3F47iFb8QbnZmKh_d2Fsh1ZytVG2HFnhySEQ,2950
20
+ iwa/core/wallet.py,sha256=sNFK-_0y-EgeLpNHt9o5tCqTM0oVqJra-eAWjR7AgyU,13038
21
21
  iwa/core/chain/__init__.py,sha256=XJMmn0ed-_aVkY2iEMKpuTxPgIKBd41dexSVmEZTa-o,1604
22
22
  iwa/core/chain/errors.py,sha256=9SEbhxZ-qASPkzt-DoI51qq0GRJVqRgqgL720gO7a64,1275
23
- iwa/core/chain/interface.py,sha256=3tyMvnOZCTTvM0Y3YgxuN6zlXyJ1EIZUoyVosGtsUI8,20228
23
+ iwa/core/chain/interface.py,sha256=GRfWvSPUKdFNrkFD-lR7qFJYbQJs-oE7G_tQMBn4jA0,21097
24
24
  iwa/core/chain/manager.py,sha256=cFEzh6pK5OyVhjhpeMAqhc9RnRDQR1DjIGiGKp-FXBI,1159
25
- iwa/core/chain/models.py,sha256=h3-vygtsAHaY1-JSqTujr0JYs7OpzBfYTRsh-vOoEV4,4962
25
+ iwa/core/chain/models.py,sha256=0OgBo08FZEQisOdd00YUMXSAV7BC0CcWpqJ2y-gs0cI,4863
26
26
  iwa/core/chain/rate_limiter.py,sha256=gU7TmWdH9D_wbXKT1X7mIgoIUCWVuebgvRhxiyLGAmI,6613
27
27
  iwa/core/contracts/__init__.py,sha256=P5GFY_pnuI02teqVY2U0t98bn1_SSPAbcAzRMpCdTi4,34
28
- iwa/core/contracts/contract.py,sha256=ERWViqZNqhsmf-tKVxn5XfQTJ8S_1MXVk0Tjq8davd0,11228
28
+ iwa/core/contracts/contract.py,sha256=qHU1bvo1uhL2smY-dOrLSwVo6fb0ouWcpMsralGwJio,11440
29
29
  iwa/core/contracts/erc20.py,sha256=VqriOdUXej0ilTgpukpm1FUF_9sSrVMAPuEpIvyZ2SQ,2646
30
30
  iwa/core/contracts/multisend.py,sha256=tSdBCWe7LSdBoKZ7z2QebmRFK4M2ln7H3kmJBeEb4Ho,2431
31
31
  iwa/core/contracts/abis/erc20.json,sha256=vrdExMWcIogg_nO59j1Pmipmpa2Ulj3oCCdcdrrFVCE,16995
@@ -35,8 +35,8 @@ iwa/core/services/__init__.py,sha256=ab5pYzmu3LrZLTO5N-plx6Rp4R0hBEnbbzsgz84zWGM
35
35
  iwa/core/services/account.py,sha256=01MoEvl6FJlMnMB4fGwsPtnGa4kgA-d5hJeKu_ACg7Y,1982
36
36
  iwa/core/services/balance.py,sha256=mPE12CuOFfCaJXaQXWOcQM1O03ZF3ghpy_-oOjNk_GE,4104
37
37
  iwa/core/services/plugin.py,sha256=GNNlbtELyHl7MNVChrypF76GYphxXduxDog4kx1MLi8,3277
38
- iwa/core/services/safe.py,sha256=ULrzawkqcKjq-ffA0evndfp4OXi_VPVR9Yozvow8rFk,14587
39
- iwa/core/services/transaction.py,sha256=RsZmkTLAZbmH9oimuJ9qXes23e5Z9mf1WnMxyNiYMCM,6928
38
+ iwa/core/services/safe.py,sha256=ytNJMndXrzTMHwhDZKYLIh4Q0UTWDBgQgTpof-UqIkA,14827
39
+ iwa/core/services/transaction.py,sha256=3IeTLntewa9XevPTMrNhjOUwdv0nMdU3KqlxljjL0Z0,14286
40
40
  iwa/core/services/transfer/__init__.py,sha256=ZJfshFxJRsp8rkOqfVvd1cqEzIJ9tqBJh8pc0l90GLk,5576
41
41
  iwa/core/services/transfer/base.py,sha256=sohz-Ss2i-pGYGl4x9bD93cnYKcSvsXaXyvyRawvgQs,9043
42
42
  iwa/core/services/transfer/erc20.py,sha256=0GvlfETgdJg15azs1apH1gI6Vm3gAv22o1saNbIfiAY,8685
@@ -48,31 +48,32 @@ iwa/plugins/__init__.py,sha256=zy-DjOZn8GSgIETN2X_GAb9O6yk71t6ZRzeUgoZ52KA,23
48
48
  iwa/plugins/gnosis/__init__.py,sha256=dpx0mE84eV-g5iZaH5nKivZJnoKWyRFX5rhdjowBwuU,114
49
49
  iwa/plugins/gnosis/cow_utils.py,sha256=iSvbfgTr2bCqRsUznKCWqmoTnyuX-WZX4oh0E-l3XBU,2263
50
50
  iwa/plugins/gnosis/plugin.py,sha256=AgkgOGYfnrcjWrPUiAvySMj6ITnss0SFXiEi6Z6fnMs,1885
51
- iwa/plugins/gnosis/safe.py,sha256=MUjb3VyoRVU5NlcLLtVfzPd-LmANfvHtsgqbG8YOa44,5505
51
+ iwa/plugins/gnosis/safe.py,sha256=aDcBz50Bliur90sVqxgjGoQJyCqsfZlm0PDsmWIDBak,5517
52
52
  iwa/plugins/gnosis/cow/__init__.py,sha256=lZN5QpIYWL67rE8r7z7zS9dlr8OqFrYeD9T4-RwUghU,224
53
53
  iwa/plugins/gnosis/cow/quotes.py,sha256=u2xFKgL7QTKqCkSPMv1RHaXvZ6WzID4haaZDMVS42Bs,5177
54
54
  iwa/plugins/gnosis/cow/swap.py,sha256=XZdvJbTbh54hxer7cKkum7lNQ-03gddMK95K3MenaFE,15209
55
55
  iwa/plugins/gnosis/cow/types.py,sha256=-9VRiFhAkmN1iIJ95Pg7zLFSeXtkkW00sl13usxi3o8,470
56
56
  iwa/plugins/gnosis/tests/test_cow.py,sha256=iVy5ockMIcPZWsX4WGXU91DhBsYEZ5NOxtFzAQ2sK3o,8440
57
- iwa/plugins/gnosis/tests/test_safe.py,sha256=BY6MJZqONrvIIougRpOQQsTNDOAjUsKXToTcwdMby44,3084
57
+ iwa/plugins/gnosis/tests/test_safe.py,sha256=pw1zrYvAiVtmPIU5k7BtOQpDNAQTSTrLIaeljCjSahc,3216
58
58
  iwa/plugins/olas/__init__.py,sha256=_NhBczzM61fhGYwGhnWfEeL8Jywyy_730GASe2BxzeQ,106
59
59
  iwa/plugins/olas/constants.py,sha256=mFUMDB46WbM9Y8sw7c-i9TRyJVrDNZXdCXa64M5tI6A,6608
60
60
  iwa/plugins/olas/importer.py,sha256=f8KlZ9dGcNbpg8uoTYbO9sDvbluZoslhpWFLqPjPnLA,26717
61
61
  iwa/plugins/olas/mech_reference.py,sha256=CaSCpQnQL4F7wOG6Ox6Zdoy-uNEQ78YBwVLILQZKL8Q,5782
62
62
  iwa/plugins/olas/models.py,sha256=xC5hYakX53pBT6zZteM9cyiC7t6XRLLpobjQmDYueOo,3520
63
- iwa/plugins/olas/plugin.py,sha256=wncoujfR1YXhJeCYwLxaX5J50OzoA3KUG8q02DRWDtA,9231
63
+ iwa/plugins/olas/plugin.py,sha256=S_vnvZ02VdVWD7N5kp7u5JIRQ2JLtfwGDZ7OHkAN0M8,9390
64
64
  iwa/plugins/olas/contracts/activity_checker.py,sha256=UDbCgFOyuEhHf1qoUwCUdLc8oK8ksuAYE-ZgKrMBnwg,3415
65
65
  iwa/plugins/olas/contracts/base.py,sha256=y73aQbDq6l4zUpz_eQAg4MsLkTAEqjjupXlcvxjfgCI,240
66
66
  iwa/plugins/olas/contracts/mech.py,sha256=dXYtyORc-oiu9ga5PtTquOFkoakb6BLGKvlUsteygIg,2767
67
67
  iwa/plugins/olas/contracts/mech_marketplace.py,sha256=hMADl5MQGvT2wLRKu4vHGe4RrAZVq8Y2M_EvXWWz528,1554
68
- iwa/plugins/olas/contracts/service.py,sha256=OHXi4TBaVlRRZJA15XKnTMN8huGDWRZWU1TOZf589_E,6731
69
- iwa/plugins/olas/contracts/staking.py,sha256=pxT62Cal1kkDfZdhbPk2YxyM2Xbf8-oFa40lL0Y8HBk,14520
68
+ iwa/plugins/olas/contracts/service.py,sha256=BDQKeCTCnBNrwKD1a8rrlLytpKG3CAdjr-s0ec-dsFY,8243
69
+ iwa/plugins/olas/contracts/staking.py,sha256=vt2UZ6G0edg1EbPrzFK5AIse531bQTu4PLydQ6rgrAA,14494
70
70
  iwa/plugins/olas/contracts/abis/activity_checker.json,sha256=HT0IMbyTLMO71ITBKwoS950rHe772suPP4b8eDAodJ0,2230
71
71
  iwa/plugins/olas/contracts/abis/mech.json,sha256=bMMCXInjE_2PTPnc_sIyS_H8pod5Sm_e-xTbKgZppKc,16369
72
72
  iwa/plugins/olas/contracts/abis/mech_marketplace.json,sha256=KPnF-H_UATb3wdb_7o6ky_hSp5xwgvckD-QqylsWJLg,32468
73
73
  iwa/plugins/olas/contracts/abis/mech_new.json,sha256=j6HkhTpVQEA4la13Kp1Q_pwlt2x5Ywh7GCEjz4q2_ws,20995
74
74
  iwa/plugins/olas/contracts/abis/service_manager.json,sha256=jsByfx_NPNqHJBbauGEg2S41D0ZYUHa24TzpJQuk604,29735
75
75
  iwa/plugins/olas/contracts/abis/service_registry.json,sha256=phtK1FHUZRtUHP0HeISyO2jlrlzGiETON_Ljd_kLYn4,43864
76
+ iwa/plugins/olas/contracts/abis/service_registry_token_utility.json,sha256=GR02mv9b8yckGubh_Huca_jbczw30AG-34ocZELNLPI,57624
76
77
  iwa/plugins/olas/contracts/abis/staking.json,sha256=_W3NBuygSU-tsqdWTD7P0PmCVz7ZUCqIoJkW60ChjLw,31139
77
78
  iwa/plugins/olas/contracts/abis/staking_token.json,sha256=cuUOmi1s4Z6VSIX0an_IxK6qkPeoyPt3NUdvlX8GlPI,81288
78
79
  iwa/plugins/olas/scripts/test_full_mech_flow.py,sha256=id9IxC06FOKwexgwsG5nbsTB2rQLlIq5a5soMvK0IgY,9021
@@ -80,28 +81,28 @@ iwa/plugins/olas/scripts/test_simple_lifecycle.py,sha256=8T50tOZx3afeECSfCNAb0rA
80
81
  iwa/plugins/olas/service_manager/__init__.py,sha256=GXiThMEY3nPgHUl1i-DLrF4h96z9jPxxI8Jepo2E1PM,1926
81
82
  iwa/plugins/olas/service_manager/base.py,sha256=V4o71ZYUSc_GzM-RWocaAGsrqI-fa5V7CcyloVpcjwE,4666
82
83
  iwa/plugins/olas/service_manager/drain.py,sha256=IS7YYKuQdkULcNdxfHVzjcq95pXKdpajolzLL78u4jc,12430
83
- iwa/plugins/olas/service_manager/lifecycle.py,sha256=-WG1ZQmC5F3vrqkMPX9iS_gcCmO_bSqAUHA3C6P8bpo,34161
84
- iwa/plugins/olas/service_manager/mech.py,sha256=jIdDzJlz-iNNrC-SErYmcbmKiEk6-zaYIGvzeQx12C4,12217
85
- iwa/plugins/olas/service_manager/staking.py,sha256=nZHB_dQ-jdMs2RtSrsmeIeaww9dQeVDqwlItiP7cp2Y,20772
84
+ iwa/plugins/olas/service_manager/lifecycle.py,sha256=DIB6yrP0VPICu6558uQJuFp2sgrA66iVNTzZVUUowGw,47159
85
+ iwa/plugins/olas/service_manager/mech.py,sha256=72-tEap-aYd0gebcH6y_De1SNeL6OrXn7sWuv_Ok_-Y,12224
86
+ iwa/plugins/olas/service_manager/staking.py,sha256=Z9GzlPfY7qSSjc9xPhWvb9qywxu_7OB3Gc1eBli07pY,28058
86
87
  iwa/plugins/olas/tests/conftest.py,sha256=4vM7EI00SrTGyeP0hNzsGSQHEj2-iznVgzlNh2_OGfo,739
87
88
  iwa/plugins/olas/tests/test_importer.py,sha256=i9LKov7kNRECB3hmRnhKBwcfx3uxtjWe4BB77bOOpeo,4282
88
89
  iwa/plugins/olas/tests/test_importer_error_handling.py,sha256=X37TrvJ6-3-NuJ2megm0Cnx3KJdA1wke563pRf_EPJk,12084
89
90
  iwa/plugins/olas/tests/test_mech_contracts.py,sha256=wvxuigPafF-ySIHVBdWVei3AO418iPh7cSVdAlUGm_s,3566
90
- iwa/plugins/olas/tests/test_olas_contracts.py,sha256=V409KPeGQl6wYV8unyiZ381TGahFcPNZxj1zJ40VbAM,10627
91
+ iwa/plugins/olas/tests/test_olas_contracts.py,sha256=B8X-5l1KfYMoZOiM94_rcNzbILLl78rqt_jhyxzAOqE,10835
91
92
  iwa/plugins/olas/tests/test_olas_integration.py,sha256=uIA9NB1iaOSTOaPgY5gRvrFxFLeq6Z93239yi2qzj1g,20488
92
93
  iwa/plugins/olas/tests/test_olas_models.py,sha256=5scX-wvRLGH3G44S2okq_tyQ9Rk7Pd0Ak1zNCZ2HtI4,4957
93
94
  iwa/plugins/olas/tests/test_olas_view.py,sha256=kh3crsriyoRiZC6l8vzGllocvQnYmqziv-csbmXih0E,10489
94
95
  iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=jAxr9bjFNAaxGf1btIrxdMaHgJ0PWX9aDwVU-oPGMpk,5109
95
96
  iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvqGt49H6fLSYGxn02c8o,5562
96
- iwa/plugins/olas/tests/test_plugin.py,sha256=UIEgW_VMivqJllOAd3mmTltM0DF_ZBK79ecpIiBricI,2429
97
- iwa/plugins/olas/tests/test_plugin_full.py,sha256=RdDY_fYGkpfP3s742yBBh-gPr5uc1dfhZsrpGCrCeu8,8224
98
- iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=dhIDzgcXh1VV-S6VGXtNqtdxxIdXY1F1hRcPL6RBxno,5649
99
- iwa/plugins/olas/tests/test_service_manager.py,sha256=dsnj1DfSYptIZkiPaLHGM9utbX9XOAy0axuzu-3kofg,41818
100
- iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=BtN-89gwaFpy3RJIDt98U0TT0lksg9NHvoSpSBHSXag,8229
101
- iwa/plugins/olas/tests/test_service_manager_flows.py,sha256=HsAD1axnfow1iTiRBqR7DT6sa3U-q8ApOlYN4Cd87Ao,20142
97
+ iwa/plugins/olas/tests/test_plugin.py,sha256=RVgU-Cq6t_3mOh90xFAGwlJOV7ZIgp0VNaK5ZAxisAQ,2565
98
+ iwa/plugins/olas/tests/test_plugin_full.py,sha256=xevLYmdU4zd5FyEEEn9gvzGimPztmt6vymybeZHXnq8,8507
99
+ iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=sOCtpz8T9s55AZe9AoqP1h3XrXw5NDSjDqwLgYThvU4,5559
100
+ iwa/plugins/olas/tests/test_service_manager.py,sha256=wUdgB_73WtMxzpO3olMCwet9v9EudGr9uQyXeF9o_yE,40380
101
+ iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=M49aZQYVBvPAEvJdpJO6gN8wC1tUdHnln7XxmqO_O50,8151
102
+ iwa/plugins/olas/tests/test_service_manager_flows.py,sha256=lxkXdK2Ht92wAywMUyXYYRfkR3boixzGGF47MEgcq54,19418
102
103
  iwa/plugins/olas/tests/test_service_manager_mech.py,sha256=qG6qu5IPRNypXUsblU2OEkuiuwDJ0TH8RXZbibmTFcQ,4937
103
104
  iwa/plugins/olas/tests/test_service_manager_rewards.py,sha256=hIVckGl5rEr-KHGNUxxVopal0Tpw4EZharBt0MbaCVA,11798
104
- iwa/plugins/olas/tests/test_service_manager_validation.py,sha256=dagFvq8eQk3HKYpajp_2uJ4AUi_74kIAMfTiN4qAZ58,5263
105
+ iwa/plugins/olas/tests/test_service_manager_validation.py,sha256=ajlfH5uc4mAHf8A7GLE5cW7X8utM2vUilM0JdGDdlVg,5382
105
106
  iwa/plugins/olas/tests/test_service_staking.py,sha256=XkC8H_qVumOQ1i4_vidEdXqkK5stInd2tgT50l0SRMk,12201
106
107
  iwa/plugins/olas/tests/test_staking_integration.py,sha256=zQdhhSLz5h2OvQ6GOJ-Yl_Y17itPML4Pr9VPkjWoz9c,9420
107
108
  iwa/plugins/olas/tests/test_staking_validation.py,sha256=J7DgDdIiVTkKv_7obtSHQ2lgfUGPmUwuPjTUkiT4cbs,4198
@@ -109,7 +110,7 @@ iwa/plugins/olas/tui/__init__.py,sha256=5ZRsbC7J3z1xfkZRiwr4bLEklf78rNVjdswe2p7S
109
110
  iwa/plugins/olas/tui/olas_view.py,sha256=qcPxhurDPJjHWln6R64ZVAJ2h82IXzw48unhRvQVZqQ,36448
110
111
  iwa/tools/__init__.py,sha256=jQyuwDQGRigSe7S9JMb4yK3CXPgZFJNffzt6N2v9PU0,21
111
112
  iwa/tools/check_profile.py,sha256=0LAv9wx4wMM610mX88-6tIoDi2I5LDzh0W9nkprt42s,2177
112
- iwa/tools/list_contracts.py,sha256=m5-m_zDuKENlCf6LiDFRh0gKcwVhrP-XNzsyy_upwV0,4864
113
+ iwa/tools/list_contracts.py,sha256=2w-LYB2RVS-eGil2kLiBIEm3tYYhYzT4lAuGO6VtLJU,4861
113
114
  iwa/tools/release.py,sha256=-Z9GG6Y-K6KG32K0VUf_MruiUdJxG6W7ToOMzhyCH7Y,3963
114
115
  iwa/tools/reset_env.py,sha256=FKN0wuh9Xq00c94B2kEFehHPKcWldxYqgU45yJwg5Cg,3140
115
116
  iwa/tools/reset_tenderly.py,sha256=w1-KujdqRpimrgiREvoRwVXsGsGoYisCLmYTcsJ6Np8,11295
@@ -129,27 +130,27 @@ iwa/tui/tests/test_wallets_refactor.py,sha256=71G3HLbhTtgDy3ffVbYv0MFYRgdYd-NWGB
129
130
  iwa/tui/tests/test_widgets.py,sha256=C9UgIGeWRaQ459JygFEQx-7hOi9mWrSUDDIMZH1ge50,3994
130
131
  iwa/tui/widgets/__init__.py,sha256=UzD6nJbwv9hOtkWl9I7faXm1a-rcu4xFRxrf4KBwwY4,161
131
132
  iwa/tui/widgets/base.py,sha256=G844GU61qSS6AgY5NxmOVHTghbgHlyTfo8hhE2VUrqQ,3379
132
- iwa/web/dependencies.py,sha256=xy99q7mJr-kCyh2hZAI0beaOtXVfppJbNmLhhbdam-g,2130
133
+ iwa/web/dependencies.py,sha256=0_dAJlRh6gKrUDRPKUe92eshFsg572yx_H0lQgSqGDA,2103
133
134
  iwa/web/models.py,sha256=MSD9WPy_Nz_amWgoo2KSDTn4ZLv_AV0o0amuNtSf-68,3035
134
- iwa/web/server.py,sha256=_7kDO-1J9znIGcOzdUuCBEePoAfjdubAmp6mxX7k2g8,5100
135
- iwa/web/routers/accounts.py,sha256=j6xFkKGeLkjpUG48vW8ZFsWzLxl-Vi5et7rcTsOJkiI,3942
135
+ iwa/web/server.py,sha256=4ZLVFEKoGs_NoCcXMeyYzDNdxUXazjwHQaX7CR1pwHE,5239
136
+ iwa/web/routers/accounts.py,sha256=HP7DdUbbnRb1dFCs7zqyhx61_IBJwDMKtmXpvAPZodg,3916
136
137
  iwa/web/routers/state.py,sha256=aEfeGFAOyaS6kWhXuWLrdvEbnQAeonKIWxJrQkqJ1GY,2198
137
- iwa/web/routers/swap.py,sha256=mU9StUZpJPvD8De412nmwlCYHRnGR4ISVl1YKF3gIb8,22656
138
- iwa/web/routers/transactions.py,sha256=ZDKaqCTt1ZylzxyfFQHxFPwzD-j9H0jUByYFSWvggBA,5654
138
+ iwa/web/routers/swap.py,sha256=8xycAytquR29ELxW3vx428W8s9bI_w_x2kpRhhJ0KXY,22630
139
+ iwa/web/routers/transactions.py,sha256=bRjfD7zcuX3orVIHzOMVsIkEtcE_pM_KCom4cdAKV6Q,5602
139
140
  iwa/web/routers/olas/__init__.py,sha256=Jo6Dm1e8fHafCD800fbxsxeFz3tvuEEKXEf5-9tj5Qg,947
140
- iwa/web/routers/olas/admin.py,sha256=ZFUTsA7k2xI16kSQ6OybN3jtJQQxh71Y5-Dc2s31rRI,5812
141
- iwa/web/routers/olas/funding.py,sha256=Jko_uZynE9cahf7ObjHfR54_9jNeU2m2hOJ8PUxegvI,4859
142
- iwa/web/routers/olas/general.py,sha256=gsL-bkOWTHLxw65Bt3T61123QUZpjxwbNkrx5Qo7s5E,830
143
- iwa/web/routers/olas/services.py,sha256=5W4Cvj5HQjxmEokPfVpaV1v_YKwOcm6SQfyXsgwpBZo,14766
144
- iwa/web/routers/olas/staking.py,sha256=9FH-yNUuG2KJxaI6HYn3d6fY5QvXd8UPCx01mDFYSgQ,12090
145
- iwa/web/static/app.js,sha256=CI9daKLWei3DpnMgUz693HqlCRrYN3ZEVi-wFI01t5U,112769
141
+ iwa/web/routers/olas/admin.py,sha256=PMRdNelqYgQ1xbqh3floFV5xrVtBRQiwZPd8J9_ffxg,5785
142
+ iwa/web/routers/olas/funding.py,sha256=f8fADNtbZEBFl-vuVKfas6os38Vot6K5tJBTenZmCD0,4832
143
+ iwa/web/routers/olas/general.py,sha256=dPsBQppTGoQY1RztliUhseOHOZGeeCR10lhThD9kyXo,803
144
+ iwa/web/routers/olas/services.py,sha256=IpjvkpJeCwREbdHt47gov-fvTl9bY4EBUmZZZEHi3iI,16310
145
+ iwa/web/routers/olas/staking.py,sha256=N1pMcPjhpfSPi7Sl7XIIAPoFxf0hptdvkUqkTtgqPcc,12424
146
+ iwa/web/static/app.js,sha256=BCpAp1BcFVcfEfqXa-9gOtjb-8YlV5NIPWgSeCchD1E,113472
146
147
  iwa/web/static/index.html,sha256=q7s7plnMbN1Nkzr5bRxZgvgOFerUChEGIZW7SpAVtPc,28514
147
148
  iwa/web/static/style.css,sha256=aTtE42mmfYV6y7xfo9cUgUhT8x-KyNC1zmPjSdskxIk,24315
148
- iwa/web/tests/test_web_endpoints.py,sha256=vZUGmrudkQHA8gBmSyO8i2SgZpsr1He-YRm2JFAs9lg,23979
149
- iwa/web/tests/test_web_olas.py,sha256=oN__4nUT_H_j-_ALEqSp-si5xMbY0Bcxhvhuhxsg4Q8,16292
149
+ iwa/web/tests/test_web_endpoints.py,sha256=C264MH-CTyDW4GLUrTXBgLJKUk4-89pFAScBddd4Fvk,23995
150
+ iwa/web/tests/test_web_olas.py,sha256=0CVSsrncOeJ3x0ECV7mVLQV_CXZRrOqGiVjgLIi6hZ8,16308
150
151
  iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
151
152
  iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
152
- iwa-0.0.2.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
153
+ iwa-0.0.11.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
153
154
  tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
154
155
  tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
155
156
  tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
@@ -158,17 +159,17 @@ tests/legacy_wallets_screen.py,sha256=9hZnX-VhKgwH9w8MxbNdboRyNxLDhOakLKJECsw_vh
158
159
  tests/legacy_web.py,sha256=q2ERIriaDHT3Q8axG2N3ucO7f2VSvV_WkuPR00DVko4,8577
159
160
  tests/test_account_service.py,sha256=g_AIVT2jhlvUtbFTaCd-d15x4CmXJQaV66tlAgnaXwY,3745
160
161
  tests/test_balance_service.py,sha256=86iEkPd2M1-UFy3qOxV1EguQOEYbboy2-2mAyS3ctGs,6549
161
- tests/test_chain.py,sha256=uXbNl9wD4e2qV1xs_MO74Soj3iaH-5xoxge4rD3FypU,16986
162
+ tests/test_chain.py,sha256=naDz3WNrB8J3hAcId8of8R4_jN0vEWMC28-70hQEU_s,17240
162
163
  tests/test_chain_interface.py,sha256=Wu0q0sREtmYBp7YvWrBIrrSTtqeQj18oJp2VmMUEMec,8312
163
- tests/test_chain_interface_coverage.py,sha256=cmZGxpBjf8pT9PwtECMqBbrUMaAJu6v3D8C18nfPyQ0,3248
164
+ tests/test_chain_interface_coverage.py,sha256=fvrVvw8-DMwdsSFKQHUhpbfutrVRxnnTc-tjB7Bb-jo,3327
164
165
  tests/test_cli.py,sha256=WW6EDeHLws5-BqFNOy11pH_D5lttuyspD5hrDCFpR0Q,3968
165
- tests/test_contract.py,sha256=XigxdTziO5SJVbg8_mWPQdbkTIQBA-W8d3WPij4KTyQ,7738
166
+ tests/test_contract.py,sha256=MuL9dI_EJXo7hNiapUPNqmP87LRh3_HluAtOEGEWyus,14116
166
167
  tests/test_db.py,sha256=dmbrupj0qlUeiiycZ2mzMFjf7HrDa6tcqMPY8zpiKIk,5710
167
168
  tests/test_drain_coverage.py,sha256=jtN5tIXzSTlS2IjwLS60azyMYsjFDlSTUa98JM1bMic,6786
168
169
  tests/test_erc20.py,sha256=kNEw1afpm5EbXRNXkjpkBNZIy7Af1nqGlztKH5IWAwU,3074
169
170
  tests/test_gnosis_plugin.py,sha256=XMoHBCTrnVBq9bXYPzMUIrhr95caucMVRxooCjKrzjg,3454
170
- tests/test_keys.py,sha256=BUKaZmnEzs7HzUCiEIMiLd2aJRegLOflOkVlC9s3XXs,17405
171
- tests/test_legacy_wallet.py,sha256=8u83TTJv2zmdfBaLXIhsrbBREqm7EA1KH6J6ZjTyzuc,49604
171
+ tests/test_keys.py,sha256=pxlGlHB-NaTbC8qar093ttdHLLtkM8irVNmCbH2KVf4,17421
172
+ tests/test_legacy_wallet.py,sha256=j7AorUMvuChyxy18y9j8Ux8wpZa2_ZvKutp5obKLLI0,49895
172
173
  tests/test_main.py,sha256=y2xr7HjCt4rHsxm8y6n24FKCteSHPyxC3DFuMcUgX1Y,475
173
174
  tests/test_migration.py,sha256=fYoxzI3KqGh0cPV0bFcbvGrAnKcNlvnwjggG_uD0QGo,1789
174
175
  tests/test_mnemonic.py,sha256=BFtXMMg17uHWh_H-ZwAOn0qzgbUCqL8BRLkgRjzfzxo,7379
@@ -177,19 +178,19 @@ tests/test_models.py,sha256=1bEfPiDVgEdtwFEzwecSPAHjCF8kjOPSMeQExJ7eCJ4,7107
177
178
  tests/test_monitor.py,sha256=P_hF61VMlCX2rh9yu_a6aKhlgXOAcCMGOZRntjcqrd0,7255
178
179
  tests/test_multisend.py,sha256=IvXpwnC5xSDRCyCDGcMdO3L-eQegvdjAzHZB0FoVFUI,2685
179
180
  tests/test_plugin_service.py,sha256=ZEe37kV_sv4Eb04032O1hZIoo9yf5gJo83ks7Grzrng,3767
180
- tests/test_pricing.py,sha256=fTrqBZ4-4W1REl-zy7RN2UKcqYi0UIbmRFB9Ni0iAf0,4685
181
+ tests/test_pricing.py,sha256=ptu_2Csc6d64bIzMMw3TheJge2Kfn05Gs-twz_KmBzg,5276
181
182
  tests/test_rate_limiter.py,sha256=DOIlrBP2AtVFHCpznIoFn2FjFc33emG7M_FffLh4MGE,7314
182
183
  tests/test_reset_tenderly.py,sha256=GVoqbDT3n4_GnlKF5Lx-8ew15jT8I2hIPdTulQDb6dI,7215
183
184
  tests/test_rpc_view.py,sha256=sgZ53KEHl8VGb7WKYa0VI7Cdxbf8JH1SdroHYbWHjfQ,2031
184
- tests/test_safe_coverage.py,sha256=J09TlcPYVms9bqDtVRPs9TnA102obUuApHXsmEDVJsI,5098
185
- tests/test_safe_service.py,sha256=HsUJZxwLCfObdHkCwfesfp8XBiv5gCx9JIJLsHuWgDg,5899
185
+ tests/test_safe_coverage.py,sha256=g9Bdrpkc-Mc8HBjk07lYNRkzxWZiF922uiVLZqhehBE,5093
186
+ tests/test_safe_service.py,sha256=nxDYmGd6p2gGe7BEeMxsqS8CgeJarPofV38HC6Cop44,5770
186
187
  tests/test_service_manager_integration.py,sha256=I_BLUzEKrVTyg_8jqsUK0oFD3aQVPCRJ7z0gY8P-j04,2354
187
188
  tests/test_service_manager_structure.py,sha256=zK506ucCXCBHcjPYKrKEuK1bgq0xsbawyL8Y-wahXf8,868
188
- tests/test_service_transaction.py,sha256=Jzb6oADMrlxNdgVvr3urpYz5NCRNO6h6bUTUQDKeTxQ,6224
189
- tests/test_staking_router.py,sha256=l7IqP9t6eGMgiW0PKW6tmdP2Wb6Fz9diRDjptjzKiLA,2621
189
+ tests/test_service_transaction.py,sha256=SecU2Fy32jLH4lg0CZHNrNkqM1pzPnYB0qZtxqaDnFE,6416
190
+ tests/test_staking_router.py,sha256=e8bI_u24SsORn9bkf4QWOtFoGxi86WTyu_Zl_QnUvpA,2769
190
191
  tests/test_staking_simple.py,sha256=NHyZ1pcVQEJGFiGseC5m6Y9Y6FJGnRIFJUwhd1hAV9g,1138
191
192
  tests/test_tables.py,sha256=1KQHgxuizoOrRxpubDdnzk9iaU5Lwyp3bcWP_hZD5uU,2686
192
- tests/test_transaction_service.py,sha256=NhTuzZnmIbMRbiO1lXutzFNhjdyGDb4QNXbm9U4D7yM,5154
193
+ tests/test_transaction_service.py,sha256=iuRMyOsMS4fRNIhudbW0ovSfA6vGzZpjIApVryOpO3U,5283
193
194
  tests/test_transfer_multisend.py,sha256=PErjNqNwN66TMh4oVa307re64Ucccg1LkXqB0KlkmsI,6677
194
195
  tests/test_transfer_native.py,sha256=cDbb4poV_veIw6eHpokrHe9yUndOjA6rQhrHd_IY3HQ,7445
195
196
  tests/test_transfer_security.py,sha256=gdpC6ybdXQbQgILbAQ0GqjWdwn9AJRNR3B_7TYg0NxI,3617
@@ -198,9 +199,10 @@ tests/test_transfer_swap_unit.py,sha256=v_tld2oF2jFf_qdrCxIPQFlAymQqHT2dcw2Z05qW
198
199
  tests/test_ui_coverage.py,sha256=N-7uhPlKOXCKyS32VjwG3JQRnAS1PoAJxR-InaOZtCQ,2423
199
200
  tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
200
201
  tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
201
- tools/verify_drain.py,sha256=1On4GmXWETA-CHfFjd7qAqIQuSgKIaEomKKXM7S8wfk,6881
202
- iwa-0.0.2.dist-info/METADATA,sha256=LI8zcRvzlRmevpeYLa1O5KdZbF6GX5L-Xp7QLUcgSI8,7294
203
- iwa-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
204
- iwa-0.0.2.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
205
- iwa-0.0.2.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
206
- iwa-0.0.2.dist-info/RECORD,,
202
+ tools/create_and_stake_service.py,sha256=1xwy_bJQI1j9yIQ968Oc9Db_F6mk1659LuuZntTASDE,3742
203
+ tools/verify_drain.py,sha256=PkMjblyOOAuQge88FwfEzRtCYeEtJxXhPBmtQYCoQ-8,6743
204
+ iwa-0.0.11.dist-info/METADATA,sha256=zjnguna0n38HHpQ8UrUvwj4gT8ZZkIp7ivYg0mYax_w,7295
205
+ iwa-0.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
206
+ iwa-0.0.11.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
207
+ iwa-0.0.11.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
208
+ iwa-0.0.11.dist-info/RECORD,,
tests/test_chain.py CHANGED
@@ -340,8 +340,13 @@ def test_chain_interface_with_real_chains():
340
340
  sym = interface.get_token_symbol(valid_addr_1)
341
341
  assert sym == "SYM"
342
342
 
343
- dec = interface.get_token_decimals(valid_addr_1)
344
- assert dec == 18
343
+ # get_token_decimals uses web3.eth.contract directly, not ERC20Contract
344
+ mock_contract = MagicMock()
345
+ mock_contract.functions.decimals.return_value.call.return_value = 18
346
+ interface.web3.eth.contract.return_value = mock_contract
347
+
348
+ dec = interface.get_token_decimals(valid_addr_1)
349
+ assert dec == 18
345
350
 
346
351
 
347
352
  # --- Negative Tests ---
@@ -438,13 +443,13 @@ def test_get_token_decimals_fallback_on_error(mock_web3):
438
443
 
439
444
  ci = ChainInterface(chain)
440
445
 
441
- with patch("iwa.core.contracts.erc20.ERC20Contract") as mock_erc20:
442
- mock_erc20.side_effect = Exception("Contract not found")
446
+ # get_token_decimals uses web3.eth.contract directly, mock it to raise error
447
+ ci.web3.eth.contract.side_effect = Exception("Contract not found")
443
448
 
444
- decimals = ci.get_token_decimals("0x1234567890123456789012345678901234567890")
449
+ decimals = ci.get_token_decimals("0x1234567890123456789012345678901234567890")
445
450
 
446
- # Should return default 18 as fallback
447
- assert decimals == 18
451
+ # Should return default 18 as fallback
452
+ assert decimals == 18
448
453
 
449
454
 
450
455
  def test_is_rate_limit_error_detection(mock_web3):
@@ -31,8 +31,9 @@ def test_rpc_rotation_exhaustion(mock_web3):
31
31
  # We also need to prevent rotation from working or make rotation also fail
32
32
  # Since we only have 2 RPCs, eventually it will give up.
33
33
 
34
- with pytest.raises(Exception, match="Connection Error"):
35
- chain.with_retry(lambda: chain.web3.eth.get_block("latest"))
34
+ with patch("time.sleep"): # Avoid real exponential backoff delays
35
+ with pytest.raises(Exception, match="Connection Error"):
36
+ chain.with_retry(lambda: chain.web3.eth.get_block("latest"))
36
37
 
37
38
 
38
39
  def test_rate_limiting_backoff(mock_web3):