wayfinder-paths 0.1.15__tar.gz → 0.1.17__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.
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/PKG-INFO +3 -41
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/README.md +1 -40
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/pyproject.toml +1 -1
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/balance_adapter/README.md +19 -20
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/balance_adapter/adapter.py +66 -37
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/balance_adapter/test_adapter.py +2 -8
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/README.md +22 -19
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/adapter.py +33 -34
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/test_adapter.py +2 -18
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperlend_adapter/adapter.py +45 -59
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +1 -8
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/moonwell_adapter/README.md +29 -31
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/moonwell_adapter/adapter.py +301 -662
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +275 -179
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/config.py +8 -47
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/constants/base.py +0 -1
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/constants/erc20_abi.py +13 -13
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/strategies/Strategy.py +6 -2
- wayfinder_paths-0.1.17/wayfinder_paths/core/utils/erc20_service.py +100 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/utils/evm_helpers.py +1 -1
- wayfinder_paths-0.1.17/wayfinder_paths/core/utils/transaction.py +191 -0
- wayfinder_paths-0.1.17/wayfinder_paths/core/utils/web3.py +66 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/run_strategy.py +37 -6
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/strategy.py +200 -224
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +128 -151
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +0 -1
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +52 -78
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -12
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +0 -1
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +39 -64
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -1
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +42 -85
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -8
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/strategy/README.md +1 -5
- wayfinder_paths-0.1.15/wayfinder_paths/core/clients/sdk_example.py +0 -125
- wayfinder_paths-0.1.15/wayfinder_paths/core/engine/__init__.py +0 -5
- wayfinder_paths-0.1.15/wayfinder_paths/core/services/base.py +0 -131
- wayfinder_paths-0.1.15/wayfinder_paths/core/services/local_evm_txn.py +0 -350
- wayfinder_paths-0.1.15/wayfinder_paths/core/services/local_token_txn.py +0 -238
- wayfinder_paths-0.1.15/wayfinder_paths/core/services/web3_service.py +0 -43
- wayfinder_paths-0.1.15/wayfinder_paths/core/wallets/README.md +0 -88
- wayfinder_paths-0.1.15/wayfinder_paths/core/wallets/WalletManager.py +0 -56
- wayfinder_paths-0.1.15/wayfinder_paths/core/wallets/__init__.py +0 -7
- wayfinder_paths-0.1.15/wayfinder_paths/scripts/run_strategy.py +0 -152
- wayfinder_paths-0.1.15/wayfinder_paths/strategies/config.py +0 -85
- wayfinder_paths-0.1.15/wayfinder_paths/tests/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/LICENSE +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/balance_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/executor.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/ledger_adapter/README.md +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/ledger_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/pool_adapter/README.md +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/pool_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/pool_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/pool_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/token_adapter/README.md +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/token_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/token_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/token_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/token_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/conftest.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/adapters/BaseAdapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/adapters/base.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/adapters/models.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/analytics/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/analytics/bootstrap.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/analytics/stats.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/analytics/test_analytics.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/BRAPClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/ClientManager.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/HyperlendClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/LedgerClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/PoolClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/TokenClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/WalletClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/WayfinderClient.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/clients/protocols.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/constants/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/constants/hyperlend_abi.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/constants/moonwell_abi.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/engine/StrategyJob.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/services/test_local_evm_txn.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/strategies/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/strategies/base.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/strategies/descriptors.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/utils/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/core/utils/wallets.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/enso.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/erc20.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/evm.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/hyper_evm.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/hyperlend.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/hyperliquid.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/moonwell.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/prjx.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/policies/util.py +0 -0
- {wayfinder_paths-0.1.15/wayfinder_paths/core/services → wayfinder_paths-0.1.17/wayfinder_paths/scripts}/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/scripts/create_strategy.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/scripts/make_wallets.py +0 -0
- {wayfinder_paths-0.1.15/wayfinder_paths/scripts → wayfinder_paths-0.1.17/wayfinder_paths/strategies}/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/README.md +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/constants.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/adapter/README.md +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/adapter/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/strategy/examples.json +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/strategy/strategy.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/templates/strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.15/wayfinder_paths/strategies → wayfinder_paths-0.1.17/wayfinder_paths/tests}/__init__.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/tests/test_smoke_manifest.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/tests/test_test_coverage.py +0 -0
- {wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/tests/test_utils.py +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wayfinder-paths
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary: Wayfinder Path: strategies and adapters
|
|
5
5
|
Author: Wayfinder
|
|
6
6
|
Author-email: dev@wayfinder.ai
|
|
7
7
|
Requires-Python: >=3.12,<4.0
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
11
|
Requires-Dist: aiohttp (>=3.13.0,<4.0.0)
|
|
11
12
|
Requires-Dist: eth-account (>=0.13.7,<0.14.0)
|
|
12
13
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
@@ -275,7 +276,6 @@ Strategies implement trading logic using adapters and the unified client system.
|
|
|
275
276
|
|
|
276
277
|
```python
|
|
277
278
|
# wayfinder_paths/strategies/my_strategy/strategy.py
|
|
278
|
-
from wayfinder_paths.core.services.web3_service import DefaultWeb3Service
|
|
279
279
|
from wayfinder_paths.core.strategies.Strategy import StatusDict, StatusTuple, Strategy
|
|
280
280
|
from wayfinder_paths.adapters.balance_adapter.adapter import BalanceAdapter
|
|
281
281
|
|
|
@@ -291,9 +291,8 @@ class MyStrategy(Strategy):
|
|
|
291
291
|
):
|
|
292
292
|
super().__init__(api_key=api_key) # Pass to base class for auto-discovery
|
|
293
293
|
self.config = config or {}
|
|
294
|
-
web3_service = DefaultWeb3Service(self.config)
|
|
295
294
|
# Adapters automatically discover API key from constructor or config.json
|
|
296
|
-
balance_adapter = BalanceAdapter(self.config
|
|
295
|
+
balance_adapter = BalanceAdapter(self.config)
|
|
297
296
|
self.register_adapters([balance_adapter])
|
|
298
297
|
self.balance_adapter = balance_adapter
|
|
299
298
|
|
|
@@ -311,7 +310,6 @@ class MyStrategy(Strategy):
|
|
|
311
310
|
if not success:
|
|
312
311
|
return (False, "Unable to fetch balances")
|
|
313
312
|
|
|
314
|
-
# Use BalanceAdapter (which leverages LocalTokenTxnService builders) for transfers here.
|
|
315
313
|
self.last_deposit = main_token_amount
|
|
316
314
|
return (True, f"Deposited {main_token_amount} tokens")
|
|
317
315
|
|
|
@@ -344,42 +342,6 @@ The following strategies are available and can be run using the CLI:
|
|
|
344
342
|
|
|
345
343
|
#### Running Strategies
|
|
346
344
|
|
|
347
|
-
```bash
|
|
348
|
-
# Check strategy status
|
|
349
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
350
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
351
|
-
--main-wallet-label main \
|
|
352
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
353
|
-
status
|
|
354
|
-
|
|
355
|
-
# Deposit funds (USDC amount, optional ETH for gas)
|
|
356
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
357
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
358
|
-
--main-wallet-label main \
|
|
359
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
360
|
-
deposit --usdc 100 --eth 0.01
|
|
361
|
-
|
|
362
|
-
# Run periodic update
|
|
363
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
364
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
365
|
-
--main-wallet-label main \
|
|
366
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
367
|
-
update
|
|
368
|
-
|
|
369
|
-
# Withdraw funds (omit --amount for full withdrawal)
|
|
370
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
371
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
372
|
-
--main-wallet-label main \
|
|
373
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
374
|
-
withdraw --amount 50
|
|
375
|
-
|
|
376
|
-
# Run in simulation mode (no real transactions)
|
|
377
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
378
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
379
|
-
--simulation \
|
|
380
|
-
status
|
|
381
|
-
```
|
|
382
|
-
|
|
383
345
|
### Built-in adapters
|
|
384
346
|
|
|
385
347
|
- **BALANCE (BalanceAdapter)**: wraps `WalletClient`/`TokenClient` to read wallet, token, and pool balances and now orchestrates transfers between the main/strategy wallets with ledger bookkeeping. Requires a `Web3Service` so it can share the same wallet provider as the strategy.
|
|
@@ -254,7 +254,6 @@ Strategies implement trading logic using adapters and the unified client system.
|
|
|
254
254
|
|
|
255
255
|
```python
|
|
256
256
|
# wayfinder_paths/strategies/my_strategy/strategy.py
|
|
257
|
-
from wayfinder_paths.core.services.web3_service import DefaultWeb3Service
|
|
258
257
|
from wayfinder_paths.core.strategies.Strategy import StatusDict, StatusTuple, Strategy
|
|
259
258
|
from wayfinder_paths.adapters.balance_adapter.adapter import BalanceAdapter
|
|
260
259
|
|
|
@@ -270,9 +269,8 @@ class MyStrategy(Strategy):
|
|
|
270
269
|
):
|
|
271
270
|
super().__init__(api_key=api_key) # Pass to base class for auto-discovery
|
|
272
271
|
self.config = config or {}
|
|
273
|
-
web3_service = DefaultWeb3Service(self.config)
|
|
274
272
|
# Adapters automatically discover API key from constructor or config.json
|
|
275
|
-
balance_adapter = BalanceAdapter(self.config
|
|
273
|
+
balance_adapter = BalanceAdapter(self.config)
|
|
276
274
|
self.register_adapters([balance_adapter])
|
|
277
275
|
self.balance_adapter = balance_adapter
|
|
278
276
|
|
|
@@ -290,7 +288,6 @@ class MyStrategy(Strategy):
|
|
|
290
288
|
if not success:
|
|
291
289
|
return (False, "Unable to fetch balances")
|
|
292
290
|
|
|
293
|
-
# Use BalanceAdapter (which leverages LocalTokenTxnService builders) for transfers here.
|
|
294
291
|
self.last_deposit = main_token_amount
|
|
295
292
|
return (True, f"Deposited {main_token_amount} tokens")
|
|
296
293
|
|
|
@@ -323,42 +320,6 @@ The following strategies are available and can be run using the CLI:
|
|
|
323
320
|
|
|
324
321
|
#### Running Strategies
|
|
325
322
|
|
|
326
|
-
```bash
|
|
327
|
-
# Check strategy status
|
|
328
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
329
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
330
|
-
--main-wallet-label main \
|
|
331
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
332
|
-
status
|
|
333
|
-
|
|
334
|
-
# Deposit funds (USDC amount, optional ETH for gas)
|
|
335
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
336
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
337
|
-
--main-wallet-label main \
|
|
338
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
339
|
-
deposit --usdc 100 --eth 0.01
|
|
340
|
-
|
|
341
|
-
# Run periodic update
|
|
342
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
343
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
344
|
-
--main-wallet-label main \
|
|
345
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
346
|
-
update
|
|
347
|
-
|
|
348
|
-
# Withdraw funds (omit --amount for full withdrawal)
|
|
349
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
350
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
351
|
-
--main-wallet-label main \
|
|
352
|
-
--strategy-wallet-label moonwell_wsteth_loop_strategy \
|
|
353
|
-
withdraw --amount 50
|
|
354
|
-
|
|
355
|
-
# Run in simulation mode (no real transactions)
|
|
356
|
-
poetry run python wayfinder_paths/scripts/run_strategy.py \
|
|
357
|
-
--strategy moonwell_wsteth_loop_strategy \
|
|
358
|
-
--simulation \
|
|
359
|
-
status
|
|
360
|
-
```
|
|
361
|
-
|
|
362
323
|
### Built-in adapters
|
|
363
324
|
|
|
364
325
|
- **BALANCE (BalanceAdapter)**: wraps `WalletClient`/`TokenClient` to read wallet, token, and pool balances and now orchestrates transfers between the main/strategy wallets with ledger bookkeeping. Requires a `Web3Service` so it can share the same wallet provider as the strategy.
|
{wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/balance_adapter/README.md
RENAMED
|
@@ -7,43 +7,42 @@ Adapter that exposes wallet, token, and pool balances backed by `WalletClient`/`
|
|
|
7
7
|
|
|
8
8
|
## Capabilities
|
|
9
9
|
|
|
10
|
-
The adapter provides both wallet read and wallet transfer capabilities.
|
|
10
|
+
The adapter provides both wallet read and wallet transfer capabilities. Ledger recording + wallet selection now live inside the adapter.
|
|
11
11
|
|
|
12
12
|
## Construction
|
|
13
13
|
|
|
14
14
|
```python
|
|
15
|
-
from wayfinder_paths.core.services.web3_service import DefaultWeb3Service
|
|
16
15
|
from wayfinder_paths.adapters.balance_adapter.adapter import BalanceAdapter
|
|
17
16
|
|
|
18
|
-
web3_service = DefaultWeb3Service(config)
|
|
19
|
-
balance = BalanceAdapter(config, web3_service=web3_service)
|
|
20
17
|
```
|
|
21
18
|
|
|
22
|
-
`web3_service` is required so the adapter can share the same wallet provider (and `TokenTxn` helper) as the rest of the strategy.
|
|
23
|
-
|
|
24
19
|
## API surface
|
|
25
20
|
|
|
26
|
-
### `get_balance(
|
|
27
|
-
Returns the raw balance (as an integer) for a specific token or pool on a wallet.
|
|
21
|
+
### `get_balance(token_id: str, wallet_address: str)`
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
Returns the raw balance (as an integer) for a specific token on a wallet.
|
|
30
24
|
|
|
31
25
|
```python
|
|
32
|
-
# Token balance (chain_id auto-resolved)
|
|
33
26
|
success, balance = await balance.get_balance(
|
|
34
|
-
|
|
27
|
+
token_id="usd-coin-base",
|
|
35
28
|
wallet_address=config["main_wallet"]["address"],
|
|
36
29
|
)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### `get_pool_balance(pool_address: str, chain_id: int, user_address: str)`
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
Fetches the amount supplied to a specific pool, using the `/wallets/pool-balance` endpoint.
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
success, amount = await balance.get_pool_balance(
|
|
38
|
+
pool_address="0xPool",
|
|
42
39
|
chain_id=8453,
|
|
40
|
+
user_address=config["strategy_wallet"]["address"],
|
|
43
41
|
)
|
|
44
42
|
```
|
|
45
43
|
|
|
46
44
|
### `move_from_main_wallet_to_strategy_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
|
|
45
|
+
|
|
47
46
|
Sends the specified token from the configured `main_wallet` to the strategy wallet, records the ledger deposit (unless `skip_ledger=True`), and returns the `(success, tx_result)` tuple from the underlying send helper.
|
|
48
47
|
|
|
49
48
|
```python
|
|
@@ -55,6 +54,7 @@ success, tx = await balance.move_from_main_wallet_to_strategy_wallet(
|
|
|
55
54
|
```
|
|
56
55
|
|
|
57
56
|
### `move_from_strategy_wallet_to_main_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
|
|
57
|
+
|
|
58
58
|
Mirrors the previous method but withdraws from the strategy wallet back to the main wallet while recording a ledger withdrawal entry.
|
|
59
59
|
|
|
60
60
|
```python
|
|
@@ -73,16 +73,15 @@ All methods return `(success: bool, payload: Any)` tuples. On failure the payloa
|
|
|
73
73
|
class MyStrategy(Strategy):
|
|
74
74
|
def __init__(self, config):
|
|
75
75
|
super().__init__()
|
|
76
|
-
|
|
77
|
-
balance_adapter = BalanceAdapter(config, web3_service=web3_service)
|
|
76
|
+
balance_adapter = BalanceAdapter(config)
|
|
78
77
|
self.register_adapters([balance_adapter])
|
|
79
78
|
self.balance_adapter = balance_adapter
|
|
80
79
|
|
|
81
80
|
async def _status(self):
|
|
82
|
-
success, pool_balance = await self.balance_adapter.
|
|
83
|
-
|
|
84
|
-
wallet_address=self.config["strategy_wallet"]["address"],
|
|
81
|
+
success, pool_balance = await self.balance_adapter.get_pool_balance(
|
|
82
|
+
pool_address=self.current_pool["address"],
|
|
85
83
|
chain_id=self.current_pool["chain"]["id"],
|
|
84
|
+
user_address=self.config["strategy_wallet"]["address"],
|
|
86
85
|
)
|
|
87
86
|
return {"portfolio_value": float(pool_balance or 0), ...}
|
|
88
87
|
```
|
|
@@ -5,9 +5,9 @@ from wayfinder_paths.adapters.token_adapter.adapter import TokenAdapter
|
|
|
5
5
|
from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
|
|
6
6
|
from wayfinder_paths.core.clients.TokenClient import TokenClient
|
|
7
7
|
from wayfinder_paths.core.clients.WalletClient import WalletClient
|
|
8
|
-
from wayfinder_paths.core.
|
|
9
|
-
from wayfinder_paths.core.services.base import Web3Service
|
|
8
|
+
from wayfinder_paths.core.utils.erc20_service import build_send_transaction
|
|
10
9
|
from wayfinder_paths.core.utils.evm_helpers import resolve_chain_id
|
|
10
|
+
from wayfinder_paths.core.utils.transaction import send_transaction
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class BalanceAdapter(BaseAdapter):
|
|
@@ -16,17 +16,19 @@ class BalanceAdapter(BaseAdapter):
|
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
18
18
|
config: dict[str, Any],
|
|
19
|
-
|
|
19
|
+
simulation: bool = False,
|
|
20
|
+
main_wallet_signing_callback=None,
|
|
21
|
+
strategy_wallet_signing_callback=None,
|
|
20
22
|
):
|
|
21
23
|
super().__init__("balance", config)
|
|
24
|
+
self.simulation = simulation
|
|
25
|
+
self.main_wallet_signing_callback = main_wallet_signing_callback
|
|
26
|
+
self.strategy_wallet_signing_callback = strategy_wallet_signing_callback
|
|
22
27
|
self.wallet_client = WalletClient()
|
|
23
28
|
self.token_client = TokenClient()
|
|
24
29
|
self.token_adapter = TokenAdapter()
|
|
25
30
|
self.ledger_adapter = LedgerAdapter()
|
|
26
31
|
|
|
27
|
-
self.wallet_provider = web3_service.evm_transactions
|
|
28
|
-
self.token_transactions = web3_service.token_transactions
|
|
29
|
-
|
|
30
32
|
def _parse_balance(self, raw: Any) -> int:
|
|
31
33
|
"""Parse balance value to integer, handling various formats."""
|
|
32
34
|
if raw is None:
|
|
@@ -42,15 +44,23 @@ class BalanceAdapter(BaseAdapter):
|
|
|
42
44
|
async def get_balance(
|
|
43
45
|
self,
|
|
44
46
|
*,
|
|
45
|
-
query: str | dict[str, Any],
|
|
47
|
+
query: str | dict[str, Any] | None = None,
|
|
48
|
+
token_id: str | None = None,
|
|
46
49
|
wallet_address: str,
|
|
47
50
|
chain_id: int | None = None,
|
|
48
51
|
) -> tuple[bool, str | int]:
|
|
49
52
|
"""Get token or pool balance for a wallet.
|
|
50
53
|
|
|
51
54
|
query: token_id/address string or a dict with a "token_id" key.
|
|
55
|
+
token_id: alternative to query for convenience.
|
|
52
56
|
"""
|
|
53
|
-
|
|
57
|
+
# Support both query= and token_id= for caller convenience
|
|
58
|
+
effective_query = query if query is not None else token_id
|
|
59
|
+
resolved = (
|
|
60
|
+
effective_query
|
|
61
|
+
if isinstance(effective_query, str)
|
|
62
|
+
else (effective_query or {}).get("token_id")
|
|
63
|
+
)
|
|
54
64
|
if not resolved:
|
|
55
65
|
return (False, "missing query")
|
|
56
66
|
try:
|
|
@@ -119,15 +129,13 @@ class BalanceAdapter(BaseAdapter):
|
|
|
119
129
|
async def send_to_address(
|
|
120
130
|
self,
|
|
121
131
|
token_id: str,
|
|
122
|
-
amount:
|
|
132
|
+
amount: int,
|
|
123
133
|
from_wallet: dict[str, Any] | None,
|
|
124
134
|
to_address: str,
|
|
135
|
+
signing_callback=None,
|
|
125
136
|
skip_ledger: bool = True,
|
|
126
137
|
) -> tuple[bool, Any]:
|
|
127
138
|
"""Send tokens from a wallet to an arbitrary address (e.g., bridge contract)."""
|
|
128
|
-
if self.token_transactions is None:
|
|
129
|
-
return False, "Token transaction service not configured"
|
|
130
|
-
|
|
131
139
|
from_address = self._wallet_address(from_wallet)
|
|
132
140
|
if not from_address:
|
|
133
141
|
return False, "from_wallet missing or invalid"
|
|
@@ -139,22 +147,28 @@ class BalanceAdapter(BaseAdapter):
|
|
|
139
147
|
if not token_info:
|
|
140
148
|
return False, f"Token not found: {token_id}"
|
|
141
149
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
chain_id = resolve_chain_id(token_info, self.logger)
|
|
151
|
+
if chain_id is None:
|
|
152
|
+
return False, f"Token {token_id} is missing chain_id"
|
|
153
|
+
|
|
154
|
+
token_address = token_info.get("address")
|
|
155
|
+
|
|
156
|
+
tx = await build_send_transaction(
|
|
145
157
|
from_address=from_address,
|
|
146
158
|
to_address=to_address,
|
|
147
|
-
|
|
159
|
+
token_address=token_address,
|
|
160
|
+
chain_id=chain_id,
|
|
161
|
+
amount=int(amount),
|
|
148
162
|
)
|
|
149
|
-
if not build_success:
|
|
150
|
-
return False, tx_data
|
|
151
163
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
|
|
155
|
-
)
|
|
164
|
+
if self.simulation:
|
|
165
|
+
return True, {"simulation": tx}
|
|
156
166
|
|
|
157
|
-
|
|
167
|
+
if not signing_callback:
|
|
168
|
+
return False, "signing_callback is required"
|
|
169
|
+
|
|
170
|
+
tx_hash = await send_transaction(tx, signing_callback)
|
|
171
|
+
return True, tx_hash
|
|
158
172
|
|
|
159
173
|
async def _move_between_wallets(
|
|
160
174
|
self,
|
|
@@ -168,9 +182,6 @@ class BalanceAdapter(BaseAdapter):
|
|
|
168
182
|
strategy_name: str,
|
|
169
183
|
skip_ledger: bool,
|
|
170
184
|
) -> tuple[bool, Any]:
|
|
171
|
-
if self.token_transactions is None:
|
|
172
|
-
return False, "Token transaction service not configured"
|
|
173
|
-
|
|
174
185
|
from_address = self._wallet_address(from_wallet)
|
|
175
186
|
to_address = self._wallet_address(to_wallet)
|
|
176
187
|
if not from_address or not to_address:
|
|
@@ -180,20 +191,21 @@ class BalanceAdapter(BaseAdapter):
|
|
|
180
191
|
if not token_info:
|
|
181
192
|
return False, f"Token not found: {token_id}"
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
chain_id = resolve_chain_id(token_info, self.logger)
|
|
195
|
+
if chain_id is None:
|
|
196
|
+
return False, f"Token {token_id} is missing chain_id"
|
|
197
|
+
|
|
198
|
+
decimals = token_info.get("decimals", 18)
|
|
199
|
+
raw_amount = int(amount * (10**decimals))
|
|
200
|
+
|
|
201
|
+
tx = await build_send_transaction(
|
|
186
202
|
from_address=from_address,
|
|
187
203
|
to_address=to_address,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return False, tx_data
|
|
192
|
-
|
|
193
|
-
tx = tx_data
|
|
194
|
-
broadcast_result = await self.wallet_provider.broadcast_transaction(
|
|
195
|
-
tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
|
|
204
|
+
token_address=token_info.get("address"),
|
|
205
|
+
chain_id=chain_id,
|
|
206
|
+
amount=raw_amount,
|
|
196
207
|
)
|
|
208
|
+
broadcast_result = await self._send_tx(tx, from_address)
|
|
197
209
|
|
|
198
210
|
if broadcast_result[0] and not skip_ledger and ledger_method is not None:
|
|
199
211
|
wallet_for_ledger = from_address if ledger_wallet == "from" else to_address
|
|
@@ -207,6 +219,23 @@ class BalanceAdapter(BaseAdapter):
|
|
|
207
219
|
|
|
208
220
|
return broadcast_result
|
|
209
221
|
|
|
222
|
+
async def _send_tx(self, tx: dict[str, Any], from_address: str) -> tuple[bool, Any]:
|
|
223
|
+
"""Send transaction with simulation check, using appropriate signing callback."""
|
|
224
|
+
if self.simulation:
|
|
225
|
+
return True, {"simulation": tx}
|
|
226
|
+
|
|
227
|
+
# Choose callback based on which wallet is sending
|
|
228
|
+
main_wallet = self.config.get("main_wallet") or {}
|
|
229
|
+
main_addr = main_wallet.get("address", "").lower()
|
|
230
|
+
|
|
231
|
+
if from_address.lower() == main_addr:
|
|
232
|
+
callback = self.main_wallet_signing_callback
|
|
233
|
+
else:
|
|
234
|
+
callback = self.strategy_wallet_signing_callback
|
|
235
|
+
|
|
236
|
+
txn_hash = await send_transaction(tx, callback)
|
|
237
|
+
return True, txn_hash
|
|
238
|
+
|
|
210
239
|
async def _record_ledger_entry(
|
|
211
240
|
self,
|
|
212
241
|
*,
|
|
@@ -21,13 +21,7 @@ class TestBalanceAdapter:
|
|
|
21
21
|
return mock_client
|
|
22
22
|
|
|
23
23
|
@pytest.fixture
|
|
24
|
-
def
|
|
25
|
-
"""Mock TokenClient for testing"""
|
|
26
|
-
mock_client = AsyncMock()
|
|
27
|
-
return mock_client
|
|
28
|
-
|
|
29
|
-
@pytest.fixture
|
|
30
|
-
def adapter(self, mock_wallet_client, mock_token_client, mock_web3_service):
|
|
24
|
+
def adapter(self, mock_wallet_client, mock_token_client):
|
|
31
25
|
"""Create a BalanceAdapter instance with mocked clients for testing"""
|
|
32
26
|
with (
|
|
33
27
|
patch(
|
|
@@ -39,7 +33,7 @@ class TestBalanceAdapter:
|
|
|
39
33
|
return_value=mock_token_client,
|
|
40
34
|
),
|
|
41
35
|
):
|
|
42
|
-
return BalanceAdapter(config={}
|
|
36
|
+
return BalanceAdapter(config={})
|
|
43
37
|
|
|
44
38
|
@pytest.mark.asyncio
|
|
45
39
|
async def test_health_check(self, adapter):
|
{wayfinder_paths-0.1.15 → wayfinder_paths-0.1.17}/wayfinder_paths/adapters/brap_adapter/README.md
RENAMED
|
@@ -13,9 +13,8 @@ A Wayfinder adapter that provides high-level operations for cross-chain swaps an
|
|
|
13
13
|
|
|
14
14
|
## Configuration
|
|
15
15
|
|
|
16
|
-
The adapter uses the BRAPClient which automatically handles authentication and API configuration through the Wayfinder settings. Pass a `Web3Service` instance so it can broadcast transactions and reuse the shared `LocalTokenTxnService` for approvals.
|
|
17
|
-
|
|
18
16
|
The BRAPClient will automatically:
|
|
17
|
+
|
|
19
18
|
- Use the WAYFINDER_API_URL from settings
|
|
20
19
|
- Handle authentication via config.json
|
|
21
20
|
- Manage token refresh and retry logic
|
|
@@ -25,11 +24,9 @@ The BRAPClient will automatically:
|
|
|
25
24
|
### Initialize the Adapter
|
|
26
25
|
|
|
27
26
|
```python
|
|
28
|
-
from wayfinder_paths.core.services.web3_service import DefaultWeb3Service
|
|
29
27
|
from wayfinder_paths.adapters.brap_adapter.adapter import BRAPAdapter
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
adapter = BRAPAdapter(web3_service=web3_service)
|
|
29
|
+
adapter = BRAPAdapter()
|
|
33
30
|
```
|
|
34
31
|
|
|
35
32
|
### Get Swap Quote
|
|
@@ -46,9 +43,10 @@ success, data = await adapter.get_swap_quote(
|
|
|
46
43
|
slippage=0.01 # 1% slippage
|
|
47
44
|
)
|
|
48
45
|
if success:
|
|
49
|
-
|
|
46
|
+
quotes = data.get("quotes", {})
|
|
47
|
+
best_quote = quotes.get("best_quote", {})
|
|
50
48
|
print(f"Output amount: {best_quote.get('output_amount')}")
|
|
51
|
-
print(f"
|
|
49
|
+
print(f"Total fee: {best_quote.get('total_fee')}")
|
|
52
50
|
else:
|
|
53
51
|
print(f"Error: {data}")
|
|
54
52
|
```
|
|
@@ -67,7 +65,8 @@ success, data = await adapter.get_best_quote(
|
|
|
67
65
|
)
|
|
68
66
|
if success:
|
|
69
67
|
print(f"Best output: {data.get('output_amount')}")
|
|
70
|
-
print(f"
|
|
68
|
+
print(f"Gas fee: {data.get('gas_fee')}")
|
|
69
|
+
print(f"Bridge fee: {data.get('bridge_fee')}")
|
|
71
70
|
else:
|
|
72
71
|
print(f"Error: {data}")
|
|
73
72
|
```
|
|
@@ -86,8 +85,10 @@ success, data = await adapter.calculate_swap_fees(
|
|
|
86
85
|
if success:
|
|
87
86
|
print(f"Input amount: {data.get('input_amount')}")
|
|
88
87
|
print(f"Output amount: {data.get('output_amount')}")
|
|
89
|
-
print(f"Gas
|
|
90
|
-
print(f"
|
|
88
|
+
print(f"Gas fee: {data.get('gas_fee')}")
|
|
89
|
+
print(f"Bridge fee: {data.get('bridge_fee')}")
|
|
90
|
+
print(f"Protocol fee: {data.get('protocol_fee')}")
|
|
91
|
+
print(f"Total fee: {data.get('total_fee')}")
|
|
91
92
|
print(f"Price impact: {data.get('price_impact')}")
|
|
92
93
|
else:
|
|
93
94
|
print(f"Error: {data}")
|
|
@@ -106,9 +107,9 @@ success, data = await adapter.compare_routes(
|
|
|
106
107
|
if success:
|
|
107
108
|
print(f"Total routes available: {data.get('total_routes')}")
|
|
108
109
|
print(f"Best route output: {data.get('best_route', {}).get('output_amount')}")
|
|
109
|
-
|
|
110
|
+
|
|
110
111
|
for i, route in enumerate(data.get('all_routes', [])):
|
|
111
|
-
print(f
|
|
112
|
+
print(f"Route {i+1}: Output {route.get('output_amount')}, Fee {route.get('total_fee')}")
|
|
112
113
|
else:
|
|
113
114
|
print(f"Error: {data}")
|
|
114
115
|
```
|
|
@@ -166,7 +167,7 @@ success, data = await adapter.get_bridge_quote(
|
|
|
166
167
|
slippage=0.01
|
|
167
168
|
)
|
|
168
169
|
if success:
|
|
169
|
-
print(f"Bridge quote received: {data.get('best_quote', {}).get('output_amount')}")
|
|
170
|
+
print(f"Bridge quote received: {data.get('quotes', {}).get('best_quote', {}).get('output_amount')}")
|
|
170
171
|
else:
|
|
171
172
|
print(f"Error: {data}")
|
|
172
173
|
```
|
|
@@ -190,9 +191,10 @@ if success:
|
|
|
190
191
|
highest_output = analysis.get("highest_output")
|
|
191
192
|
lowest_fees = analysis.get("lowest_fees")
|
|
192
193
|
fastest = analysis.get("fastest")
|
|
193
|
-
|
|
194
|
+
|
|
194
195
|
print(f"Highest output route: {highest_output.get('output_amount')}")
|
|
195
|
-
print(f
|
|
196
|
+
print(f"Lowest fees route: {lowest_fees.get('total_fee')}")
|
|
197
|
+
print(f"Fastest route: {fastest.get('estimated_time')} seconds")
|
|
196
198
|
```
|
|
197
199
|
|
|
198
200
|
### Fee Analysis
|
|
@@ -210,23 +212,24 @@ success, data = await adapter.calculate_swap_fees(
|
|
|
210
212
|
if success:
|
|
211
213
|
input_amount = int(data.get("input_amount", 0))
|
|
212
214
|
output_amount = int(data.get("output_amount", 0))
|
|
213
|
-
|
|
214
|
-
|
|
215
|
+
total_fee = int(data.get("total_fee", 0))
|
|
216
|
+
|
|
215
217
|
# Calculate effective rate
|
|
216
218
|
effective_rate = (input_amount - output_amount) / input_amount
|
|
217
219
|
print(f"Effective rate: {effective_rate:.4f} ({effective_rate * 100:.2f}%)")
|
|
218
|
-
print(f"Total fees:
|
|
220
|
+
print(f"Total fees: {total_fee / 1e18:.6f} tokens")
|
|
219
221
|
```
|
|
220
222
|
|
|
221
223
|
## API Endpoints
|
|
222
224
|
|
|
223
225
|
The adapter uses the following Wayfinder API endpoints:
|
|
224
226
|
|
|
225
|
-
- `
|
|
227
|
+
- `POST /api/v1/public/quotes/` - Get swap/bridge quotes
|
|
226
228
|
|
|
227
229
|
## Error Handling
|
|
228
230
|
|
|
229
231
|
All methods return a tuple of `(success: bool, data: Any)` where:
|
|
232
|
+
|
|
230
233
|
- `success` is `True` if the operation succeeded
|
|
231
234
|
- `data` contains the response data on success or error message on failure
|
|
232
235
|
|