iwa 0.0.24__py3-none-any.whl → 0.0.26__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.
@@ -234,6 +234,9 @@ class OlasServiceImporter:
234
234
  # Extract staking program from .env
235
235
  self._extract_staking_from_env(service, folder)
236
236
 
237
+ # Infer owner address from keys if not already set
238
+ self._infer_owner_address(service)
239
+
237
240
  if not service.keys and not service.service_id:
238
241
  logger.debug(f"No valid data found in {folder}")
239
242
  return None
@@ -423,6 +426,9 @@ class OlasServiceImporter:
423
426
  # 5. Extract owner address from wallets folder
424
427
  self._extract_owner_address(service, operate_folder)
425
428
 
429
+ # 6. Infer owner address from keys if not already set
430
+ self._infer_owner_address(service)
431
+
426
432
  return service
427
433
 
428
434
  def _extract_keys_from_operate_config(
@@ -534,6 +540,17 @@ class OlasServiceImporter:
534
540
  service.keys.append(key)
535
541
  existing_addrs.add(key.address.lower())
536
542
 
543
+ def _infer_owner_address(self, service: DiscoveredService) -> None:
544
+ """Infer service_owner_address from keys with role='owner' if not already set."""
545
+ if service.service_owner_address:
546
+ return # Already set
547
+
548
+ for key in service.keys:
549
+ if key.role == "owner" and key.address:
550
+ service.service_owner_address = key.address
551
+ logger.debug(f"Inferred owner address from key: {key.address}")
552
+ return
553
+
537
554
  def _parse_keystore_file(
538
555
  self, file_path: Path, role: str = "unknown"
539
556
  ) -> Optional[DiscoveredKey]:
@@ -269,9 +269,9 @@ class OlasPlugin(Plugin):
269
269
  # Scan directory
270
270
  console.print(f"\n[bold]Scanning[/bold] {path}...")
271
271
 
272
- # Ask for password in dry-run to allow signature verification of encrypted keys
273
- if dry_run and not password:
274
- password = self._prompt_dry_run_password()
272
+ # Ask for password before scan to allow signature verification of encrypted keys
273
+ if not password:
274
+ password = self._prompt_password_for_verification()
275
275
 
276
276
  importer = OlasServiceImporter(password=password)
277
277
  discovered = importer.scan_directory(Path(path))
@@ -306,8 +306,8 @@ class OlasPlugin(Plugin):
306
306
  results = self._import_and_print_results(console, importer, discovered, password)
307
307
  self._print_import_summary(console, *results)
308
308
 
309
- def _prompt_dry_run_password(self) -> Optional[str]:
310
- """Prompt for password during dry-run."""
309
+ def _prompt_password_for_verification(self) -> Optional[str]:
310
+ """Prompt for password to verify encrypted keys during scan."""
311
311
  pwd = typer.prompt(
312
312
  "Enter wallet password to verify encrypted keys (optional, press Enter to skip)",
313
313
  hide_input=True,
@@ -146,8 +146,8 @@ def test_import_services_cli_abort(plugin, runner):
146
146
  DiscoveredService(service_id=1, service_name="Test", chain_name="gnosis")
147
147
  ]
148
148
 
149
- # Simulate 'n' to confirmation prompt
150
- result = runner.invoke(app, ["/tmp/test"], input="n\n")
149
+ # input: first Enter to skip password prompt, then 'n' to abort confirmation
150
+ result = runner.invoke(app, ["/tmp/test"], input="\nn\n")
151
151
  assert result.exit_code == 0
152
152
  assert "Aborted" in result.output
153
153
  mock_importer.import_service.assert_not_called()
@@ -162,7 +162,8 @@ def test_import_services_cli_no_services(plugin, runner):
162
162
  mock_importer = mock_importer_cls.return_value
163
163
  mock_importer.scan_directory.return_value = []
164
164
 
165
- result = runner.invoke(app, ["/tmp/test"])
165
+ # input: Enter to skip password prompt
166
+ result = runner.invoke(app, ["/tmp/test"], input="\n")
166
167
  assert result.exit_code == 0
167
168
  assert "No Olas services found" in result.output
168
169
 
@@ -208,8 +209,9 @@ def test_import_services_cli_password_prompt(plugin, runner):
208
209
  mock_importer.scan_directory.return_value = [service]
209
210
  mock_importer.import_service.return_value = ImportResult(success=True, message="OK")
210
211
 
211
- # input="y\nsecret\n" -> 'y' for confirm import, 'secret' for password prompt
212
- result = runner.invoke(app, ["/tmp/test"], input="y\nsecret\n")
212
+ # input: 'secret' for password before scan, 'y' for confirm import
213
+ # Note: password is now prompted BEFORE scan for signature verification
214
+ result = runner.invoke(app, ["/tmp/test"], input="secret\ny\n")
213
215
  assert result.exit_code == 0
214
216
  assert "password" in result.output.lower()
215
217
  mock_importer.import_service.assert_called_with(service, "secret")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwa
3
- Version: 0.0.24
3
+ Version: 0.0.26
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
@@ -61,10 +61,10 @@ iwa/plugins/gnosis/tests/test_safe.py,sha256=hQHVHBWQhGnuvzvx4U9fOWEwASJWwql42q6
61
61
  iwa/plugins/olas/__init__.py,sha256=_NhBczzM61fhGYwGhnWfEeL8Jywyy_730GASe2BxzeQ,106
62
62
  iwa/plugins/olas/constants.py,sha256=iTFoO2QW3KbhL5k5sKsJxxyDytl9wVIb_9hAih55KrE,7728
63
63
  iwa/plugins/olas/events.py,sha256=SWD3wYdQ-l6dLUJSkfh_WsLmedH4Vsw_EvYXg7QC3yc,5970
64
- iwa/plugins/olas/importer.py,sha256=-zI0Fqmf6E7w3OpqEuTR8vuQOaAGNykGWzHZgadrHmE,37362
64
+ iwa/plugins/olas/importer.py,sha256=A7trGY8yz-uB0MNDcC7W3U_FR_wSECoFnMkzCVw3rlc,38059
65
65
  iwa/plugins/olas/mech_reference.py,sha256=CaSCpQnQL4F7wOG6Ox6Zdoy-uNEQ78YBwVLILQZKL8Q,5782
66
66
  iwa/plugins/olas/models.py,sha256=xC5hYakX53pBT6zZteM9cyiC7t6XRLLpobjQmDYueOo,3520
67
- iwa/plugins/olas/plugin.py,sha256=sv1Hx4-wHZOwpdjhrpvxrFaA44wiGkcCXjbI_7NLH2Y,13127
67
+ iwa/plugins/olas/plugin.py,sha256=7vTnr7OUZhzXKxyQjjp5oiRkMsB5c-1arDW4YYoV9RM,13156
68
68
  iwa/plugins/olas/contracts/activity_checker.py,sha256=WXxuzbpXGVqIfEiMPiiqN3Z_UxIY-Lvx0raa1ErBfPA,5323
69
69
  iwa/plugins/olas/contracts/base.py,sha256=y73aQbDq6l4zUpz_eQAg4MsLkTAEqjjupXlcvxjfgCI,240
70
70
  iwa/plugins/olas/contracts/mech.py,sha256=dXYtyORc-oiu9ga5PtTquOFkoakb6BLGKvlUsteygIg,2767
@@ -101,7 +101,7 @@ iwa/plugins/olas/tests/test_olas_view.py,sha256=kh3crsriyoRiZC6l8vzGllocvQnYmqzi
101
101
  iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=jAxr9bjFNAaxGf1btIrxdMaHgJ0PWX9aDwVU-oPGMpk,5109
102
102
  iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvqGt49H6fLSYGxn02c8o,5562
103
103
  iwa/plugins/olas/tests/test_plugin.py,sha256=RVgU-Cq6t_3mOh90xFAGwlJOV7ZIgp0VNaK5ZAxisAQ,2565
104
- iwa/plugins/olas/tests/test_plugin_full.py,sha256=GBZ-TL5t8NXy6HVQozCI1hMEn2EY4lXjGFC89QpoPxQ,8415
104
+ iwa/plugins/olas/tests/test_plugin_full.py,sha256=55EBa07JhJLVG3IMi6QKlR_ivWLYCdLQTySP66qbEXo,8584
105
105
  iwa/plugins/olas/tests/test_service_lifecycle.py,sha256=sOCtpz8T9s55AZe9AoqP1h3XrXw5NDSjDqwLgYThvU4,5559
106
106
  iwa/plugins/olas/tests/test_service_manager.py,sha256=rS2m0A26apc-o4HsfP5oXmVcmZSR5e874bjhQKZRaSg,40650
107
107
  iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=udlAsQj_t1F5TwVQuWhroF6jDJ4RmGEXaxPh87tMsuA,8538
@@ -157,7 +157,7 @@ iwa/web/tests/test_web_endpoints.py,sha256=C264MH-CTyDW4GLUrTXBgLJKUk4-89pFAScBd
157
157
  iwa/web/tests/test_web_olas.py,sha256=0CVSsrncOeJ3x0ECV7mVLQV_CXZRrOqGiVjgLIi6hZ8,16308
158
158
  iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
159
159
  iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
160
- iwa-0.0.24.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
160
+ iwa-0.0.26.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
161
161
  tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
162
162
  tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
163
163
  tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
@@ -210,8 +210,8 @@ tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
210
210
  tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
211
211
  tools/create_and_stake_service.py,sha256=1xwy_bJQI1j9yIQ968Oc9Db_F6mk1659LuuZntTASDE,3742
212
212
  tools/verify_drain.py,sha256=PkMjblyOOAuQge88FwfEzRtCYeEtJxXhPBmtQYCoQ-8,6743
213
- iwa-0.0.24.dist-info/METADATA,sha256=N-qgeL8ZAmzJTvBthIa65x8zoZpsmqVuFG4YZ_K7-kA,7295
214
- iwa-0.0.24.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
215
- iwa-0.0.24.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
216
- iwa-0.0.24.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
217
- iwa-0.0.24.dist-info/RECORD,,
213
+ iwa-0.0.26.dist-info/METADATA,sha256=Wqiy2X1x-bMEyAb6hYzuWfhXhSp65n4HnCD5lK4GO5c,7295
214
+ iwa-0.0.26.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
215
+ iwa-0.0.26.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
216
+ iwa-0.0.26.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
217
+ iwa-0.0.26.dist-info/RECORD,,
File without changes