iwa 0.0.0__tar.gz → 0.0.1a2__tar.gz
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-0.0.1a2/LICENSE +21 -0
- iwa-0.0.1a2/PKG-INFO +234 -0
- iwa-0.0.1a2/README.md +197 -0
- iwa-0.0.1a2/pyproject.toml +135 -0
- iwa-0.0.1a2/src/conftest.py +22 -0
- iwa-0.0.1a2/src/iwa/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/__main__.py +6 -0
- iwa-0.0.1a2/src/iwa/core/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/core/chain/__init__.py +68 -0
- iwa-0.0.1a2/src/iwa/core/chain/errors.py +47 -0
- iwa-0.0.1a2/src/iwa/core/chain/interface.py +514 -0
- iwa-0.0.1a2/src/iwa/core/chain/manager.py +38 -0
- iwa-0.0.1a2/src/iwa/core/chain/models.py +128 -0
- iwa-0.0.1a2/src/iwa/core/chain/rate_limiter.py +193 -0
- iwa-0.0.1a2/src/iwa/core/cli.py +210 -0
- iwa-0.0.1a2/src/iwa/core/constants.py +28 -0
- iwa-0.0.1a2/src/iwa/core/contracts/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/core/contracts/contract.py +297 -0
- iwa-0.0.1a2/src/iwa/core/contracts/erc20.py +79 -0
- iwa-0.0.1a2/src/iwa/core/contracts/multisend.py +71 -0
- iwa-0.0.1a2/src/iwa/core/db.py +317 -0
- iwa-0.0.1a2/src/iwa/core/keys.py +361 -0
- iwa-0.0.1a2/src/iwa/core/mnemonic.py +385 -0
- iwa-0.0.1a2/src/iwa/core/models.py +344 -0
- iwa-0.0.1a2/src/iwa/core/monitor.py +209 -0
- iwa-0.0.1a2/src/iwa/core/plugins.py +45 -0
- iwa-0.0.1a2/src/iwa/core/pricing.py +91 -0
- iwa-0.0.1a2/src/iwa/core/services/__init__.py +17 -0
- iwa-0.0.1a2/src/iwa/core/services/account.py +57 -0
- iwa-0.0.1a2/src/iwa/core/services/balance.py +113 -0
- iwa-0.0.1a2/src/iwa/core/services/plugin.py +88 -0
- iwa-0.0.1a2/src/iwa/core/services/safe.py +392 -0
- iwa-0.0.1a2/src/iwa/core/services/transaction.py +172 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/__init__.py +166 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/base.py +260 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/erc20.py +247 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/multisend.py +386 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/native.py +262 -0
- iwa-0.0.1a2/src/iwa/core/services/transfer/swap.py +326 -0
- iwa-0.0.1a2/src/iwa/core/settings.py +95 -0
- iwa-0.0.1a2/src/iwa/core/tables.py +60 -0
- iwa-0.0.1a2/src/iwa/core/test.py +27 -0
- iwa-0.0.1a2/src/iwa/core/tests/test_wallet.py +255 -0
- iwa-0.0.1a2/src/iwa/core/types.py +59 -0
- iwa-0.0.1a2/src/iwa/core/ui.py +99 -0
- iwa-0.0.1a2/src/iwa/core/utils.py +59 -0
- iwa-0.0.1a2/src/iwa/core/wallet.py +380 -0
- iwa-0.0.1a2/src/iwa/plugins/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/__init__.py +5 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/cow/__init__.py +6 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/cow/quotes.py +148 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/cow/swap.py +403 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/cow/types.py +20 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/cow_utils.py +44 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/plugin.py +68 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/safe.py +157 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/tests/test_cow.py +227 -0
- iwa-0.0.1a2/src/iwa/plugins/gnosis/tests/test_safe.py +100 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/__init__.py +5 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/constants.py +106 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/activity_checker.py +93 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/base.py +10 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/mech.py +49 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/mech_marketplace.py +43 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/service.py +215 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/contracts/staking.py +403 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/importer.py +736 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/mech_reference.py +135 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/models.py +110 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/plugin.py +243 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/scripts/test_full_mech_flow.py +259 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/scripts/test_simple_lifecycle.py +74 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/__init__.py +60 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/base.py +113 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/drain.py +336 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/lifecycle.py +839 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/mech.py +322 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/service_manager/staking.py +530 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/conftest.py +30 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_importer.py +128 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_importer_error_handling.py +349 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_mech_contracts.py +85 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_contracts.py +249 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_integration.py +561 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_models.py +144 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_view.py +258 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_view_actions.py +137 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_olas_view_modals.py +120 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_plugin.py +70 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_plugin_full.py +212 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_lifecycle.py +150 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager.py +1065 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager_errors.py +208 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager_flows.py +497 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager_mech.py +135 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager_rewards.py +360 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_manager_validation.py +145 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_service_staking.py +342 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_staking_integration.py +269 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tests/test_staking_validation.py +109 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tui/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/plugins/olas/tui/olas_view.py +952 -0
- iwa-0.0.1a2/src/iwa/tools/check_profile.py +67 -0
- iwa-0.0.1a2/src/iwa/tools/release.py +111 -0
- iwa-0.0.1a2/src/iwa/tools/reset_env.py +111 -0
- iwa-0.0.1a2/src/iwa/tools/reset_tenderly.py +362 -0
- iwa-0.0.1a2/src/iwa/tools/restore_backup.py +82 -0
- iwa-0.0.1a2/src/iwa/tui/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/tui/app.py +174 -0
- iwa-0.0.1a2/src/iwa/tui/modals/__init__.py +5 -0
- iwa-0.0.1a2/src/iwa/tui/modals/base.py +406 -0
- iwa-0.0.1a2/src/iwa/tui/rpc.py +63 -0
- iwa-0.0.1a2/src/iwa/tui/screens/__init__.py +1 -0
- iwa-0.0.1a2/src/iwa/tui/screens/wallets.py +749 -0
- iwa-0.0.1a2/src/iwa/tui/tests/test_app.py +125 -0
- iwa-0.0.1a2/src/iwa/tui/tests/test_rpc.py +139 -0
- iwa-0.0.1a2/src/iwa/tui/tests/test_wallets_refactor.py +30 -0
- iwa-0.0.1a2/src/iwa/tui/tests/test_widgets.py +123 -0
- iwa-0.0.1a2/src/iwa/tui/widgets/__init__.py +5 -0
- iwa-0.0.1a2/src/iwa/tui/widgets/base.py +100 -0
- iwa-0.0.1a2/src/iwa/tui/workers.py +42 -0
- iwa-0.0.1a2/src/iwa/web/dependencies.py +76 -0
- iwa-0.0.1a2/src/iwa/web/models.py +76 -0
- iwa-0.0.1a2/src/iwa/web/routers/accounts.py +115 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/__init__.py +24 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/admin.py +169 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/funding.py +135 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/general.py +29 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/services.py +378 -0
- iwa-0.0.1a2/src/iwa/web/routers/olas/staking.py +341 -0
- iwa-0.0.1a2/src/iwa/web/routers/state.py +65 -0
- iwa-0.0.1a2/src/iwa/web/routers/swap.py +617 -0
- iwa-0.0.1a2/src/iwa/web/routers/transactions.py +153 -0
- iwa-0.0.1a2/src/iwa/web/server.py +155 -0
- iwa-0.0.1a2/src/iwa/web/tests/test_web_endpoints.py +713 -0
- iwa-0.0.1a2/src/iwa/web/tests/test_web_olas.py +430 -0
- iwa-0.0.1a2/src/iwa/web/tests/test_web_swap.py +103 -0
- iwa-0.0.1a2/src/iwa.egg-info/PKG-INFO +234 -0
- iwa-0.0.1a2/src/iwa.egg-info/SOURCES.txt +189 -0
- iwa-0.0.1a2/src/iwa.egg-info/entry_points.txt +2 -0
- iwa-0.0.1a2/src/iwa.egg-info/requires.txt +28 -0
- iwa-0.0.1a2/src/iwa.egg-info/top_level.txt +4 -0
- iwa-0.0.1a2/src/tests/legacy_cow.py +248 -0
- iwa-0.0.1a2/src/tests/legacy_safe.py +93 -0
- iwa-0.0.1a2/src/tests/legacy_transaction_retry_logic.py +51 -0
- iwa-0.0.1a2/src/tests/legacy_tui.py +440 -0
- iwa-0.0.1a2/src/tests/legacy_wallets_screen.py +554 -0
- iwa-0.0.1a2/src/tests/legacy_web.py +243 -0
- iwa-0.0.1a2/src/tests/test_account_service.py +120 -0
- iwa-0.0.1a2/src/tests/test_balance_service.py +186 -0
- iwa-0.0.1a2/src/tests/test_chain.py +490 -0
- iwa-0.0.1a2/src/tests/test_chain_interface.py +210 -0
- iwa-0.0.1a2/src/tests/test_cli.py +139 -0
- iwa-0.0.1a2/src/tests/test_contract.py +195 -0
- iwa-0.0.1a2/src/tests/test_db.py +180 -0
- iwa-0.0.1a2/src/tests/test_drain_coverage.py +174 -0
- iwa-0.0.1a2/src/tests/test_erc20.py +95 -0
- iwa-0.0.1a2/src/tests/test_gnosis_plugin.py +111 -0
- iwa-0.0.1a2/src/tests/test_keys.py +449 -0
- iwa-0.0.1a2/src/tests/test_legacy_wallet.py +1285 -0
- iwa-0.0.1a2/src/tests/test_main.py +13 -0
- iwa-0.0.1a2/src/tests/test_mnemonic.py +217 -0
- iwa-0.0.1a2/src/tests/test_modals.py +109 -0
- iwa-0.0.1a2/src/tests/test_models.py +213 -0
- iwa-0.0.1a2/src/tests/test_monitor.py +202 -0
- iwa-0.0.1a2/src/tests/test_multisend.py +84 -0
- iwa-0.0.1a2/src/tests/test_plugin_service.py +119 -0
- iwa-0.0.1a2/src/tests/test_pricing.py +143 -0
- iwa-0.0.1a2/src/tests/test_rate_limiter.py +199 -0
- iwa-0.0.1a2/src/tests/test_reset_tenderly.py +202 -0
- iwa-0.0.1a2/src/tests/test_rpc_view.py +73 -0
- iwa-0.0.1a2/src/tests/test_safe_coverage.py +139 -0
- iwa-0.0.1a2/src/tests/test_safe_service.py +168 -0
- iwa-0.0.1a2/src/tests/test_service_manager_integration.py +61 -0
- iwa-0.0.1a2/src/tests/test_service_manager_structure.py +31 -0
- iwa-0.0.1a2/src/tests/test_service_transaction.py +176 -0
- iwa-0.0.1a2/src/tests/test_staking_router.py +71 -0
- iwa-0.0.1a2/src/tests/test_staking_simple.py +31 -0
- iwa-0.0.1a2/src/tests/test_tables.py +76 -0
- iwa-0.0.1a2/src/tests/test_transaction_service.py +161 -0
- iwa-0.0.1a2/src/tests/test_transfer_multisend.py +179 -0
- iwa-0.0.1a2/src/tests/test_transfer_native.py +220 -0
- iwa-0.0.1a2/src/tests/test_transfer_security.py +93 -0
- iwa-0.0.1a2/src/tests/test_transfer_structure.py +37 -0
- iwa-0.0.1a2/src/tests/test_transfer_swap_unit.py +155 -0
- iwa-0.0.1a2/src/tests/test_ui_coverage.py +66 -0
- iwa-0.0.1a2/src/tests/test_utils.py +53 -0
- iwa-0.0.1a2/src/tests/test_workers.py +91 -0
- iwa-0.0.1a2/src/tools/verify_drain.py +183 -0
- iwa-0.0.0/PKG-INFO +0 -10
- iwa-0.0.0/README.md +0 -3
- iwa-0.0.0/pyproject.toml +0 -12
- iwa-0.0.0/src/__init__.py +0 -2
- iwa-0.0.0/src/hello.py +0 -6
- iwa-0.0.0/src/iwa.egg-info/PKG-INFO +0 -10
- iwa-0.0.0/src/iwa.egg-info/SOURCES.txt +0 -8
- iwa-0.0.0/src/iwa.egg-info/top_level.txt +0 -2
- {iwa-0.0.0 → iwa-0.0.1a2}/setup.cfg +0 -0
- {iwa-0.0.0 → iwa-0.0.1a2}/src/iwa.egg-info/dependency_links.txt +0 -0
iwa-0.0.1a2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Iwa Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
iwa-0.0.1a2/PKG-INFO
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iwa
|
|
3
|
+
Version: 0.0.1a2
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Requires-Python: <4.0,>=3.12
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: bip-utils>=2.9.3
|
|
9
|
+
Requires-Dist: cryptography>=46.0.2
|
|
10
|
+
Requires-Dist: eth-account>=0.13.7
|
|
11
|
+
Requires-Dist: loguru>=0.7.3
|
|
12
|
+
Requires-Dist: pydantic>=2.12.0
|
|
13
|
+
Requires-Dist: pydantic-settings>=2.11.0
|
|
14
|
+
Requires-Dist: rich>=14.2.0
|
|
15
|
+
Requires-Dist: tomli>=2.3.0
|
|
16
|
+
Requires-Dist: tomli-w>=1.2.0
|
|
17
|
+
Requires-Dist: typer>=0.19.2
|
|
18
|
+
Requires-Dist: web3>=7.13.0
|
|
19
|
+
Requires-Dist: pyyaml<7.0.0,>=6.0.3
|
|
20
|
+
Requires-Dist: safe-eth-py>=7.14.0
|
|
21
|
+
Requires-Dist: twine>=6.2.0
|
|
22
|
+
Requires-Dist: cowdao-cowpy>=1.0.1
|
|
23
|
+
Requires-Dist: pytest>=9.0.1
|
|
24
|
+
Requires-Dist: textual>=0.47.1
|
|
25
|
+
Requires-Dist: pyperclip>=1.8.2
|
|
26
|
+
Requires-Dist: peewee>=3.17.0
|
|
27
|
+
Requires-Dist: fastapi>=0.115.0
|
|
28
|
+
Requires-Dist: uvicorn>=0.32.0
|
|
29
|
+
Requires-Dist: jinja2>=3.1.4
|
|
30
|
+
Requires-Dist: cbor2==5.8.0
|
|
31
|
+
Requires-Dist: slowapi>=0.1.9
|
|
32
|
+
Requires-Dist: nest-asyncio>=1.6.0
|
|
33
|
+
Requires-Dist: aiohttp>=3.13.3
|
|
34
|
+
Requires-Dist: pynacl>=1.6.2
|
|
35
|
+
Requires-Dist: urllib3>=2.6.3
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# Iwa
|
|
39
|
+
|
|
40
|
+
[](https://badge.fury.io/py/iwa)
|
|
41
|
+
[](https://hub.docker.com/r/dvilela/iwa)
|
|
42
|
+
[](https://www.python.org/downloads/)
|
|
43
|
+
[]()
|
|
44
|
+
[]()
|
|
45
|
+
[](https://opensource.org/licenses/MIT)
|
|
46
|
+
|
|
47
|
+
*Iwa (岩), meaning "rock" in Japanese, symbolizes the unshakeable stability and immutable foundation required for secure financial infrastructure.*
|
|
48
|
+
|
|
49
|
+
</br>
|
|
50
|
+
<p align="center">
|
|
51
|
+
<img width="40%" src="https://raw.githubusercontent.com/dvilelaf/iwa/master/images/iwa.png">
|
|
52
|
+
</p>
|
|
53
|
+
</br>
|
|
54
|
+
|
|
55
|
+
Iwa is a Python framework designed for managing crypto wallets and interacting with smart contracts and crypto protocols in a secure, modular, and extensible way. It's ideal for building autonomous agents and applications that require blockchain interactions.
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- **Secure Key Storage**: Private keys are encrypted with AES-256-GCM and stored safely. They are never exposed to the application layer; signing happens internally via the `KeyStorage` class.
|
|
60
|
+
|
|
61
|
+
- **Modularity (Plugins)**: Protocols and features are implemented as plugins, loaded dynamically. Currently supports Gnosis (Safe, CowSwap) and Olas (Registry, Services, Staking).
|
|
62
|
+
|
|
63
|
+
- **Multi-Chain Support**: Native support for Gnosis Chain, Ethereum, and Base, with easy extensibility for others.
|
|
64
|
+
|
|
65
|
+
- **Robust Transaction Management**:
|
|
66
|
+
- **RPC Rotation**: Automatically switches RPC providers if one fails or is rate-limited.
|
|
67
|
+
- **Rate Limiting**: Token bucket algorithm with automatic backoff.
|
|
68
|
+
- **Retry Logic**: Automatic retries with exponential backoff for transient failures.
|
|
69
|
+
|
|
70
|
+
- **CLI & TUI Integration**: Interact with your wallet via a unified CLI or a beautiful Terminal User Interface built with Textual.
|
|
71
|
+
|
|
72
|
+
- **Web API**: RESTful API built with FastAPI for web-based integrations.
|
|
73
|
+
|
|
74
|
+
- **Modern Tooling**: Managed with `uv`, `Justfile` for automation, and ready for Docker deployment.
|
|
75
|
+
|
|
76
|
+
## Architecture
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
iwa/
|
|
80
|
+
├── core/ # Core wallet functionality
|
|
81
|
+
│ ├── keys.py # KeyStorage - Encrypted key management
|
|
82
|
+
│ ├── wallet.py # Wallet - High-level interface
|
|
83
|
+
│ ├── chain.py # ChainInterface - Blockchain interaction with rate limiting
|
|
84
|
+
│ ├── services/ # Service layer (accounts, balances, transactions)
|
|
85
|
+
│ └── contracts/ # Contract abstractions (ERC20, Safe)
|
|
86
|
+
├── plugins/ # Protocol integrations
|
|
87
|
+
│ ├── gnosis/ # Safe multisig and CowSwap DEX
|
|
88
|
+
│ └── olas/ # Olas Registry, Services, Staking
|
|
89
|
+
├── tui/ # Terminal User Interface (Textual)
|
|
90
|
+
└── web/ # Web API (FastAPI)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Key Components
|
|
94
|
+
|
|
95
|
+
| Component | Description |
|
|
96
|
+
|-----------|-------------|
|
|
97
|
+
| `KeyStorage` | Encrypts/decrypts private keys, provides internal signing |
|
|
98
|
+
| `Wallet` | Main high-level interface for user interactions |
|
|
99
|
+
| `ChainInterface` | Manages Web3 connections with rate limiting and RPC rotation |
|
|
100
|
+
| `TransactionService` | Handles transaction signing and sending with retry logic |
|
|
101
|
+
| `PluginService` | Dynamically loads and manages protocol plugins |
|
|
102
|
+
|
|
103
|
+
## Setup & Usage
|
|
104
|
+
|
|
105
|
+
### Prerequisites
|
|
106
|
+
|
|
107
|
+
- Python 3.12+
|
|
108
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
109
|
+
|
|
110
|
+
### Installation
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Install from PyPI
|
|
114
|
+
pip install iwa
|
|
115
|
+
|
|
116
|
+
# Or using uv (recommended for tools)
|
|
117
|
+
uv tool install iwa
|
|
118
|
+
|
|
119
|
+
# Or from source
|
|
120
|
+
git clone https://github.com/dvilelaf/iwa.git
|
|
121
|
+
cd iwa
|
|
122
|
+
just install
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Configuration
|
|
126
|
+
|
|
127
|
+
Create a `secrets.env` file with your configuration:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
WALLET_PASSWORD=your_secure_password
|
|
131
|
+
GNOSIS_RPC=https://rpc.gnosis.io,https://gnosis.drpc.org
|
|
132
|
+
ETHEREUM_RPC=https://mainnet.infura.io/v3/YOUR_KEY
|
|
133
|
+
BASE_RPC=https://mainnet.base.org
|
|
134
|
+
|
|
135
|
+
# Optional
|
|
136
|
+
GNOSISSCAN_API_KEY=your_api_key
|
|
137
|
+
COINGECKO_API_KEY=your_api_key
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Running
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Launch TUI
|
|
144
|
+
just tui
|
|
145
|
+
|
|
146
|
+
# Launch Web UI
|
|
147
|
+
just web
|
|
148
|
+
|
|
149
|
+
# Use CLI
|
|
150
|
+
iwa wallet list --chain gnosis
|
|
151
|
+
iwa wallet balance <address> --chain gnosis
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Running Tests
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
just test
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Security Checks
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
just security # Runs gitleaks, bandit, and pip-audit
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Docker
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# Pull from Docker Hub
|
|
170
|
+
docker pull dvilelaf/iwa:latest
|
|
171
|
+
|
|
172
|
+
# Build locally
|
|
173
|
+
just docker-build
|
|
174
|
+
just docker-run
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Plugins
|
|
178
|
+
|
|
179
|
+
Plugins are located in `src/iwa/plugins`. Currently supported:
|
|
180
|
+
|
|
181
|
+
### Gnosis Plugin
|
|
182
|
+
- **Safe**: Create and manage Safe multisig wallets
|
|
183
|
+
- **CowSwap**: Token swaps via CoW Protocol with MEV protection, Max balance support, and auto-refreshing UI
|
|
184
|
+
|
|
185
|
+
### Olas Plugin
|
|
186
|
+
- **Registry**: Interact with Olas service registry
|
|
187
|
+
- **Services**: Create, deploy, and manage Olas services
|
|
188
|
+
- **Staking**: Stake/unstake services and claim rewards
|
|
189
|
+
|
|
190
|
+
## Transaction Flow
|
|
191
|
+
|
|
192
|
+
1. **Preparation**: A high-level method prepares a raw transaction dictionary
|
|
193
|
+
2. **Delegation**: The transaction is passed to `TransactionService`
|
|
194
|
+
3. **Signing**: `KeyStorage` decrypts the key in memory, signs, and wipes the key
|
|
195
|
+
4. **Sending**: The signed transaction is sent via `ChainInterface`
|
|
196
|
+
5. **Recovery**: Automatic RPC rotation and gas bumping on failures
|
|
197
|
+
6. **Receipt**: Transaction receipt is returned upon success
|
|
198
|
+
|
|
199
|
+
## Documentation
|
|
200
|
+
|
|
201
|
+
Full documentation is available in the `docs/` directory:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# Serve docs locally
|
|
205
|
+
just docs-serve
|
|
206
|
+
|
|
207
|
+
# Build static docs
|
|
208
|
+
just docs-build
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Development
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Format code
|
|
215
|
+
just format
|
|
216
|
+
|
|
217
|
+
# Lint code
|
|
218
|
+
just check
|
|
219
|
+
|
|
220
|
+
# Type check
|
|
221
|
+
just types
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
1. Fork the repository
|
|
227
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
228
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
229
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
230
|
+
5. Open a Pull Request
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
iwa-0.0.1a2/README.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Iwa
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/iwa)
|
|
4
|
+
[](https://hub.docker.com/r/dvilela/iwa)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[]()
|
|
7
|
+
[]()
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
*Iwa (岩), meaning "rock" in Japanese, symbolizes the unshakeable stability and immutable foundation required for secure financial infrastructure.*
|
|
11
|
+
|
|
12
|
+
</br>
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img width="40%" src="https://raw.githubusercontent.com/dvilelaf/iwa/master/images/iwa.png">
|
|
15
|
+
</p>
|
|
16
|
+
</br>
|
|
17
|
+
|
|
18
|
+
Iwa is a Python framework designed for managing crypto wallets and interacting with smart contracts and crypto protocols in a secure, modular, and extensible way. It's ideal for building autonomous agents and applications that require blockchain interactions.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Secure Key Storage**: Private keys are encrypted with AES-256-GCM and stored safely. They are never exposed to the application layer; signing happens internally via the `KeyStorage` class.
|
|
23
|
+
|
|
24
|
+
- **Modularity (Plugins)**: Protocols and features are implemented as plugins, loaded dynamically. Currently supports Gnosis (Safe, CowSwap) and Olas (Registry, Services, Staking).
|
|
25
|
+
|
|
26
|
+
- **Multi-Chain Support**: Native support for Gnosis Chain, Ethereum, and Base, with easy extensibility for others.
|
|
27
|
+
|
|
28
|
+
- **Robust Transaction Management**:
|
|
29
|
+
- **RPC Rotation**: Automatically switches RPC providers if one fails or is rate-limited.
|
|
30
|
+
- **Rate Limiting**: Token bucket algorithm with automatic backoff.
|
|
31
|
+
- **Retry Logic**: Automatic retries with exponential backoff for transient failures.
|
|
32
|
+
|
|
33
|
+
- **CLI & TUI Integration**: Interact with your wallet via a unified CLI or a beautiful Terminal User Interface built with Textual.
|
|
34
|
+
|
|
35
|
+
- **Web API**: RESTful API built with FastAPI for web-based integrations.
|
|
36
|
+
|
|
37
|
+
- **Modern Tooling**: Managed with `uv`, `Justfile` for automation, and ready for Docker deployment.
|
|
38
|
+
|
|
39
|
+
## Architecture
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
iwa/
|
|
43
|
+
├── core/ # Core wallet functionality
|
|
44
|
+
│ ├── keys.py # KeyStorage - Encrypted key management
|
|
45
|
+
│ ├── wallet.py # Wallet - High-level interface
|
|
46
|
+
│ ├── chain.py # ChainInterface - Blockchain interaction with rate limiting
|
|
47
|
+
│ ├── services/ # Service layer (accounts, balances, transactions)
|
|
48
|
+
│ └── contracts/ # Contract abstractions (ERC20, Safe)
|
|
49
|
+
├── plugins/ # Protocol integrations
|
|
50
|
+
│ ├── gnosis/ # Safe multisig and CowSwap DEX
|
|
51
|
+
│ └── olas/ # Olas Registry, Services, Staking
|
|
52
|
+
├── tui/ # Terminal User Interface (Textual)
|
|
53
|
+
└── web/ # Web API (FastAPI)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Key Components
|
|
57
|
+
|
|
58
|
+
| Component | Description |
|
|
59
|
+
|-----------|-------------|
|
|
60
|
+
| `KeyStorage` | Encrypts/decrypts private keys, provides internal signing |
|
|
61
|
+
| `Wallet` | Main high-level interface for user interactions |
|
|
62
|
+
| `ChainInterface` | Manages Web3 connections with rate limiting and RPC rotation |
|
|
63
|
+
| `TransactionService` | Handles transaction signing and sending with retry logic |
|
|
64
|
+
| `PluginService` | Dynamically loads and manages protocol plugins |
|
|
65
|
+
|
|
66
|
+
## Setup & Usage
|
|
67
|
+
|
|
68
|
+
### Prerequisites
|
|
69
|
+
|
|
70
|
+
- Python 3.12+
|
|
71
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
72
|
+
|
|
73
|
+
### Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Install from PyPI
|
|
77
|
+
pip install iwa
|
|
78
|
+
|
|
79
|
+
# Or using uv (recommended for tools)
|
|
80
|
+
uv tool install iwa
|
|
81
|
+
|
|
82
|
+
# Or from source
|
|
83
|
+
git clone https://github.com/dvilelaf/iwa.git
|
|
84
|
+
cd iwa
|
|
85
|
+
just install
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Configuration
|
|
89
|
+
|
|
90
|
+
Create a `secrets.env` file with your configuration:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
WALLET_PASSWORD=your_secure_password
|
|
94
|
+
GNOSIS_RPC=https://rpc.gnosis.io,https://gnosis.drpc.org
|
|
95
|
+
ETHEREUM_RPC=https://mainnet.infura.io/v3/YOUR_KEY
|
|
96
|
+
BASE_RPC=https://mainnet.base.org
|
|
97
|
+
|
|
98
|
+
# Optional
|
|
99
|
+
GNOSISSCAN_API_KEY=your_api_key
|
|
100
|
+
COINGECKO_API_KEY=your_api_key
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Running
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Launch TUI
|
|
107
|
+
just tui
|
|
108
|
+
|
|
109
|
+
# Launch Web UI
|
|
110
|
+
just web
|
|
111
|
+
|
|
112
|
+
# Use CLI
|
|
113
|
+
iwa wallet list --chain gnosis
|
|
114
|
+
iwa wallet balance <address> --chain gnosis
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Running Tests
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
just test
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Security Checks
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
just security # Runs gitleaks, bandit, and pip-audit
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Docker
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Pull from Docker Hub
|
|
133
|
+
docker pull dvilelaf/iwa:latest
|
|
134
|
+
|
|
135
|
+
# Build locally
|
|
136
|
+
just docker-build
|
|
137
|
+
just docker-run
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Plugins
|
|
141
|
+
|
|
142
|
+
Plugins are located in `src/iwa/plugins`. Currently supported:
|
|
143
|
+
|
|
144
|
+
### Gnosis Plugin
|
|
145
|
+
- **Safe**: Create and manage Safe multisig wallets
|
|
146
|
+
- **CowSwap**: Token swaps via CoW Protocol with MEV protection, Max balance support, and auto-refreshing UI
|
|
147
|
+
|
|
148
|
+
### Olas Plugin
|
|
149
|
+
- **Registry**: Interact with Olas service registry
|
|
150
|
+
- **Services**: Create, deploy, and manage Olas services
|
|
151
|
+
- **Staking**: Stake/unstake services and claim rewards
|
|
152
|
+
|
|
153
|
+
## Transaction Flow
|
|
154
|
+
|
|
155
|
+
1. **Preparation**: A high-level method prepares a raw transaction dictionary
|
|
156
|
+
2. **Delegation**: The transaction is passed to `TransactionService`
|
|
157
|
+
3. **Signing**: `KeyStorage` decrypts the key in memory, signs, and wipes the key
|
|
158
|
+
4. **Sending**: The signed transaction is sent via `ChainInterface`
|
|
159
|
+
5. **Recovery**: Automatic RPC rotation and gas bumping on failures
|
|
160
|
+
6. **Receipt**: Transaction receipt is returned upon success
|
|
161
|
+
|
|
162
|
+
## Documentation
|
|
163
|
+
|
|
164
|
+
Full documentation is available in the `docs/` directory:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Serve docs locally
|
|
168
|
+
just docs-serve
|
|
169
|
+
|
|
170
|
+
# Build static docs
|
|
171
|
+
just docs-build
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Format code
|
|
178
|
+
just format
|
|
179
|
+
|
|
180
|
+
# Lint code
|
|
181
|
+
just check
|
|
182
|
+
|
|
183
|
+
# Type check
|
|
184
|
+
just types
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Contributing
|
|
188
|
+
|
|
189
|
+
1. Fork the repository
|
|
190
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
191
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
192
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
193
|
+
5. Open a Pull Request
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "iwa"
|
|
3
|
+
version = "0.0.1-alpha2"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12,<4.0"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"bip-utils>=2.9.3",
|
|
9
|
+
"cryptography>=46.0.2",
|
|
10
|
+
"eth-account>=0.13.7",
|
|
11
|
+
"loguru>=0.7.3",
|
|
12
|
+
"pydantic>=2.12.0",
|
|
13
|
+
"pydantic-settings>=2.11.0",
|
|
14
|
+
"rich>=14.2.0",
|
|
15
|
+
"tomli>=2.3.0",
|
|
16
|
+
"tomli-w>=1.2.0",
|
|
17
|
+
"typer>=0.19.2",
|
|
18
|
+
"web3>=7.13.0",
|
|
19
|
+
"pyyaml (>=6.0.3,<7.0.0)",
|
|
20
|
+
"safe-eth-py>=7.14.0",
|
|
21
|
+
"twine>=6.2.0",
|
|
22
|
+
"cowdao-cowpy>=1.0.1",
|
|
23
|
+
"pytest>=9.0.1",
|
|
24
|
+
"textual>=0.47.1",
|
|
25
|
+
"pyperclip>=1.8.2",
|
|
26
|
+
"peewee>=3.17.0",
|
|
27
|
+
"fastapi>=0.115.0",
|
|
28
|
+
"uvicorn>=0.32.0",
|
|
29
|
+
"jinja2>=3.1.4",
|
|
30
|
+
"cbor2==5.8.0",
|
|
31
|
+
"slowapi>=0.1.9",
|
|
32
|
+
"nest-asyncio>=1.6.0",
|
|
33
|
+
"aiohttp>=3.13.3",
|
|
34
|
+
"pynacl>=1.6.2",
|
|
35
|
+
"urllib3>=2.6.3",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
iwa = "iwa.core.cli:iwa_cli"
|
|
40
|
+
|
|
41
|
+
[dependency-groups]
|
|
42
|
+
dev = [
|
|
43
|
+
"mypy>=1.18.2",
|
|
44
|
+
"ruff>=0.14.1",
|
|
45
|
+
"twine>=6.2.0",
|
|
46
|
+
"pytest-cov>=6.0.0",
|
|
47
|
+
"pytest-asyncio>=0.23.0",
|
|
48
|
+
"mkdocs>=1.6.1",
|
|
49
|
+
"mkdocs-material>=9.5.49",
|
|
50
|
+
"mkdocstrings[python]>=0.27.0",
|
|
51
|
+
"bandit>=1.9.2",
|
|
52
|
+
"pip-audit>=2.10.0",
|
|
53
|
+
"djlint>=1.34.1",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[build-system]
|
|
57
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
58
|
+
build-backend = "setuptools.build_meta"
|
|
59
|
+
|
|
60
|
+
[tool.ruff]
|
|
61
|
+
line-length = 100
|
|
62
|
+
target-version = "0.0.1-alpha2"
|
|
63
|
+
fix = true
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
extend-select = ["I", "B", "C90", "N", "D"] # imports, bugbear, complexity, naming, docstrings
|
|
67
|
+
ignore = [
|
|
68
|
+
"E501",
|
|
69
|
+
"D203",
|
|
70
|
+
"D213",
|
|
71
|
+
"D400", # First line should end with a period
|
|
72
|
+
"D401", # First line should be in imperative mood
|
|
73
|
+
"D415", # First line should end with a period, question mark, or exclamation point
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
[tool.ruff.lint.per-file-ignores]
|
|
77
|
+
"src/tests/**/*.py" = ["D", "E402"]
|
|
78
|
+
"tests/**/*.py" = ["D", "E402"]
|
|
79
|
+
|
|
80
|
+
[tool.ruff.format]
|
|
81
|
+
quote-style = "double"
|
|
82
|
+
indent-style = "space"
|
|
83
|
+
|
|
84
|
+
# strict = true
|
|
85
|
+
[tool.mypy]
|
|
86
|
+
check_untyped_defs = true
|
|
87
|
+
disallow_untyped_defs = false
|
|
88
|
+
ignore_missing_imports = true
|
|
89
|
+
follow_imports = "silent"
|
|
90
|
+
exclude = [
|
|
91
|
+
"pydantic_core",
|
|
92
|
+
"typing_inspection",
|
|
93
|
+
"src/tests/.*",
|
|
94
|
+
"tests/.*",
|
|
95
|
+
"src/iwa/tools/.*",
|
|
96
|
+
"src/iwa/tui/.*", # TUI is often complex with types, delaying check for speed
|
|
97
|
+
"src/iwa/plugins/olas/scripts/.*", # Integration test scripts, not production code
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
[[tool.mypy.overrides]]
|
|
101
|
+
module = [
|
|
102
|
+
"bip_utils.*",
|
|
103
|
+
"cowdao_cowpy.*",
|
|
104
|
+
"eth_account.*",
|
|
105
|
+
"loguru.*",
|
|
106
|
+
"peewee.*",
|
|
107
|
+
"playhouse.*",
|
|
108
|
+
"pydantic.*",
|
|
109
|
+
"pydantic_core.*",
|
|
110
|
+
"pyperclip.*",
|
|
111
|
+
"pytest.*",
|
|
112
|
+
"rich.*",
|
|
113
|
+
"safe_eth.*",
|
|
114
|
+
"textual.*",
|
|
115
|
+
"tomli_w.*",
|
|
116
|
+
"typer.*",
|
|
117
|
+
"web3.*",
|
|
118
|
+
"iwa.plugins.*",
|
|
119
|
+
"iwa.tui.*",
|
|
120
|
+
"iwa.core.*",
|
|
121
|
+
"iwa.*",
|
|
122
|
+
"iwa.tools.*",
|
|
123
|
+
"tests.*",
|
|
124
|
+
]
|
|
125
|
+
ignore_missing_imports = true
|
|
126
|
+
ignore_errors = true
|
|
127
|
+
follow_imports = "skip"
|
|
128
|
+
|
|
129
|
+
[tool.bandit]
|
|
130
|
+
exclude_dirs = ["tests", "src/tests", "src/iwa/plugins/olas/tests"]
|
|
131
|
+
skips = ["B101", "B105", "B106", "B110", "B107", "B112"]
|
|
132
|
+
[tool.djlint]
|
|
133
|
+
profile = "jinja"
|
|
134
|
+
extension = "html"
|
|
135
|
+
indent = 4
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Pytest configuration."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(autouse=True)
|
|
10
|
+
def caplog(caplog):
|
|
11
|
+
"""Make loguru logs visible to pytest caplog."""
|
|
12
|
+
|
|
13
|
+
class PropagateHandler(logging.Handler):
|
|
14
|
+
def emit(self, record):
|
|
15
|
+
logging.getLogger(record.name).handle(record)
|
|
16
|
+
|
|
17
|
+
handler_id = logger.add(PropagateHandler(), format="{message}")
|
|
18
|
+
yield caplog
|
|
19
|
+
try:
|
|
20
|
+
logger.remove(handler_id)
|
|
21
|
+
except ValueError:
|
|
22
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""iwa package."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""iwa.core package."""
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Chain interaction helpers.
|
|
2
|
+
|
|
3
|
+
This package provides chain-related utilities for blockchain interactions:
|
|
4
|
+
- ChainInterface: Main interface for interacting with a blockchain
|
|
5
|
+
- ChainInterfaces: Singleton manager for all supported chains
|
|
6
|
+
- SupportedChain: Base model for chain definitions
|
|
7
|
+
- Rate limiting and error handling utilities
|
|
8
|
+
|
|
9
|
+
All symbols are re-exported here for backward compatibility.
|
|
10
|
+
Import from `iwa.core.chain` to use these utilities.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import TypeVar
|
|
14
|
+
|
|
15
|
+
# Re-export all public symbols for backward compatibility
|
|
16
|
+
from iwa.core.chain.errors import (
|
|
17
|
+
TenderlyQuotaExceededError,
|
|
18
|
+
sanitize_rpc_url,
|
|
19
|
+
)
|
|
20
|
+
from iwa.core.chain.interface import (
|
|
21
|
+
DEFAULT_RPC_TIMEOUT,
|
|
22
|
+
ChainInterface,
|
|
23
|
+
)
|
|
24
|
+
from iwa.core.chain.manager import ChainInterfaces
|
|
25
|
+
from iwa.core.chain.models import (
|
|
26
|
+
Base,
|
|
27
|
+
Ethereum,
|
|
28
|
+
Gnosis,
|
|
29
|
+
SupportedChain,
|
|
30
|
+
SupportedChains,
|
|
31
|
+
)
|
|
32
|
+
from iwa.core.chain.rate_limiter import (
|
|
33
|
+
RateLimitedEth,
|
|
34
|
+
RateLimitedWeb3,
|
|
35
|
+
RPCRateLimiter,
|
|
36
|
+
get_rate_limiter,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Backward compatibility alias
|
|
40
|
+
_sanitize_rpc_url = sanitize_rpc_url
|
|
41
|
+
|
|
42
|
+
# Expose type variable for retry decorator (used in type hints)
|
|
43
|
+
T = TypeVar("T")
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
# Errors
|
|
47
|
+
"TenderlyQuotaExceededError",
|
|
48
|
+
"sanitize_rpc_url",
|
|
49
|
+
"_sanitize_rpc_url",
|
|
50
|
+
# Rate limiting
|
|
51
|
+
"RPCRateLimiter",
|
|
52
|
+
"RateLimitedEth",
|
|
53
|
+
"RateLimitedWeb3",
|
|
54
|
+
"get_rate_limiter",
|
|
55
|
+
# Models
|
|
56
|
+
"SupportedChain",
|
|
57
|
+
"Gnosis",
|
|
58
|
+
"Ethereum",
|
|
59
|
+
"Base",
|
|
60
|
+
"SupportedChains",
|
|
61
|
+
# Interface
|
|
62
|
+
"ChainInterface",
|
|
63
|
+
"DEFAULT_RPC_TIMEOUT",
|
|
64
|
+
# Manager
|
|
65
|
+
"ChainInterfaces",
|
|
66
|
+
# Types
|
|
67
|
+
"T",
|
|
68
|
+
]
|