iwa 0.0.31__py3-none-any.whl → 0.0.33__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.
@@ -214,6 +214,24 @@ class TransactionService:
214
214
  self.account_service = account_service
215
215
  self.safe_service = safe_service
216
216
 
217
+ def _resolve_label(self, address: str, chain_name: str = "gnosis") -> str:
218
+ """Resolve address to human-readable label."""
219
+ if not address:
220
+ return "None"
221
+ # Try account/safe tags
222
+ tag = self.account_service.get_tag_by_address(address)
223
+ if tag:
224
+ return tag
225
+ # Try token/contract names
226
+ try:
227
+ chain_interface = ChainInterfaces().get(chain_name)
228
+ name = chain_interface.chain.get_token_name(address)
229
+ if name:
230
+ return name
231
+ except Exception:
232
+ pass
233
+ return address
234
+
217
235
  def sign_and_send( # noqa: C901
218
236
  self,
219
237
  transaction: dict,
@@ -388,7 +406,7 @@ class TransactionService:
388
406
  tags: List[str] = None
389
407
  ) -> Tuple[bool, Dict]:
390
408
  """Execute transaction via SafeService."""
391
- logger.info(f"Routing transaction via Safe {signer_account.address}...")
409
+ logger.info(f"Routing transaction via Safe {self._resolve_label(signer_account.address, chain_name)}...")
392
410
 
393
411
  try:
394
412
  # Extract basic params
@@ -14,9 +14,28 @@ if TYPE_CHECKING:
14
14
  from iwa.core.services.transfer import TransferService
15
15
 
16
16
 
17
+
17
18
  class ERC20TransferMixin:
18
19
  """Mixin for ERC20 token transfers and approvals."""
19
20
 
21
+ def _resolve_label(self, address: str, chain_name: str = "gnosis") -> str:
22
+ """Resolve address to human-readable label."""
23
+ if not address:
24
+ return "None"
25
+ try:
26
+ # Try account/safe tags
27
+ tag = self.account_service.get_tag_by_address(address)
28
+ if tag:
29
+ return tag
30
+ # Try token/contract names
31
+ chain_interface = ChainInterfaces().get(chain_name)
32
+ name = chain_interface.chain.get_token_name(address)
33
+ if name:
34
+ return name
35
+ except Exception:
36
+ pass
37
+ return address
38
+
20
39
  def _send_erc20_via_safe(
21
40
  self: "TransferService",
22
41
  from_account: StoredSafeAccount,
@@ -181,9 +200,11 @@ class ERC20TransferMixin:
181
200
  is_safe = getattr(owner_account, "threshold", None) is not None
182
201
  amount_eth = float(chain_interface.web3.from_wei(amount_wei, "ether"))
183
202
 
184
- logger.info(
185
- f"Approving {spender_address} to spend {amount_eth:.4f} {token_address_or_name} from {owner_address_or_tag}"
186
- )
203
+ if is_safe:
204
+ logger.info(
205
+ f"Approving {self._resolve_label(spender_address, chain_name)} to spend {amount_eth:.4f} "
206
+ f"{self._resolve_label(token_address, chain_name)} from {self._resolve_label(owner_account.address, chain_name)}"
207
+ )
187
208
 
188
209
  if is_safe:
189
210
  tx_limit = self.safe_service.execute_safe_transaction(
@@ -889,9 +889,11 @@ class OlasServiceImporter:
889
889
  """Generate a unique tag for an imported key.
890
890
 
891
891
  Tags follow the pattern: {service_name}_{role}[_eoa]
892
+
892
893
  Examples:
893
894
  - trader_alpha_agent
894
895
  - trader_alpha_owner_eoa (EOA keys for owner role)
896
+
895
897
  """
896
898
  # Use service name as prefix, or 'imported' as fallback
897
899
  prefix = service_name or "imported"
@@ -99,6 +99,24 @@ class LifecycleManagerMixin:
99
99
  manager.spin_up(bond_amount_wei=5000e18, staking_contract=staking)
100
100
  """
101
101
 
102
+ def _get_label(self, address: str) -> str:
103
+ """Resolve address to a human-readable label."""
104
+ if not address:
105
+ return "None"
106
+
107
+ # Try account service tags first (wallets, safes)
108
+ tag = self.wallet.account_service.get_tag_by_address(address)
109
+ if tag:
110
+ return tag
111
+
112
+ # Try token names
113
+ chain_interface = ChainInterfaces().get(self.chain_name)
114
+ token_name = chain_interface.chain.get_token_name(address)
115
+ if token_name:
116
+ return token_name
117
+
118
+ return address
119
+
102
120
  def create(
103
121
  self,
104
122
  chain_name: str = "gnosis",
@@ -141,8 +159,8 @@ class LifecycleManagerMixin:
141
159
  agent_params = self._prepare_agent_params(agent_id_values, bond_amount_wei)
142
160
 
143
161
  logger.info(
144
- f"Preparing create tx: owner={service_owner_account.address}, "
145
- f"token={token_address}, agent_ids={agent_id_values}, agent_params={agent_params}"
162
+ f"Preparing create tx: owner={self._get_label(service_owner_account.address)}, "
163
+ f"token={self._get_label(token_address)}, agent_ids={agent_id_values}, agent_params={agent_params}"
146
164
  )
147
165
 
148
166
  receipt = self._send_create_transaction(
@@ -339,7 +357,7 @@ class LifecycleManagerMixin:
339
357
  return False
340
358
 
341
359
  token_address = self._get_service_token(service_id)
342
- logger.debug(f"[ACTIVATE] Token address: {token_address}")
360
+ logger.debug(f"[ACTIVATE] Token address: {self._get_label(token_address)}")
343
361
 
344
362
  service_info = self.registry.get_service(service_id)
345
363
  security_deposit = service_info["security_deposit"]
@@ -518,7 +536,7 @@ class LifecycleManagerMixin:
518
536
  # The OLAS token approval was done in _ensure_token_approval_for_activation
519
537
  activation_value = security_deposit if is_native else 1
520
538
  logger.info(
521
- f"[ACTIVATE] Token={token_address}, is_native={is_native}, "
539
+ f"[ACTIVATE] Token={self._get_label(token_address)}, is_native={is_native}, "
522
540
  f"activation_value={activation_value} wei"
523
541
  )
524
542
 
@@ -526,7 +544,7 @@ class LifecycleManagerMixin:
526
544
  owner_address = self.service.service_owner_address or self.wallet.master_account.address
527
545
 
528
546
  logger.debug(
529
- f"[ACTIVATE] Preparing tx from {owner_address}: service_id={service_id}, value={activation_value}"
547
+ f"[ACTIVATE] Preparing tx from {self._get_label(owner_address)}: service_id={service_id}, value={activation_value}"
530
548
  )
531
549
  activate_tx = self.manager.prepare_activate_registration_tx(
532
550
  from_address=owner_address,
@@ -583,7 +601,7 @@ class LifecycleManagerMixin:
583
601
  if not agent_account_address:
584
602
  logger.error("[REGISTER] Failed to get/create agent account")
585
603
  return False
586
- logger.info(f"[REGISTER] Agent address: {agent_account_address}")
604
+ logger.info(f"[REGISTER] Agent address: {self._get_label(agent_account_address)}")
587
605
 
588
606
  if not self._ensure_agent_token_approval(agent_account_address, bond_amount_wei):
589
607
  logger.error("[REGISTER] Token approval failed")
@@ -721,7 +739,7 @@ class LifecycleManagerMixin:
721
739
  total_value = 1 * len(self.service.agent_ids)
722
740
 
723
741
  logger.info(
724
- f"[REGISTER] Token={token_address}, is_native={is_native}, "
742
+ f"[REGISTER] Token={self._get_label(token_address)}, is_native={is_native}, "
725
743
  f"total_value={total_value} wei"
726
744
  )
727
745
 
@@ -729,7 +747,7 @@ class LifecycleManagerMixin:
729
747
  owner_address = self.service.service_owner_address or self.wallet.master_account.address
730
748
 
731
749
  logger.debug(
732
- f"[REGISTER] Preparing tx from {owner_address}: agent={agent_account_address}, "
750
+ f"[REGISTER] Preparing tx from {self._get_label(owner_address)}: agent={self._get_label(agent_account_address)}, "
733
751
  f"agent_ids={self.service.agent_ids}, value={total_value}"
734
752
  )
735
753
 
@@ -782,7 +800,7 @@ class LifecycleManagerMixin:
782
800
  )
783
801
  return False
784
802
 
785
- logger.debug(f"[DEPLOY] Preparing deploy tx for owner {self.service.service_owner_address}")
803
+ logger.debug(f"[DEPLOY] Preparing deploy tx for owner {self._get_label(self.service.service_owner_address)}")
786
804
  deploy_tx = self.manager.prepare_deploy_tx(
787
805
  from_address=self.service.service_owner_address,
788
806
  service_id=self.service.service_id,
@@ -74,6 +74,31 @@ class StakingManagerMixin:
74
74
  - Service token must match staking contract's required token
75
75
  """
76
76
 
77
+ def _get_label(self, address: str) -> str:
78
+ """Resolve address to a human-readable label."""
79
+ if not address:
80
+ return "None"
81
+
82
+ # Try account service tags first (wallets, safes)
83
+ try:
84
+ tag = self.wallet.account_service.get_tag_by_address(address)
85
+ if tag:
86
+ return tag
87
+ except AttributeError:
88
+ pass
89
+
90
+ # Try token/contract names
91
+ try:
92
+ from iwa.core.chain import ChainInterfaces
93
+ chain_interface = ChainInterfaces().get(self.chain_name)
94
+ token_name = chain_interface.chain.get_token_name(address)
95
+ if token_name:
96
+ return token_name
97
+ except Exception:
98
+ pass
99
+
100
+ return address
101
+
77
102
  def get_staking_status(self) -> Optional[StakingStatus]:
78
103
  """Get comprehensive staking status for the active service.
79
104
 
@@ -246,7 +271,7 @@ class StakingManagerMixin:
246
271
  """
247
272
  logger.info("=" * 50)
248
273
  logger.info(f"[STAKE] Starting staking for service {self.service.service_id}")
249
- logger.info(f"[STAKE] Contract: {staking_contract.address}")
274
+ logger.info(f"[STAKE] Contract: {self._get_label(staking_contract.address)}")
250
275
  logger.info("=" * 50)
251
276
 
252
277
  # 1. Validation
@@ -412,7 +437,7 @@ class StakingManagerMixin:
412
437
  owner_address = self.service.service_owner_address or self.wallet.master_account.address
413
438
 
414
439
  # Approve service NFT - this is an ERC-721 approval, not ERC-20
415
- logger.debug(f"[STAKE] Approving service NFT for staking contract from {owner_address}...")
440
+ logger.debug(f"[STAKE] Approving service NFT for staking contract from {self._get_label(owner_address)}...")
416
441
  approve_tx = self.registry.prepare_approve_tx(
417
442
  from_address=owner_address,
418
443
  spender=staking_contract.address,
@@ -458,7 +483,7 @@ class StakingManagerMixin:
458
483
  # Use service owner which holds the NFT (not necessarily master)
459
484
  owner_address = self.service.service_owner_address or self.wallet.master_account.address
460
485
 
461
- logger.debug(f"[STAKE] Preparing stake transaction from {owner_address}...")
486
+ logger.debug(f"[STAKE] Preparing stake transaction from {self._get_label(owner_address)}...")
462
487
  stake_tx = staking_contract.prepare_stake_tx(
463
488
  from_address=owner_address,
464
489
  service_id=self.service.service_id,
@@ -512,7 +537,7 @@ class StakingManagerMixin:
512
537
  return False
513
538
 
514
539
  logger.info(
515
- f"Preparing to unstake service {self.service.service_id} from {staking_contract.address}"
540
+ f"Preparing to unstake service {self.service.service_id} from {self._get_label(staking_contract.address)}"
516
541
  )
517
542
 
518
543
  # Check that the service is staked
@@ -553,7 +578,7 @@ class StakingManagerMixin:
553
578
  # Unstake the service
554
579
  try:
555
580
  logger.info(
556
- f"Preparing unstake transaction for service {self.service.service_id} from {owner_address}"
581
+ f"Preparing unstake transaction for service {self.service.service_id} from {self._get_label(owner_address)}"
557
582
  )
558
583
  unstake_tx = staking_contract.prepare_unstake_tx(
559
584
  from_address=owner_address,
@@ -69,6 +69,10 @@ def mock_wallet():
69
69
  new_acc = MagicMock()
70
70
  new_acc.address = "0x0987654321098765432109876543210987654321"
71
71
  wallet.key_storage.create_account.return_value = new_acc
72
+ wallet.key_storage.create_account.return_value = new_acc
73
+ # Mock account_service
74
+ wallet.account_service = MagicMock()
75
+ wallet.account_service.get_tag_by_address.return_value = "mock_tag"
72
76
  # Mock transfer_service
73
77
  wallet.transfer_service = MagicMock()
74
78
  wallet.transfer_service.approve_erc20.return_value = True
iwa/tools/reset_env.py CHANGED
@@ -17,11 +17,18 @@ from iwa.core.models import Config
17
17
 
18
18
 
19
19
  def _reset_tenderly(profile: int) -> None:
20
- """Reset Tenderly networks using just command."""
21
- cmd = ["just", "reset-tenderly", str(profile)]
20
+ """Reset Tenderly networks using reset_tenderly.py script."""
21
+ cmd = ["uv", "run", "src/iwa/tools/reset_tenderly.py", "--profile", str(profile)]
22
22
  print(f"Running: {' '.join(cmd)}")
23
23
  try:
24
- subprocess.check_call(cmd) # nosec B603
24
+ # Ensure PYTHONPATH is set to include src
25
+ env = {"PYTHONPATH": "src"}
26
+ # Merge with current env to keep PATH etc.
27
+ import os
28
+ full_env = os.environ.copy()
29
+ full_env.update(env)
30
+
31
+ subprocess.check_call(cmd, env=full_env) # nosec B603
25
32
  except subprocess.CalledProcessError as e:
26
33
  print(f"Error running reset-tenderly: {e}")
27
34
  sys.exit(1)
@@ -97,12 +104,26 @@ def _clean_wallet_accounts() -> None:
97
104
 
98
105
  def main():
99
106
  """Reset the environment by clearing networks, services, and accounts."""
107
+ import argparse
108
+
109
+ parser = argparse.ArgumentParser(description="Reset environment.")
110
+ parser.add_argument(
111
+ "--keep-data",
112
+ action="store_true",
113
+ help="Reset only Tenderly, keeping config.yaml and wallet.json intact."
114
+ )
115
+ args = parser.parse_args()
116
+
100
117
  profile = Config().core.tenderly_profile
101
118
  print(f"Detected Tenderly profile: {profile}")
102
119
 
103
120
  _reset_tenderly(profile)
104
- _clean_olas_services()
105
- _clean_wallet_accounts()
121
+
122
+ if args.keep_data:
123
+ print("Skipping Olas services and wallet cleanup (--keep-data used).")
124
+ else:
125
+ _clean_olas_services()
126
+ _clean_wallet_accounts()
106
127
 
107
128
  print("Environment reset complete.")
108
129
 
@@ -41,7 +41,8 @@ def _determine_bond_amount(req: CreateServiceRequest) -> int:
41
41
 
42
42
  if req.token_address and req.staking_contract:
43
43
  # If a contract is specified, we MUST use its requirements
44
- logger.info(f"Fetching requirements from {req.staking_contract}...")
44
+ staking_name = wallet.account_service.get_tag_by_address(req.staking_contract) or req.staking_contract
45
+ logger.info(f"Fetching requirements from {staking_name}...")
45
46
  staking_contract = StakingContract(req.staking_contract, req.chain)
46
47
  reqs = staking_contract.get_requirements()
47
48
  bond_amount = reqs["required_agent_bond"]
@@ -195,7 +196,8 @@ def deploy_service(
195
196
  if staking_contract:
196
197
  try:
197
198
  staking_obj = StakingContract(staking_contract, service.chain_name)
198
- logger.info(f"Will stake in {staking_contract} after deployment")
199
+ staking_name = wallet.account_service.get_tag_by_address(staking_contract) or staking_contract
200
+ logger.info(f"Will stake in {staking_name} after deployment")
199
201
  except Exception as e:
200
202
  logger.warning(f"Could not set up staking contract: {e}")
201
203
 
@@ -228,6 +230,74 @@ def deploy_service(
228
230
  raise HTTPException(status_code=400, detail=str(e)) from None
229
231
 
230
232
 
233
+
234
+ def _resolve_service_accounts(service) -> dict:
235
+ """Resolve basic accounts info including owner_signer if applicable."""
236
+ accounts = {}
237
+ for role, addr in [
238
+ ("agent", service.agent_address),
239
+ ("safe", str(service.multisig_address) if service.multisig_address else None),
240
+ ("owner", service.service_owner_address),
241
+ ]:
242
+ if addr:
243
+ stored = wallet.key_storage.find_stored_account(addr)
244
+ # If this role is 'owner' and it's a Safe, add owner_signer role
245
+ if role == "owner" and stored and hasattr(stored, "signers") and stored.signers:
246
+ signer_addr = stored.signers[0]
247
+ signer_stored = wallet.key_storage.find_stored_account(signer_addr)
248
+ accounts["owner_signer"] = {
249
+ "address": signer_addr,
250
+ "tag": signer_stored.tag if signer_stored else None,
251
+ "native": None,
252
+ "olas": None,
253
+ }
254
+
255
+ accounts[role] = {
256
+ "address": addr,
257
+ "tag": stored.tag if stored else None,
258
+ "native": None,
259
+ "olas": None,
260
+ }
261
+ return accounts
262
+
263
+
264
+ def _resolve_service_balances(service, chain: str) -> dict:
265
+ """Resolve detailed balances including owner_signer."""
266
+ balances = {}
267
+ for role, addr in [
268
+ ("agent", service.agent_address),
269
+ ("safe", str(service.multisig_address) if service.multisig_address else None),
270
+ ("owner", service.service_owner_address),
271
+ ]:
272
+ if addr:
273
+ native_bal = wallet.get_native_balance_eth(addr, chain)
274
+ olas_bal = wallet.balance_service.get_erc20_balance_wei(addr, "OLAS", chain)
275
+ olas_bal_eth = float(olas_bal) / 1e18 if olas_bal else 0
276
+ stored = wallet.key_storage.find_stored_account(addr)
277
+
278
+ # If this role is 'owner' and it's a Safe, resolve owner_signer
279
+ if role == "owner" and stored and hasattr(stored, "signers") and stored.signers:
280
+ signer_addr = stored.signers[0]
281
+ s_native = wallet.get_native_balance_eth(signer_addr, chain)
282
+ s_olas_wei = wallet.balance_service.get_erc20_balance_wei(signer_addr, "OLAS", chain)
283
+ s_olas = float(s_olas_wei) / 1e18 if s_olas_wei else 0
284
+ s_stored = wallet.key_storage.find_stored_account(signer_addr)
285
+ balances["owner_signer"] = {
286
+ "address": signer_addr,
287
+ "tag": s_stored.tag if s_stored else None,
288
+ "native": f"{s_native:.2f}" if s_native else "0.00",
289
+ "olas": f"{s_olas:.2f}",
290
+ }
291
+
292
+ balances[role] = {
293
+ "address": addr,
294
+ "tag": stored.tag if stored else None,
295
+ "native": f"{native_bal:.2f}" if native_bal else "0.00",
296
+ "olas": f"{olas_bal_eth:.2f}",
297
+ }
298
+ return balances
299
+
300
+
231
301
  @router.get(
232
302
  "/services/basic",
233
303
  summary="Get Basic Services",
@@ -262,20 +332,7 @@ def get_olas_services_basic(chain: str = "gnosis", auth: bool = Depends(verify_a
262
332
  logger.warning(f"Could not get state for {service_key}: {e}")
263
333
 
264
334
  # Get tags from wallet storage (fast, local lookup)
265
- accounts = {}
266
- for role, addr in [
267
- ("agent", service.agent_address),
268
- ("safe", str(service.multisig_address) if service.multisig_address else None),
269
- ("owner", service.service_owner_address),
270
- ]:
271
- if addr:
272
- stored = wallet.key_storage.find_stored_account(addr)
273
- accounts[role] = {
274
- "address": addr,
275
- "tag": stored.tag if stored else None,
276
- "native": None, # Will be filled by details endpoint
277
- "olas": None,
278
- }
335
+ accounts = _resolve_service_accounts(service)
279
336
 
280
337
  result.append(
281
338
  {
@@ -327,23 +384,7 @@ def get_olas_service_details(service_key: str, auth: bool = Depends(verify_auth)
327
384
  service_state = manager.get_service_state()
328
385
 
329
386
  # Get balances
330
- balances = {}
331
- for role, addr in [
332
- ("agent", service.agent_address),
333
- ("safe", str(service.multisig_address) if service.multisig_address else None),
334
- ("owner", service.service_owner_address),
335
- ]:
336
- if addr:
337
- native_bal = wallet.get_native_balance_eth(addr, chain)
338
- olas_bal = wallet.balance_service.get_erc20_balance_wei(addr, "OLAS", chain)
339
- olas_bal_eth = float(olas_bal) / 1e18 if olas_bal else 0
340
- stored = wallet.key_storage.find_stored_account(addr)
341
- balances[role] = {
342
- "address": addr,
343
- "tag": stored.tag if stored else None,
344
- "native": f"{native_bal:.2f}" if native_bal else "0.00",
345
- "olas": f"{olas_bal_eth:.2f}",
346
- }
387
+ balances = _resolve_service_balances(service, chain)
347
388
 
348
389
  staking = None
349
390
  if staking_status:
iwa/web/static/app.js CHANGED
@@ -1966,25 +1966,30 @@ document.addEventListener("DOMContentLoaded", () => {
1966
1966
  }
1967
1967
 
1968
1968
  // Build accounts table
1969
- const roles = ["agent", "safe", "owner"];
1969
+ const roles = ["agent", "safe", "owner", "owner_signer"];
1970
1970
  const accountsHtml = roles
1971
1971
  .map((role) => {
1972
1972
  const acc = service.accounts[role];
1973
1973
  if (!acc || !acc.address) {
1974
1974
  if (role === "owner") return "";
1975
+ // For Owner Signer (EOA owner case) or other missing roles
1976
+ const label =
1977
+ role === "owner_signer"
1978
+ ? "Owner Signer"
1979
+ : role.charAt(0).toUpperCase() + role.slice(1);
1980
+ const addrText = role === "owner_signer" ? "-" : "Not deployed";
1975
1981
  return `
1976
1982
  <tr>
1977
- <td>${escapeHtml(role.charAt(0).toUpperCase() + role.slice(1))}</td>
1978
- <td class="address-cell text-muted">Not deployed</td>
1983
+ <td>${escapeHtml(label)}</td>
1984
+ <td class="address-cell text-muted">${escapeHtml(addrText)}</td>
1979
1985
  <td class="val">-</td>
1980
1986
  <td class="val">-</td>
1981
1987
  </tr>
1982
1988
  `;
1983
1989
  }
1984
1990
 
1985
- // Requirement: addresses for 'agent' and 'safe', but only 'tag' for 'owner'
1986
- const displayText =
1987
- role === "owner" && acc.tag ? acc.tag : shortenAddr(acc.address);
1991
+ // Requirement: Prefer TAG if available, otherwise shorten address
1992
+ const displayText = acc.tag ? acc.tag : shortenAddr(acc.address);
1988
1993
  const explorerUrl = getExplorerUrl(acc.address, service.chain);
1989
1994
 
1990
1995
  // Show spinner if loading, otherwise show balance
@@ -1997,9 +2002,13 @@ document.addEventListener("DOMContentLoaded", () => {
1997
2002
  ? '<span class="cell-spinner"></span>'
1998
2003
  : escapeHtml(formatBalance(acc.olas));
1999
2004
 
2005
+ const label =
2006
+ role === "owner_signer"
2007
+ ? "Owner Signer"
2008
+ : role.charAt(0).toUpperCase() + role.slice(1);
2000
2009
  return `
2001
2010
  <tr>
2002
- <td>${escapeHtml(role.charAt(0).toUpperCase() + role.slice(1))}</td>
2011
+ <td>${escapeHtml(label)}</td>
2003
2012
  <td class="address-cell">
2004
2013
  <a href="${explorerUrl}" target="_blank" class="explorer-link" title="${escapeHtml(acc.address)}">
2005
2014
  ${escapeHtml(displayText)}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwa
3
- Version: 0.0.31
3
+ Version: 0.0.33
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
@@ -40,10 +40,10 @@ iwa/core/services/account.py,sha256=01MoEvl6FJlMnMB4fGwsPtnGa4kgA-d5hJeKu_ACg7Y,
40
40
  iwa/core/services/balance.py,sha256=mPE12CuOFfCaJXaQXWOcQM1O03ZF3ghpy_-oOjNk_GE,4104
41
41
  iwa/core/services/plugin.py,sha256=GNNlbtELyHl7MNVChrypF76GYphxXduxDog4kx1MLi8,3277
42
42
  iwa/core/services/safe.py,sha256=ZmgVwbQhYlH5r3qhlY5uP8nCPtkkvV3sNnYG7_UCWUQ,14831
43
- iwa/core/services/transaction.py,sha256=FP-Qw7v0LrWTkgDPWeuoB48D7Gl9TrKVQt_trGNolRc,18462
43
+ iwa/core/services/transaction.py,sha256=Z5H5dXEXEMYT6YJWt5q04d_eciv8bKUuHQfWKZRYz1U,19106
44
44
  iwa/core/services/transfer/__init__.py,sha256=ZJfshFxJRsp8rkOqfVvd1cqEzIJ9tqBJh8pc0l90GLk,5576
45
45
  iwa/core/services/transfer/base.py,sha256=sohz-Ss2i-pGYGl4x9bD93cnYKcSvsXaXyvyRawvgQs,9043
46
- iwa/core/services/transfer/erc20.py,sha256=958ctXPWxq_KSQNoaG7RqWbC8SRb9NB3MzhtC2dp_NU,8960
46
+ iwa/core/services/transfer/erc20.py,sha256=vs7OQR36C7JNScZ_UF2Fc9webQLLgAQjaMbMeqdB3do,9736
47
47
  iwa/core/services/transfer/multisend.py,sha256=MuOTjzUQoYg1eSixXKhJGBmB1c0ymLelvk4puHm_VGE,15194
48
48
  iwa/core/services/transfer/native.py,sha256=2CiUOP1gHEXAtLG0-8FaykV3u3jclq5y71gXQNEoc3w,10433
49
49
  iwa/core/services/transfer/swap.py,sha256=exOJdzwkZaGbrFWfmQT_2JMcZUxnkiehXca8TH-vlF0,12269
@@ -62,7 +62,7 @@ iwa/plugins/gnosis/tests/test_safe.py,sha256=hQHVHBWQhGnuvzvx4U9fOWEwASJWwql42q6
62
62
  iwa/plugins/olas/__init__.py,sha256=_NhBczzM61fhGYwGhnWfEeL8Jywyy_730GASe2BxzeQ,106
63
63
  iwa/plugins/olas/constants.py,sha256=iTFoO2QW3KbhL5k5sKsJxxyDytl9wVIb_9hAih55KrE,7728
64
64
  iwa/plugins/olas/events.py,sha256=SWD3wYdQ-l6dLUJSkfh_WsLmedH4Vsw_EvYXg7QC3yc,5970
65
- iwa/plugins/olas/importer.py,sha256=CLWalbnXRnOwuCBVvUFpOkr1cGdkunrElfWNUl6NQMs,42040
65
+ iwa/plugins/olas/importer.py,sha256=ZnMi5noNUZMJzQ-aEmtPZz-eOK3cvboIJPL625F3mHQ,42042
66
66
  iwa/plugins/olas/mech_reference.py,sha256=CaSCpQnQL4F7wOG6Ox6Zdoy-uNEQ78YBwVLILQZKL8Q,5782
67
67
  iwa/plugins/olas/models.py,sha256=36N2Wuia7DVfpekJJ2pXPeS0lqhe5ED-Hjdox9YQG2c,5230
68
68
  iwa/plugins/olas/plugin.py,sha256=zOPWyoVkSVh6guJ3TZj5enJFuiIbP3fRM8FkziPB-c0,15606
@@ -88,9 +88,9 @@ iwa/plugins/olas/scripts/test_simple_lifecycle.py,sha256=8T50tOZx3afeECSfCNAb0rA
88
88
  iwa/plugins/olas/service_manager/__init__.py,sha256=GXiThMEY3nPgHUl1i-DLrF4h96z9jPxxI8Jepo2E1PM,1926
89
89
  iwa/plugins/olas/service_manager/base.py,sha256=EBPg0ymqgtAb7ZvVSfTt31QYgv_6gp4UAc6je00NLAg,5009
90
90
  iwa/plugins/olas/service_manager/drain.py,sha256=1Ku7axThwLtKxaNTkwhP4j1yjIXbFXAqNFDrCSmgfto,12569
91
- iwa/plugins/olas/service_manager/lifecycle.py,sha256=-YE2mqgF8twO_Q4iYhnFBFXN4W0KJ1qJzNXJRXJJdUo,49151
91
+ iwa/plugins/olas/service_manager/lifecycle.py,sha256=wvg49bv9_zFH1aR26TqM4VYzH8Ff7J8MJt98-zvkV_Q,49880
92
92
  iwa/plugins/olas/service_manager/mech.py,sha256=NVzVbEmyOe3wK92VEzCCOSuy3HDkEP1MSoVt7Av8Psk,27949
93
- iwa/plugins/olas/service_manager/staking.py,sha256=4WS1m1E1ddX5EbQuvNnNswZjT20nc7I9IKzjrBuUCFw,28701
93
+ iwa/plugins/olas/service_manager/staking.py,sha256=U_Akma_8PDeymHDEH5lNc64AQZ2xN8uljYo0ER7-wYQ,29554
94
94
  iwa/plugins/olas/tests/conftest.py,sha256=4vM7EI00SrTGyeP0hNzsGSQHEj2-iznVgzlNh2_OGfo,739
95
95
  iwa/plugins/olas/tests/test_importer.py,sha256=i9LKov7kNRECB3hmRnhKBwcfx3uxtjWe4BB77bOOpeo,4282
96
96
  iwa/plugins/olas/tests/test_importer_error_handling.py,sha256=yHpdxfN20gnZ1cHPJqk9xHC_26jyVN8kiziY-sl4FuA,11696
@@ -104,7 +104,7 @@ iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvq
104
104
  iwa/plugins/olas/tests/test_plugin.py,sha256=RVgU-Cq6t_3mOh90xFAGwlJOV7ZIgp0VNaK5ZAxisAQ,2565
105
105
  iwa/plugins/olas/tests/test_plugin_full.py,sha256=55EBa07JhJLVG3IMi6QKlR_ivWLYCdLQTySP66qbEXo,8584
106
106
  iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=sOCtpz8T9s55AZe9AoqP1h3XrXw5NDSjDqwLgYThvU4,5559
107
- iwa/plugins/olas/tests/test_service_manager.py,sha256=rS2m0A26apc-o4HsfP5oXmVcmZSR5e874bjhQKZRaSg,40650
107
+ iwa/plugins/olas/tests/test_service_manager.py,sha256=g9PREmYEHu2iRx9VzQhNJbxQU000dpXg57KN3ApMCTQ,40851
108
108
  iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=udlAsQj_t1F5TwVQuWhroF6jDJ4RmGEXaxPh87tMsuA,8538
109
109
  iwa/plugins/olas/tests/test_service_manager_flows.py,sha256=QvRFpJIapZXbagxPApr-995i64aJDapxSFyae8tNSHU,20722
110
110
  iwa/plugins/olas/tests/test_service_manager_mech.py,sha256=qG6qu5IPRNypXUsblU2OEkuiuwDJ0TH8RXZbibmTFcQ,4937
@@ -119,7 +119,7 @@ iwa/tools/__init__.py,sha256=jQyuwDQGRigSe7S9JMb4yK3CXPgZFJNffzt6N2v9PU0,21
119
119
  iwa/tools/check_profile.py,sha256=0LAv9wx4wMM610mX88-6tIoDi2I5LDzh0W9nkprt42s,2177
120
120
  iwa/tools/list_contracts.py,sha256=2w-LYB2RVS-eGil2kLiBIEm3tYYhYzT4lAuGO6VtLJU,4861
121
121
  iwa/tools/release.py,sha256=-Z9GG6Y-K6KG32K0VUf_MruiUdJxG6W7ToOMzhyCH7Y,3963
122
- iwa/tools/reset_env.py,sha256=FKN0wuh9Xq00c94B2kEFehHPKcWldxYqgU45yJwg5Cg,3140
122
+ iwa/tools/reset_env.py,sha256=lHWMUatl4n6KNCluX-egA9uSt0xSH9m48gt4Lz8GW28,3831
123
123
  iwa/tools/reset_tenderly.py,sha256=usKfOLrQvdCzEncueg-Sz3spqX80vHPQmbh2tIygo8o,11295
124
124
  iwa/tools/restore_backup.py,sha256=_LJbmKv9SlekLUQFdjI3aHCvAc6uePobJe3bQEFyatk,2455
125
125
  iwa/tools/test_chainlist.py,sha256=9J06sTsKgnEcN7WSn-YgJkCHhfbGDdVS-KNMDBhYllA,1143
@@ -149,16 +149,16 @@ iwa/web/routers/olas/__init__.py,sha256=Jo6Dm1e8fHafCD800fbxsxeFz3tvuEEKXEf5-9tj
149
149
  iwa/web/routers/olas/admin.py,sha256=PMRdNelqYgQ1xbqh3floFV5xrVtBRQiwZPd8J9_ffxg,5785
150
150
  iwa/web/routers/olas/funding.py,sha256=f8fADNtbZEBFl-vuVKfas6os38Vot6K5tJBTenZmCD0,4832
151
151
  iwa/web/routers/olas/general.py,sha256=dPsBQppTGoQY1RztliUhseOHOZGeeCR10lhThD9kyXo,803
152
- iwa/web/routers/olas/services.py,sha256=IpjvkpJeCwREbdHt47gov-fvTl9bY4EBUmZZZEHi3iI,16310
152
+ iwa/web/routers/olas/services.py,sha256=mDQh_Hp118Ek8_WIfhmZA_7HC2slw_aKRUjY6PPx91A,18099
153
153
  iwa/web/routers/olas/staking.py,sha256=jktJ2C1Q9X4aC0tWJByN3sHpEXY0EIvr3rr4N0MtXXc,14081
154
- iwa/web/static/app.js,sha256=CWm_TR2nKSDe8z0-nUQp7VaBHIGJg7mAOU-XJDveFsk,113487
154
+ iwa/web/static/app.js,sha256=hZns7VpUZDRnHaIkOLinit65yGItYAxRj6j20CBSm-o,113839
155
155
  iwa/web/static/index.html,sha256=q7s7plnMbN1Nkzr5bRxZgvgOFerUChEGIZW7SpAVtPc,28514
156
156
  iwa/web/static/style.css,sha256=aTtE42mmfYV6y7xfo9cUgUhT8x-KyNC1zmPjSdskxIk,24315
157
157
  iwa/web/tests/test_web_endpoints.py,sha256=C264MH-CTyDW4GLUrTXBgLJKUk4-89pFAScBddd4Fvk,23995
158
158
  iwa/web/tests/test_web_olas.py,sha256=0CVSsrncOeJ3x0ECV7mVLQV_CXZRrOqGiVjgLIi6hZ8,16308
159
159
  iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
160
160
  iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
161
- iwa-0.0.31.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
161
+ iwa-0.0.33.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
162
162
  tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
163
163
  tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
164
164
  tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
@@ -211,8 +211,8 @@ tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
211
211
  tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
212
212
  tools/create_and_stake_service.py,sha256=1xwy_bJQI1j9yIQ968Oc9Db_F6mk1659LuuZntTASDE,3742
213
213
  tools/verify_drain.py,sha256=PkMjblyOOAuQge88FwfEzRtCYeEtJxXhPBmtQYCoQ-8,6743
214
- iwa-0.0.31.dist-info/METADATA,sha256=RiJtuR4SmuW363r5cA7niuwufEjRFzIBV_zg9eeb5DM,7295
215
- iwa-0.0.31.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
216
- iwa-0.0.31.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
217
- iwa-0.0.31.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
218
- iwa-0.0.31.dist-info/RECORD,,
214
+ iwa-0.0.33.dist-info/METADATA,sha256=bwANWxXoIcxfT9aqgxEufCR9s4dfGzuEQmc17xjlJno,7295
215
+ iwa-0.0.33.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
216
+ iwa-0.0.33.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
217
+ iwa-0.0.33.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
218
+ iwa-0.0.33.dist-info/RECORD,,
File without changes