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
@@ -64,10 +64,10 @@ class ServiceRegistryContract(ContractInstance):
64
64
  """Get the token address for a service."""
65
65
  return self.call("token", service_id)
66
66
 
67
- def get_agent_params(self, service_id: int, agent_id: int) -> Dict:
68
- """Get agent params (slots, bond) for a service."""
69
- (slots, bond) = self.call("getAgentParams", service_id, agent_id)
70
- return {"slots": slots, "bond": bond}
67
+ def get_agent_params(self, service_id: int) -> list:
68
+ """Get agent params (slots, bond) for all agents in a service."""
69
+ num_ids, params = self.call("getAgentParams", service_id)
70
+ return [{"slots": p[0], "bond": p[1]} for p in params]
71
71
 
72
72
  def prepare_approve_tx(
73
73
  self,
@@ -213,3 +213,53 @@ class ServiceManagerContract(ContractInstance):
213
213
  tx_params={"from": from_address},
214
214
  )
215
215
  return tx
216
+
217
+
218
+ class ServiceRegistryTokenUtilityContract(ContractInstance):
219
+ """Class to interact with the service registry token utility contract.
220
+
221
+ This contract manages token-bonded services, tracking agent bonds and
222
+ security deposits for services that use ERC20 tokens (like OLAS) instead
223
+ of native currency.
224
+ """
225
+
226
+ name = "service_registry_token_utility"
227
+ abi_path = OLAS_ABI_PATH / "service_registry_token_utility.json"
228
+
229
+ def get_agent_bond(self, service_id: int, agent_id: int) -> int:
230
+ """Get the agent bond for a specific agent in a service.
231
+
232
+ Args:
233
+ service_id: The service ID.
234
+ agent_id: The agent ID within the service.
235
+
236
+ Returns:
237
+ The bond amount in wei.
238
+
239
+ """
240
+ return self.call("getAgentBond", service_id, agent_id)
241
+
242
+ def get_operator_balance(self, operator: str, service_id: int) -> int:
243
+ """Get the operator balance for a service.
244
+
245
+ Args:
246
+ operator: The operator address.
247
+ service_id: The service ID.
248
+
249
+ Returns:
250
+ The balance amount in wei.
251
+
252
+ """
253
+ return self.call("getOperatorBalance", operator, service_id)
254
+
255
+ def get_service_token_deposit(self, service_id: int) -> tuple:
256
+ """Get the token deposit info for a service.
257
+
258
+ Args:
259
+ service_id: The service ID.
260
+
261
+ Returns:
262
+ Tuple of (token_address, security_deposit).
263
+
264
+ """
265
+ return self.call("mapServiceIdTokenDeposit", service_id)
@@ -30,20 +30,19 @@ The staking contract checks that:
30
30
  4. Agent bond was deposited during service registration
31
31
  """
32
32
 
33
- import logging
34
33
  import math
35
34
  import time
36
35
  from datetime import datetime, timezone
37
36
  from enum import Enum
38
37
  from typing import Dict, List, Optional, Union
39
38
 
39
+ from loguru import logger
40
+
40
41
  from iwa.core.contracts.contract import ContractInstance
41
42
  from iwa.core.types import EthereumAddress
42
43
  from iwa.plugins.olas.contracts.activity_checker import ActivityCheckerContract
43
44
  from iwa.plugins.olas.contracts.base import OLAS_ABI_PATH
44
45
 
45
- logger = logging.getLogger(__name__)
46
-
47
46
 
48
47
  class StakingState(Enum):
49
48
  """Enum representing the staking state of a service."""
@@ -48,8 +48,12 @@ class OlasPlugin(Plugin):
48
48
  """Create a new Olas service"""
49
49
  wallet = Wallet()
50
50
  manager = ServiceManager(wallet)
51
- # Note: Manager logic currently depends on internal config state which might need setup
52
- manager.create(chain_name, owner, token, bond)
51
+ manager.create(
52
+ chain_name=chain_name,
53
+ service_owner_address_or_tag=owner,
54
+ token_address_or_tag=token,
55
+ bond_amount_wei=bond,
56
+ )
53
57
 
54
58
  def _get_safe_signers(self, safe_address: str, chain_name: str) -> tuple:
55
59
  """Query Safe signers on-chain.
@@ -65,13 +69,16 @@ class OlasPlugin(Plugin):
65
69
  from safe_eth.eth import EthereumClient
66
70
  from safe_eth.safe import Safe
67
71
 
68
- from iwa.core.secrets import secrets
72
+ from iwa.core.chain import ChainInterfaces
69
73
 
70
- rpc_secret = getattr(secrets, f"{chain_name}_rpc", None)
71
- if not rpc_secret:
72
- return None, None # Can't verify, skip
74
+ try:
75
+ chain_interface = ChainInterfaces().get(chain_name)
76
+ if not chain_interface.chain.rpcs:
77
+ return None, None
78
+ except ValueError:
79
+ return None, None # Chain not supported/configured
73
80
 
74
- ethereum_client = EthereumClient(rpc_secret.get_secret_value())
81
+ ethereum_client = EthereumClient(chain_interface.chain.rpc)
75
82
  safe = Safe(safe_address, ethereum_client)
76
83
  owners = safe.retrieve_owners()
77
84
  return owners, True