iwa 0.0.10__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.
- iwa/core/chain/interface.py +21 -7
- iwa/core/services/transaction.py +196 -3
- iwa/core/wallet.py +2 -1
- iwa/plugins/olas/contracts/abis/service_registry_token_utility.json +926 -0
- iwa/plugins/olas/contracts/service.py +50 -0
- iwa/plugins/olas/service_manager/lifecycle.py +275 -39
- iwa/plugins/olas/service_manager/staking.py +152 -63
- iwa/plugins/olas/tests/test_olas_contracts.py +6 -2
- iwa/plugins/olas/tests/test_service_lifecycle.py +1 -4
- iwa/plugins/olas/tests/test_service_manager.py +59 -89
- iwa/plugins/olas/tests/test_service_manager_errors.py +1 -2
- iwa/plugins/olas/tests/test_service_manager_flows.py +5 -15
- iwa/web/routers/olas/services.py +52 -19
- iwa/web/routers/olas/staking.py +8 -2
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/METADATA +1 -1
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/RECORD +21 -20
- tests/test_chain.py +12 -7
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/WHEEL +0 -0
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/entry_points.txt +0 -0
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/licenses/LICENSE +0 -0
- {iwa-0.0.10.dist-info → iwa-0.0.11.dist-info}/top_level.txt +0 -0
iwa/web/routers/olas/services.py
CHANGED
|
@@ -28,6 +28,50 @@ class CreateServiceRequest(BaseModel):
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def _determine_bond_amount(req: CreateServiceRequest) -> int:
|
|
32
|
+
"""Determine the bond amount required for the service."""
|
|
33
|
+
from web3 import Web3
|
|
34
|
+
|
|
35
|
+
from iwa.core.contracts.erc20 import ERC20Contract
|
|
36
|
+
from iwa.plugins.olas.contracts.staking import StakingContract
|
|
37
|
+
from iwa.web.dependencies import wallet
|
|
38
|
+
|
|
39
|
+
# Default to 1 wei of the service token if no staking contract specified
|
|
40
|
+
bond_amount = Web3.to_wei(1, "wei")
|
|
41
|
+
|
|
42
|
+
if req.token_address and req.staking_contract:
|
|
43
|
+
# If a contract is specified, we MUST use its requirements
|
|
44
|
+
logger.info(f"Fetching requirements from {req.staking_contract}...")
|
|
45
|
+
staking_contract = StakingContract(req.staking_contract, req.chain)
|
|
46
|
+
reqs = staking_contract.get_requirements()
|
|
47
|
+
bond_amount = reqs["required_agent_bond"]
|
|
48
|
+
min_staking_deposit = reqs["min_staking_deposit"]
|
|
49
|
+
logger.info(f"Required bond amount from contract: {bond_amount} wei")
|
|
50
|
+
logger.info(f"Required min_staking_deposit: {min_staking_deposit} wei")
|
|
51
|
+
|
|
52
|
+
# Validate upfront: total OLAS needed = bond + min_staking_deposit
|
|
53
|
+
if req.stake_on_create:
|
|
54
|
+
total_olas_needed = bond_amount + min_staking_deposit
|
|
55
|
+
logger.info(
|
|
56
|
+
f"Total OLAS needed for create + stake: {total_olas_needed / 1e18:.2f} OLAS"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Check owner balance (master is default owner for new services)
|
|
60
|
+
staking_token = reqs.get("staking_token")
|
|
61
|
+
if staking_token:
|
|
62
|
+
erc20 = ERC20Contract(staking_token, req.chain)
|
|
63
|
+
owner_balance = erc20.balance_of_wei(wallet.master_account.address)
|
|
64
|
+
logger.info(f"Owner OLAS balance: {owner_balance / 1e18:.2f} OLAS")
|
|
65
|
+
|
|
66
|
+
if owner_balance < total_olas_needed:
|
|
67
|
+
raise HTTPException(
|
|
68
|
+
status_code=400,
|
|
69
|
+
detail=f"Insufficient OLAS balance. Need {total_olas_needed / 1e18:.2f} OLAS "
|
|
70
|
+
f"(bond: {bond_amount / 1e18:.2f} + deposit: {min_staking_deposit / 1e18:.2f}), "
|
|
71
|
+
f"but owner has {owner_balance / 1e18:.2f} OLAS",
|
|
72
|
+
)
|
|
73
|
+
return bond_amount
|
|
74
|
+
|
|
31
75
|
@router.post(
|
|
32
76
|
"/create",
|
|
33
77
|
summary="Create Service",
|
|
@@ -36,28 +80,14 @@ class CreateServiceRequest(BaseModel):
|
|
|
36
80
|
def create_service(req: CreateServiceRequest, auth: bool = Depends(verify_auth)):
|
|
37
81
|
"""Create a new Olas service using spin_up for seamless deployment."""
|
|
38
82
|
try:
|
|
39
|
-
from web3 import Web3
|
|
40
83
|
|
|
41
84
|
from iwa.plugins.olas.contracts.staking import StakingContract
|
|
42
85
|
from iwa.plugins.olas.service_manager import ServiceManager
|
|
43
86
|
|
|
44
87
|
manager = ServiceManager(wallet)
|
|
45
88
|
|
|
46
|
-
# Determine bond amount
|
|
47
|
-
bond_amount =
|
|
48
|
-
|
|
49
|
-
staking_contract = None
|
|
50
|
-
if req.token_address:
|
|
51
|
-
if req.staking_contract:
|
|
52
|
-
# If a contract is specified, we MUST use its requirements
|
|
53
|
-
logger.info(f"Fetching requirements from {req.staking_contract}...")
|
|
54
|
-
staking_contract = StakingContract(req.staking_contract, req.chain)
|
|
55
|
-
reqs = staking_contract.get_requirements()
|
|
56
|
-
bond_amount = reqs["required_agent_bond"]
|
|
57
|
-
logger.info(f"Required bond amount from contract: {bond_amount} wei")
|
|
58
|
-
else:
|
|
59
|
-
# Default to 1 wei of the service token if no staking contract specified
|
|
60
|
-
bond_amount = Web3.to_wei(1, "wei")
|
|
89
|
+
# Determine bond amount
|
|
90
|
+
bond_amount = _determine_bond_amount(req)
|
|
61
91
|
|
|
62
92
|
# Step 1: Create the service (PRE_REGISTRATION state)
|
|
63
93
|
logger.info(
|
|
@@ -87,11 +117,14 @@ def create_service(req: CreateServiceRequest, auth: bool = Depends(verify_auth))
|
|
|
87
117
|
|
|
88
118
|
# Step 2: Spin up the service (activate → register → deploy → optionally stake)
|
|
89
119
|
# Only pass staking_contract if user wants to stake on create
|
|
90
|
-
|
|
120
|
+
staking_obj = None
|
|
121
|
+
if req.stake_on_create and req.staking_contract:
|
|
122
|
+
# We need to instantiate the staking contract object for spin_up
|
|
123
|
+
staking_obj = StakingContract(req.staking_contract, req.chain)
|
|
91
124
|
|
|
92
125
|
success = manager.spin_up(
|
|
93
126
|
service_id=service_id,
|
|
94
|
-
staking_contract=
|
|
127
|
+
staking_contract=staking_obj,
|
|
95
128
|
bond_amount_wei=bond_amount,
|
|
96
129
|
)
|
|
97
130
|
|
|
@@ -110,7 +143,7 @@ def create_service(req: CreateServiceRequest, auth: bool = Depends(verify_auth))
|
|
|
110
143
|
"service_key": manager.service.key if manager.service else None,
|
|
111
144
|
"multisig": str(manager.service.multisig_address) if manager.service else None,
|
|
112
145
|
"final_state": final_state,
|
|
113
|
-
"staked": req.stake_on_create and
|
|
146
|
+
"staked": req.stake_on_create and staking_obj is not None,
|
|
114
147
|
}
|
|
115
148
|
|
|
116
149
|
except HTTPException:
|
iwa/web/routers/olas/staking.py
CHANGED
|
@@ -140,11 +140,17 @@ def _check_availability(name, address, interface):
|
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
def _fetch_all_contracts(contracts: dict, interface) -> list:
|
|
143
|
-
"""Fetch availability for all contracts using threads.
|
|
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
|
+
"""
|
|
144
150
|
from concurrent.futures import ThreadPoolExecutor
|
|
145
151
|
|
|
146
152
|
results = []
|
|
147
|
-
with ThreadPoolExecutor(max_workers=
|
|
153
|
+
with ThreadPoolExecutor(max_workers=2) as executor:
|
|
148
154
|
futures = [
|
|
149
155
|
executor.submit(_check_availability, name, addr, interface)
|
|
150
156
|
for name, addr in contracts.items()
|
|
@@ -17,10 +17,10 @@ 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
19
|
iwa/core/utils.py,sha256=5fc8Ffd3F47iFb8QbnZmKh_d2Fsh1ZytVG2HFnhySEQ,2950
|
|
20
|
-
iwa/core/wallet.py,sha256=
|
|
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=
|
|
23
|
+
iwa/core/chain/interface.py,sha256=GRfWvSPUKdFNrkFD-lR7qFJYbQJs-oE7G_tQMBn4jA0,21097
|
|
24
24
|
iwa/core/chain/manager.py,sha256=cFEzh6pK5OyVhjhpeMAqhc9RnRDQR1DjIGiGKp-FXBI,1159
|
|
25
25
|
iwa/core/chain/models.py,sha256=0OgBo08FZEQisOdd00YUMXSAV7BC0CcWpqJ2y-gs0cI,4863
|
|
26
26
|
iwa/core/chain/rate_limiter.py,sha256=gU7TmWdH9D_wbXKT1X7mIgoIUCWVuebgvRhxiyLGAmI,6613
|
|
@@ -36,7 +36,7 @@ iwa/core/services/account.py,sha256=01MoEvl6FJlMnMB4fGwsPtnGa4kgA-d5hJeKu_ACg7Y,
|
|
|
36
36
|
iwa/core/services/balance.py,sha256=mPE12CuOFfCaJXaQXWOcQM1O03ZF3ghpy_-oOjNk_GE,4104
|
|
37
37
|
iwa/core/services/plugin.py,sha256=GNNlbtELyHl7MNVChrypF76GYphxXduxDog4kx1MLi8,3277
|
|
38
38
|
iwa/core/services/safe.py,sha256=ytNJMndXrzTMHwhDZKYLIh4Q0UTWDBgQgTpof-UqIkA,14827
|
|
39
|
-
iwa/core/services/transaction.py,sha256=
|
|
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
|
|
@@ -65,7 +65,7 @@ iwa/plugins/olas/contracts/activity_checker.py,sha256=UDbCgFOyuEhHf1qoUwCUdLc8oK
|
|
|
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=
|
|
68
|
+
iwa/plugins/olas/contracts/service.py,sha256=BDQKeCTCnBNrwKD1a8rrlLytpKG3CAdjr-s0ec-dsFY,8243
|
|
69
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
|
|
@@ -73,6 +73,7 @@ iwa/plugins/olas/contracts/abis/mech_marketplace.json,sha256=KPnF-H_UATb3wdb_7o6
|
|
|
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,14 +81,14 @@ 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=
|
|
84
|
+
iwa/plugins/olas/service_manager/lifecycle.py,sha256=DIB6yrP0VPICu6558uQJuFp2sgrA66iVNTzZVUUowGw,47159
|
|
84
85
|
iwa/plugins/olas/service_manager/mech.py,sha256=72-tEap-aYd0gebcH6y_De1SNeL6OrXn7sWuv_Ok_-Y,12224
|
|
85
|
-
iwa/plugins/olas/service_manager/staking.py,sha256=
|
|
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=
|
|
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
|
|
@@ -95,10 +96,10 @@ iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=jAxr9bjFNAaxGf1btIrxdMaH
|
|
|
95
96
|
iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvqGt49H6fLSYGxn02c8o,5562
|
|
96
97
|
iwa/plugins/olas/tests/test_plugin.py,sha256=RVgU-Cq6t_3mOh90xFAGwlJOV7ZIgp0VNaK5ZAxisAQ,2565
|
|
97
98
|
iwa/plugins/olas/tests/test_plugin_full.py,sha256=xevLYmdU4zd5FyEEEn9gvzGimPztmt6vymybeZHXnq8,8507
|
|
98
|
-
iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=
|
|
99
|
-
iwa/plugins/olas/tests/test_service_manager.py,sha256=
|
|
100
|
-
iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=
|
|
101
|
-
iwa/plugins/olas/tests/test_service_manager_flows.py,sha256=
|
|
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
105
|
iwa/plugins/olas/tests/test_service_manager_validation.py,sha256=ajlfH5uc4mAHf8A7GLE5cW7X8utM2vUilM0JdGDdlVg,5382
|
|
@@ -140,8 +141,8 @@ iwa/web/routers/olas/__init__.py,sha256=Jo6Dm1e8fHafCD800fbxsxeFz3tvuEEKXEf5-9tj
|
|
|
140
141
|
iwa/web/routers/olas/admin.py,sha256=PMRdNelqYgQ1xbqh3floFV5xrVtBRQiwZPd8J9_ffxg,5785
|
|
141
142
|
iwa/web/routers/olas/funding.py,sha256=f8fADNtbZEBFl-vuVKfas6os38Vot6K5tJBTenZmCD0,4832
|
|
142
143
|
iwa/web/routers/olas/general.py,sha256=dPsBQppTGoQY1RztliUhseOHOZGeeCR10lhThD9kyXo,803
|
|
143
|
-
iwa/web/routers/olas/services.py,sha256=
|
|
144
|
-
iwa/web/routers/olas/staking.py,sha256=
|
|
144
|
+
iwa/web/routers/olas/services.py,sha256=IpjvkpJeCwREbdHt47gov-fvTl9bY4EBUmZZZEHi3iI,16310
|
|
145
|
+
iwa/web/routers/olas/staking.py,sha256=N1pMcPjhpfSPi7Sl7XIIAPoFxf0hptdvkUqkTtgqPcc,12424
|
|
145
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
|
|
@@ -149,7 +150,7 @@ iwa/web/tests/test_web_endpoints.py,sha256=C264MH-CTyDW4GLUrTXBgLJKUk4-89pFAScBd
|
|
|
149
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.
|
|
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,7 +159,7 @@ 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=
|
|
162
|
+
tests/test_chain.py,sha256=naDz3WNrB8J3hAcId8of8R4_jN0vEWMC28-70hQEU_s,17240
|
|
162
163
|
tests/test_chain_interface.py,sha256=Wu0q0sREtmYBp7YvWrBIrrSTtqeQj18oJp2VmMUEMec,8312
|
|
163
164
|
tests/test_chain_interface_coverage.py,sha256=fvrVvw8-DMwdsSFKQHUhpbfutrVRxnnTc-tjB7Bb-jo,3327
|
|
164
165
|
tests/test_cli.py,sha256=WW6EDeHLws5-BqFNOy11pH_D5lttuyspD5hrDCFpR0Q,3968
|
|
@@ -200,8 +201,8 @@ tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
|
|
|
200
201
|
tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
|
|
201
202
|
tools/create_and_stake_service.py,sha256=1xwy_bJQI1j9yIQ968Oc9Db_F6mk1659LuuZntTASDE,3742
|
|
202
203
|
tools/verify_drain.py,sha256=PkMjblyOOAuQge88FwfEzRtCYeEtJxXhPBmtQYCoQ-8,6743
|
|
203
|
-
iwa-0.0.
|
|
204
|
-
iwa-0.0.
|
|
205
|
-
iwa-0.0.
|
|
206
|
-
iwa-0.0.
|
|
207
|
-
iwa-0.0.
|
|
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
|
-
|
|
344
|
-
|
|
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
|
-
|
|
442
|
-
|
|
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
|
-
|
|
449
|
+
decimals = ci.get_token_decimals("0x1234567890123456789012345678901234567890")
|
|
445
450
|
|
|
446
|
-
|
|
447
|
-
|
|
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):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|