wayfinder-paths 0.1.11__py3-none-any.whl → 0.1.14__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.
Potentially problematic release.
This version of wayfinder-paths might be problematic. Click here for more details.
- wayfinder_paths/adapters/balance_adapter/README.md +13 -14
- wayfinder_paths/adapters/balance_adapter/adapter.py +36 -39
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +123 -0
- wayfinder_paths/adapters/brap_adapter/README.md +11 -16
- wayfinder_paths/adapters/brap_adapter/adapter.py +87 -75
- wayfinder_paths/adapters/brap_adapter/examples.json +63 -52
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +121 -59
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +22 -23
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +114 -60
- wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +1 -1
- wayfinder_paths/adapters/hyperliquid_adapter/executor.py +44 -5
- wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +104 -0
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +0 -3
- wayfinder_paths/adapters/pool_adapter/README.md +11 -27
- wayfinder_paths/adapters/pool_adapter/adapter.py +11 -37
- wayfinder_paths/adapters/pool_adapter/examples.json +6 -7
- wayfinder_paths/adapters/pool_adapter/test_adapter.py +8 -8
- wayfinder_paths/adapters/token_adapter/README.md +2 -14
- wayfinder_paths/adapters/token_adapter/adapter.py +16 -10
- wayfinder_paths/adapters/token_adapter/examples.json +4 -8
- wayfinder_paths/adapters/token_adapter/test_adapter.py +5 -3
- wayfinder_paths/core/clients/BRAPClient.py +103 -62
- wayfinder_paths/core/clients/ClientManager.py +1 -68
- wayfinder_paths/core/clients/HyperlendClient.py +127 -66
- wayfinder_paths/core/clients/LedgerClient.py +1 -4
- wayfinder_paths/core/clients/PoolClient.py +126 -88
- wayfinder_paths/core/clients/TokenClient.py +92 -37
- wayfinder_paths/core/clients/WalletClient.py +28 -58
- wayfinder_paths/core/clients/WayfinderClient.py +33 -166
- wayfinder_paths/core/clients/__init__.py +0 -2
- wayfinder_paths/core/clients/protocols.py +35 -52
- wayfinder_paths/core/clients/sdk_example.py +37 -22
- wayfinder_paths/core/config.py +60 -224
- wayfinder_paths/core/engine/StrategyJob.py +7 -55
- wayfinder_paths/core/services/local_evm_txn.py +28 -10
- wayfinder_paths/core/services/local_token_txn.py +1 -1
- wayfinder_paths/core/strategies/Strategy.py +3 -5
- wayfinder_paths/core/strategies/descriptors.py +7 -0
- wayfinder_paths/core/utils/evm_helpers.py +7 -3
- wayfinder_paths/core/utils/wallets.py +12 -19
- wayfinder_paths/core/wallets/README.md +1 -1
- wayfinder_paths/run_strategy.py +8 -17
- wayfinder_paths/scripts/create_strategy.py +5 -5
- wayfinder_paths/scripts/make_wallets.py +5 -5
- wayfinder_paths/scripts/run_strategy.py +3 -3
- wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -1
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +206 -526
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +228 -11
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -2
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +41 -25
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +54 -9
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +1 -1
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +10 -9
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +12 -6
- wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +3 -3
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +110 -78
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +44 -21
- wayfinder_paths/templates/adapter/README.md +1 -1
- wayfinder_paths/templates/strategy/README.md +3 -3
- wayfinder_paths/templates/strategy/test_strategy.py +3 -2
- {wayfinder_paths-0.1.11.dist-info → wayfinder_paths-0.1.14.dist-info}/METADATA +21 -59
- {wayfinder_paths-0.1.11.dist-info → wayfinder_paths-0.1.14.dist-info}/RECORD +64 -65
- wayfinder_paths/core/clients/AuthClient.py +0 -83
- wayfinder_paths/core/settings.py +0 -61
- {wayfinder_paths-0.1.11.dist-info → wayfinder_paths-0.1.14.dist-info}/LICENSE +0 -0
- {wayfinder_paths-0.1.11.dist-info → wayfinder_paths-0.1.14.dist-info}/WHEEL +0 -0
|
@@ -52,7 +52,10 @@ def strategy():
|
|
|
52
52
|
usdc_balance_mock = AsyncMock(return_value=(True, 60000000))
|
|
53
53
|
gas_balance_mock = AsyncMock(return_value=(True, 2000000000000000))
|
|
54
54
|
|
|
55
|
-
def get_balance_side_effect(
|
|
55
|
+
def get_balance_side_effect(query, wallet_address, **kwargs):
|
|
56
|
+
token_id = (
|
|
57
|
+
query if isinstance(query, str) else (query or {}).get("token_id")
|
|
58
|
+
)
|
|
56
59
|
if token_id == "usd-coin-base" or token_id == "usd-coin":
|
|
57
60
|
return usdc_balance_mock.return_value
|
|
58
61
|
elif token_id == "ethereum-base" or token_id == "ethereum":
|
|
@@ -121,9 +124,8 @@ def strategy():
|
|
|
121
124
|
)
|
|
122
125
|
|
|
123
126
|
if hasattr(s, "ledger_adapter") and s.ledger_adapter:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
127
|
+
# NOTE: The real LedgerClient returns float, not dict!
|
|
128
|
+
s.ledger_adapter.get_strategy_net_deposit = AsyncMock(return_value=(True, 0.0))
|
|
127
129
|
s.ledger_adapter.get_strategy_transactions = AsyncMock(
|
|
128
130
|
return_value=(True, {"transactions": []})
|
|
129
131
|
)
|
|
@@ -135,21 +137,21 @@ def strategy():
|
|
|
135
137
|
{"pools": [{"id": "test-pool-base", "apy": 15.0, "symbol": "POOL"}]},
|
|
136
138
|
)
|
|
137
139
|
)
|
|
138
|
-
s.pool_adapter.
|
|
140
|
+
s.pool_adapter.get_pools = AsyncMock(
|
|
139
141
|
return_value=(
|
|
140
142
|
True,
|
|
141
143
|
{
|
|
142
144
|
"matches": [
|
|
143
145
|
{
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
"
|
|
146
|
+
"stablecoin": True,
|
|
147
|
+
"ilRisk": "no",
|
|
148
|
+
"tvlUsd": 2000000,
|
|
149
|
+
"apy": 5.0,
|
|
148
150
|
"network": "base",
|
|
149
151
|
"address": "0x1234567890123456789012345678901234567890",
|
|
150
152
|
"token_id": "test-pool-base",
|
|
151
153
|
"pool_id": "test-pool-base",
|
|
152
|
-
"
|
|
154
|
+
"combined_apy_pct": 15.0,
|
|
153
155
|
}
|
|
154
156
|
]
|
|
155
157
|
},
|
|
@@ -450,7 +452,8 @@ async def test_sweep_wallet_uses_tracked_tokens(strategy):
|
|
|
450
452
|
assert "token-2" in strategy.tracked_token_ids
|
|
451
453
|
|
|
452
454
|
# Mock balance adapter to return fresh balances
|
|
453
|
-
async def get_balance_mock(
|
|
455
|
+
async def get_balance_mock(query, **kwargs):
|
|
456
|
+
token_id = query if isinstance(query, str) else (query or {}).get("token_id")
|
|
454
457
|
balance = strategy.tracked_balances.get(token_id, 0)
|
|
455
458
|
# Return the balance, ensuring it's an int
|
|
456
459
|
return (True, int(balance) if balance else 0)
|
|
@@ -496,12 +499,11 @@ async def test_get_non_gas_balances_uses_tracked_state(strategy):
|
|
|
496
499
|
strategy._track_token(pool_token_id, 50000000000000000000)
|
|
497
500
|
|
|
498
501
|
# Mock refresh
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
)
|
|
502
|
+
def _get_balance_effect(query, **kwargs):
|
|
503
|
+
token_id = query if isinstance(query, str) else (query or {}).get("token_id")
|
|
504
|
+
return (True, strategy.tracked_balances.get(token_id, 0))
|
|
505
|
+
|
|
506
|
+
strategy.balance_adapter.get_balance = AsyncMock(side_effect=_get_balance_effect)
|
|
505
507
|
|
|
506
508
|
# Get non-gas balances
|
|
507
509
|
balances = await strategy._get_non_gas_balances()
|
|
@@ -520,11 +522,12 @@ async def test_partial_liquidate_uses_tracked_tokens(strategy):
|
|
|
520
522
|
strategy._track_token("test-pool-base", 100000000000000000000) # 100 POOL tokens
|
|
521
523
|
|
|
522
524
|
# Mock balance and token adapters
|
|
525
|
+
def _get_balance_effect_partial(query, **kwargs):
|
|
526
|
+
token_id = query if isinstance(query, str) else (query or {}).get("token_id")
|
|
527
|
+
return (True, strategy.tracked_balances.get(token_id, 0))
|
|
528
|
+
|
|
523
529
|
strategy.balance_adapter.get_balance = AsyncMock(
|
|
524
|
-
side_effect=
|
|
525
|
-
True,
|
|
526
|
-
strategy.tracked_balances.get(token_id, 0),
|
|
527
|
-
)
|
|
530
|
+
side_effect=_get_balance_effect_partial
|
|
528
531
|
)
|
|
529
532
|
|
|
530
533
|
strategy.token_adapter.get_token_price = AsyncMock(
|
|
@@ -541,3 +544,23 @@ async def test_partial_liquidate_uses_tracked_tokens(strategy):
|
|
|
541
544
|
# Verify success
|
|
542
545
|
assert ok
|
|
543
546
|
assert "liquidation completed" in msg.lower()
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
@pytest.mark.asyncio
|
|
550
|
+
async def test_setup_handles_float_net_deposit(strategy):
|
|
551
|
+
"""Test that setup() correctly handles float from get_strategy_net_deposit.
|
|
552
|
+
|
|
553
|
+
The ledger adapter returns (success, float) not (success, dict).
|
|
554
|
+
This test ensures the strategy doesn't try to call .get() on the float,
|
|
555
|
+
which would raise "'float' object has no attribute 'get'".
|
|
556
|
+
"""
|
|
557
|
+
# Mock get_strategy_net_deposit to return float (not dict)
|
|
558
|
+
strategy.ledger_adapter.get_strategy_net_deposit = AsyncMock(
|
|
559
|
+
return_value=(True, 1500.0)
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
# Run setup - should not raise AttributeError
|
|
563
|
+
await strategy.setup()
|
|
564
|
+
|
|
565
|
+
# Verify DEPOSIT_USDC was set from the float
|
|
566
|
+
assert strategy.DEPOSIT_USDC == 1500.0
|
|
@@ -46,7 +46,7 @@ class MyAdapter(BaseAdapter):
|
|
|
46
46
|
"""Example capability that proxies PoolClient."""
|
|
47
47
|
try:
|
|
48
48
|
data = await self.pool_client.get_pools_by_ids(
|
|
49
|
-
pool_ids=
|
|
49
|
+
pool_ids=pool_ids
|
|
50
50
|
)
|
|
51
51
|
return (True, data)
|
|
52
52
|
except Exception as exc: # noqa: BLE001
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# Strategy Template
|
|
2
2
|
|
|
3
3
|
This template provides the scaffolding for a new strategy. It mirrors the structure in `wayfinder_paths/strategies/...`.
|
|
4
4
|
|
|
@@ -70,7 +70,7 @@ class MyStrategy(Strategy):
|
|
|
70
70
|
return (False, "Nothing to deposit")
|
|
71
71
|
|
|
72
72
|
success, _ = await self.balance_adapter.get_balance(
|
|
73
|
-
|
|
73
|
+
query=self.config.get("token_id"),
|
|
74
74
|
wallet_address=self.config.get("main_wallet", {}).get("address"),
|
|
75
75
|
)
|
|
76
76
|
if not success:
|
|
@@ -87,7 +87,7 @@ class MyStrategy(Strategy):
|
|
|
87
87
|
async def _status(self) -> StatusDict:
|
|
88
88
|
"""Surface state back to run_strategy.py."""
|
|
89
89
|
success, balance = await self.balance_adapter.get_balance(
|
|
90
|
-
|
|
90
|
+
query=self.config.get("token_id"),
|
|
91
91
|
wallet_address=self.config.get("strategy_wallet", {}).get("address"),
|
|
92
92
|
)
|
|
93
93
|
return {
|
|
@@ -66,14 +66,15 @@ def strategy():
|
|
|
66
66
|
# usdc_balance_mock = AsyncMock(return_value=(True, 60000000))
|
|
67
67
|
# gas_balance_mock = AsyncMock(return_value=(True, 2000000000000000))
|
|
68
68
|
#
|
|
69
|
-
# def get_balance_side_effect(
|
|
69
|
+
# def get_balance_side_effect(query, wallet_address, **kwargs):
|
|
70
|
+
# token_id = query if isinstance(query, str) else (query or {}).get("token_id")
|
|
70
71
|
# if token_id == "usd-coin-base" or token_id == "usd-coin":
|
|
71
72
|
# return usdc_balance_mock.return_value
|
|
72
73
|
# elif token_id == "ethereum-base" or token_id == "ethereum":
|
|
73
74
|
# return gas_balance_mock.return_value
|
|
74
75
|
# return (True, 1000000000)
|
|
75
76
|
#
|
|
76
|
-
# s.balance_adapter.
|
|
77
|
+
# s.balance_adapter.get_balance = AsyncMock(
|
|
77
78
|
# side_effect=get_balance_side_effect
|
|
78
79
|
# )
|
|
79
80
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wayfinder-paths
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: Wayfinder Path: strategies and adapters
|
|
5
5
|
Author: Wayfinder
|
|
6
6
|
Author-email: dev@wayfinder.ai
|
|
@@ -15,8 +15,6 @@ Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
|
|
15
15
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
16
16
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
|
17
17
|
Requires-Dist: pydantic (>=2.11.9,<3.0.0)
|
|
18
|
-
Requires-Dist: pydantic-settings (>=2.7.0,<3.0.0)
|
|
19
|
-
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
20
18
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
21
19
|
Requires-Dist: web3 (>=7.13.0,<8.0.0)
|
|
22
20
|
Description-Content-Type: text/markdown
|
|
@@ -43,7 +41,7 @@ curl -sSL https://install.python-poetry.org | python3 -
|
|
|
43
41
|
poetry install
|
|
44
42
|
|
|
45
43
|
# ⚠️ Generate test wallets FIRST (required!)
|
|
46
|
-
# This creates
|
|
44
|
+
# This creates config.json with a main wallet for local testing
|
|
47
45
|
just create-wallets
|
|
48
46
|
# Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
|
|
49
47
|
|
|
@@ -92,8 +90,7 @@ wayfinder_paths/
|
|
|
92
90
|
│ ├── config.example.json # Example configuration
|
|
93
91
|
│ ├── scripts/ # Utility scripts
|
|
94
92
|
│ └── run_strategy.py # Strategy runner script
|
|
95
|
-
├── config.json # Your local config
|
|
96
|
-
├── wallets.json # Generated dev wallets
|
|
93
|
+
├── config.json # Your local config with credentials and wallets
|
|
97
94
|
├── pyproject.toml # Poetry configuration
|
|
98
95
|
└── README.md # This file
|
|
99
96
|
```
|
|
@@ -219,63 +216,28 @@ See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
|
|
|
219
216
|
|
|
220
217
|
### Authentication
|
|
221
218
|
|
|
222
|
-
Wayfinder Paths
|
|
219
|
+
Wayfinder Paths uses API key authentication via the `X-API-KEY` header.
|
|
223
220
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
For backend services and automated systems with higher rate limits:
|
|
227
|
-
|
|
228
|
-
**Option A: Pass to Strategy Constructor**
|
|
229
|
-
|
|
230
|
-
```python
|
|
231
|
-
from wayfinder_paths.strategies.stablecoin_yield_strategy.strategy import StablecoinYieldStrategy
|
|
232
|
-
|
|
233
|
-
strategy = StablecoinYieldStrategy(
|
|
234
|
-
config={...},
|
|
235
|
-
api_key="sk_live_abc123..." # API key is auto-discovered by all clients
|
|
236
|
-
)
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
**Option B: Add to config.json**
|
|
221
|
+
**Add API key to config.json:**
|
|
240
222
|
|
|
241
223
|
```json
|
|
242
224
|
{
|
|
243
|
-
"user": {
|
|
244
|
-
"api_key": "sk_live_abc123..."
|
|
245
|
-
},
|
|
246
225
|
"system": {
|
|
247
|
-
"api_key": "sk_live_abc123..."
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Priority Order:** Constructor parameter > `config.json` (user.api_key or system.api_key)
|
|
253
|
-
|
|
254
|
-
**Note:** API keys in `config.json` are loaded directly by `WayfinderClient` via `_load_config_credentials()`, not through the `UserConfig` or `SystemConfig` dataclasses. This allows flexible credential loading.
|
|
255
|
-
|
|
256
|
-
#### 2. Personal Access Authentication (OAuth)
|
|
257
|
-
|
|
258
|
-
For standalone SDK users with username/password:
|
|
259
|
-
|
|
260
|
-
```json
|
|
261
|
-
{
|
|
262
|
-
"user": {
|
|
263
|
-
"username": "your_username",
|
|
264
|
-
"password": "your_password",
|
|
265
|
-
"refresh_token": null // Optional: use refresh token instead
|
|
226
|
+
"api_key": "sk_live_abc123...",
|
|
227
|
+
"api_base_url": "https://wayfinder.ai/api/v1",
|
|
228
|
+
"wallets_path": "wallets.json"
|
|
266
229
|
}
|
|
267
230
|
}
|
|
268
231
|
```
|
|
269
232
|
|
|
270
233
|
**How It Works:**
|
|
271
234
|
|
|
272
|
-
- API
|
|
273
|
-
-
|
|
274
|
-
-
|
|
275
|
-
-
|
|
276
|
-
- API keys in `config.json` are loaded directly by `WayfinderClient._load_config_credentials()` from `user.api_key` or `system.api_key`, not stored in the `UserConfig` or `SystemConfig` dataclasses
|
|
235
|
+
- API key is automatically loaded from `system.api_key` in config.json
|
|
236
|
+
- The API key is sent as the `X-API-KEY` header on all API requests
|
|
237
|
+
- All clients automatically include the API key header
|
|
238
|
+
- No need to pass API keys explicitly to strategies or clients
|
|
277
239
|
|
|
278
|
-
See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for detailed
|
|
240
|
+
See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for detailed configuration documentation.
|
|
279
241
|
|
|
280
242
|
## 🔌 Creating Adapters
|
|
281
243
|
|
|
@@ -302,7 +264,7 @@ class MyAdapter(BaseAdapter):
|
|
|
302
264
|
|
|
303
265
|
async def get_pools(self, pool_ids: list[str]):
|
|
304
266
|
data = await self.pool_client.get_pools_by_ids(
|
|
305
|
-
pool_ids=
|
|
267
|
+
pool_ids=pool_ids
|
|
306
268
|
)
|
|
307
269
|
return (True, data)
|
|
308
270
|
```
|
|
@@ -343,7 +305,7 @@ class MyStrategy(Strategy):
|
|
|
343
305
|
return (False, "Nothing to deposit")
|
|
344
306
|
|
|
345
307
|
success, _ = await self.balance_adapter.get_balance(
|
|
346
|
-
|
|
308
|
+
query=self.config.get("token_id"),
|
|
347
309
|
wallet_address=self.config.get("main_wallet", {}).get("address"),
|
|
348
310
|
)
|
|
349
311
|
if not success:
|
|
@@ -360,7 +322,7 @@ class MyStrategy(Strategy):
|
|
|
360
322
|
async def _status(self) -> StatusDict:
|
|
361
323
|
"""Report balances back to the runner"""
|
|
362
324
|
success, balance = await self.balance_adapter.get_balance(
|
|
363
|
-
|
|
325
|
+
query=self.config.get("token_id"),
|
|
364
326
|
wallet_address=self.config.get("strategy_wallet", {}).get("address"),
|
|
365
327
|
)
|
|
366
328
|
return {
|
|
@@ -491,7 +453,7 @@ poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --de
|
|
|
491
453
|
|
|
492
454
|
### Wallet Generation for Testing
|
|
493
455
|
|
|
494
|
-
**Before running any strategies, generate test wallets.** This creates `
|
|
456
|
+
**Before running any strategies, generate test wallets.** This creates `config.json` in the repository root with throwaway wallets for local testing:
|
|
495
457
|
|
|
496
458
|
```bash
|
|
497
459
|
# Essential: Create main wallet for testing
|
|
@@ -501,8 +463,8 @@ just create-wallets
|
|
|
501
463
|
|
|
502
464
|
This creates:
|
|
503
465
|
|
|
504
|
-
- `main` wallet - your main wallet for testing (labeled "main" in
|
|
505
|
-
- `
|
|
466
|
+
- `main` wallet - your main wallet for testing (labeled "main" in config.json)
|
|
467
|
+
- `config.json` - wallet addresses and private keys for local testing
|
|
506
468
|
|
|
507
469
|
**Note:** Strategy-specific wallets are automatically created when you use `just create-strategy "Strategy Name"`. For manual creation, use `just create-wallet "strategy_name"` or `poetry run python wayfinder_paths/scripts/make_wallets.py --label "strategy_name"`.
|
|
508
470
|
|
|
@@ -538,9 +500,9 @@ cp wayfinder_paths/config.example.json config.json
|
|
|
538
500
|
# - user.username: Your Wayfinder username
|
|
539
501
|
# - user.password: Your Wayfinder password
|
|
540
502
|
# - OR user.refresh_token: Your refresh token
|
|
541
|
-
# - system.wallets_path: Path to
|
|
503
|
+
# - system.wallets_path: Path to config.json (default: "config.json")
|
|
542
504
|
#
|
|
543
|
-
# Wallet addresses are auto-loaded from
|
|
505
|
+
# Wallet addresses are auto-loaded from config.json by default.
|
|
544
506
|
# Then run with:
|
|
545
507
|
poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config config.json
|
|
546
508
|
```
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
wayfinder_paths/__init__.py,sha256=YgOg-PRPT3ROh0zg6hgQyQE-YFkFGw6TM77zDvB4_sE,427
|
|
2
2
|
wayfinder_paths/abis/generic/erc20.json,sha256=geyzVzdTNt3u1XHKxi4seszP_GIWIzPTl0FYgiftRnM,9336
|
|
3
3
|
wayfinder_paths/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
wayfinder_paths/adapters/balance_adapter/README.md,sha256=
|
|
5
|
-
wayfinder_paths/adapters/balance_adapter/adapter.py,sha256=
|
|
4
|
+
wayfinder_paths/adapters/balance_adapter/README.md,sha256=VCBvhAzgWayVgRZonwAB0oMIip1iXvRWb0cYSmeDmPI,3789
|
|
5
|
+
wayfinder_paths/adapters/balance_adapter/adapter.py,sha256=OzhnMfB1z7BgCKaXv7Yp4Hdl2Ny2LZ6Yzjz51-Ur3EM,8580
|
|
6
6
|
wayfinder_paths/adapters/balance_adapter/examples.json,sha256=3R1M4B_VsIy29viAuFT9nQbnQShWl8ZbU-rnSNWUW9U,129
|
|
7
|
-
wayfinder_paths/adapters/balance_adapter/test_adapter.py,sha256=
|
|
8
|
-
wayfinder_paths/adapters/brap_adapter/README.md,sha256=
|
|
7
|
+
wayfinder_paths/adapters/balance_adapter/test_adapter.py,sha256=slCRF6JlLSbLAUyPYQsl19KxwSgrF9853O7XOPyUPNY,6311
|
|
8
|
+
wayfinder_paths/adapters/brap_adapter/README.md,sha256=eOWIwAPdaBuvPCmT_E4myucUSvgupvvQQKDcptgRluw,7756
|
|
9
9
|
wayfinder_paths/adapters/brap_adapter/__init__.py,sha256=jpqxZ-Bv_8kBo-lhgO_QCWaVZNq_WwlkNBHD4RsqOJg,90
|
|
10
|
-
wayfinder_paths/adapters/brap_adapter/adapter.py,sha256=
|
|
11
|
-
wayfinder_paths/adapters/brap_adapter/examples.json,sha256=
|
|
12
|
-
wayfinder_paths/adapters/brap_adapter/test_adapter.py,sha256=
|
|
10
|
+
wayfinder_paths/adapters/brap_adapter/adapter.py,sha256=rTy4g6-_pkP61o-plTNBIb7j1phB5xX7lmaYadtYAfE,30446
|
|
11
|
+
wayfinder_paths/adapters/brap_adapter/examples.json,sha256=FGZhNaMCAQ56KhovEGSsV1BHOcMd_QqQBNmCU6m8zfQ,5389
|
|
12
|
+
wayfinder_paths/adapters/brap_adapter/test_adapter.py,sha256=qIPPHk1_WGKYSFndWC-CzHE7z1OvM8hNVypvFNV_lG4,12848
|
|
13
13
|
wayfinder_paths/adapters/hyperlend_adapter/__init__.py,sha256=DsWOnEn-Tlu9ZoIoGaFeSqOYI3b4lXGVK3_FTntWpLw,139
|
|
14
|
-
wayfinder_paths/adapters/hyperlend_adapter/adapter.py,sha256=
|
|
15
|
-
wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py,sha256=
|
|
14
|
+
wayfinder_paths/adapters/hyperlend_adapter/adapter.py,sha256=DtdKzi8dDTBZdzbddIDuzJXWF_NOvOG_EtfxE6taTGY,10013
|
|
15
|
+
wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py,sha256=7QYUh0xEQd2dDyt069abHjSduVPtPXAL5q_TNeQXk_4,12152
|
|
16
16
|
wayfinder_paths/adapters/hyperliquid_adapter/__init__.py,sha256=QpA258RzVbxzsha86HQduAuNVG0g0qvsI5OcZunQ8DQ,467
|
|
17
|
-
wayfinder_paths/adapters/hyperliquid_adapter/adapter.py,sha256=
|
|
18
|
-
wayfinder_paths/adapters/hyperliquid_adapter/executor.py,sha256=
|
|
17
|
+
wayfinder_paths/adapters/hyperliquid_adapter/adapter.py,sha256=Z5Gl9M9wk7PVUIyP_i2oAMegmCTbVFd48Zp57DURh6M,34510
|
|
18
|
+
wayfinder_paths/adapters/hyperliquid_adapter/executor.py,sha256=ix1FmRO6DPiPk0BwGy4zrCP5IfKzzMSQNhnOmIewfGA,18977
|
|
19
19
|
wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py,sha256=nOBsrAka8PKv5h8SuoJuLTH4HYS4n0vpTIADUCyDKlA,37546
|
|
20
20
|
wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py,sha256=JEDeIMSTdrgcSy4BGSVB0CixQzl3NsKpukOZ9mRu3kE,4542
|
|
21
21
|
wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py,sha256=lnlL0njECM6C4hVlsEZ4_7wtcixIBO8qqTRO6b1yGGg,7672
|
|
22
|
+
wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py,sha256=6tAstfO2fFTWWYSqYsd3jzY5iQ1RrCsLl_0pbwJO-bE,4147
|
|
22
23
|
wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py,sha256=2gSrXJgtfrTqNOQIhBS92vUkfcwhFsMLgFRkf1bzLy8,7290
|
|
23
24
|
wayfinder_paths/adapters/hyperliquid_adapter/utils.py,sha256=WjLEaNVvcB8FfYlTrwZBrmw7k2MLS5KhBeW4NNoLlVI,4254
|
|
24
25
|
wayfinder_paths/adapters/ledger_adapter/README.md,sha256=_tGIpIkg-TCYddf8d4FhJvJuHV79iTizqePosKX2ekU,4079
|
|
@@ -28,18 +29,18 @@ wayfinder_paths/adapters/ledger_adapter/examples.json,sha256=DdqTSe4vnBrfIycQVQQ
|
|
|
28
29
|
wayfinder_paths/adapters/ledger_adapter/test_adapter.py,sha256=Z1-rPP9k5fI-8ofWMKgU3syzNegKGH_hGO6CKApQj1c,7470
|
|
29
30
|
wayfinder_paths/adapters/moonwell_adapter/README.md,sha256=PyQllVXgW0aUUoWhAZ5phLPAxtR9A5GkwesnZznckV8,5465
|
|
30
31
|
wayfinder_paths/adapters/moonwell_adapter/__init__.py,sha256=Gf6AM4BylxxPenUQ_cveUg70QcB9i61SIYaCsXMSjXw,135
|
|
31
|
-
wayfinder_paths/adapters/moonwell_adapter/adapter.py,sha256=
|
|
32
|
+
wayfinder_paths/adapters/moonwell_adapter/adapter.py,sha256=kpzuIEUQHHo8WUkt-XGO5FqMtPBRNubYqkkWT0jKvKM,45030
|
|
32
33
|
wayfinder_paths/adapters/moonwell_adapter/test_adapter.py,sha256=DLbbCW6ytjKY2C5aQUrW-YBFyrXjush9qbGWiuL42DM,23440
|
|
33
|
-
wayfinder_paths/adapters/pool_adapter/README.md,sha256=
|
|
34
|
+
wayfinder_paths/adapters/pool_adapter/README.md,sha256=cBeWz8UzOOIKCkyBUDGTujR1vZNPyhgqKO2HNgq0j3I,2470
|
|
34
35
|
wayfinder_paths/adapters/pool_adapter/__init__.py,sha256=rv56pYzz2Gqiz33uoPJktCQRe3CRt8U9ry5GbjVgK3A,90
|
|
35
|
-
wayfinder_paths/adapters/pool_adapter/adapter.py,sha256
|
|
36
|
-
wayfinder_paths/adapters/pool_adapter/examples.json,sha256=
|
|
37
|
-
wayfinder_paths/adapters/pool_adapter/test_adapter.py,sha256=
|
|
38
|
-
wayfinder_paths/adapters/token_adapter/README.md,sha256=
|
|
36
|
+
wayfinder_paths/adapters/pool_adapter/adapter.py,sha256=zHYCcCjum3jJpG4BZnTJ8YuOyI9ZJlSN5r8TMO4KCDM,1806
|
|
37
|
+
wayfinder_paths/adapters/pool_adapter/examples.json,sha256=NW-7J6_zXxky8uMDRym3jJaPP8hZLEiytQ3WKoZEP54,855
|
|
38
|
+
wayfinder_paths/adapters/pool_adapter/test_adapter.py,sha256=jz3QYP8ubHjIfE4Sz7CMQai_7zqG9IJBjXz7CKC0PU0,2625
|
|
39
|
+
wayfinder_paths/adapters/token_adapter/README.md,sha256=mvsfm1fZDsNim4A_H0o54l4y4BNH9mxDu2UB_mNz1xw,2338
|
|
39
40
|
wayfinder_paths/adapters/token_adapter/__init__.py,sha256=nEmxrvffEygn3iKH3cZTNLkhnUUhlUAEtshmrFRAjq8,62
|
|
40
|
-
wayfinder_paths/adapters/token_adapter/adapter.py,sha256=
|
|
41
|
-
wayfinder_paths/adapters/token_adapter/examples.json,sha256=
|
|
42
|
-
wayfinder_paths/adapters/token_adapter/test_adapter.py,sha256=
|
|
41
|
+
wayfinder_paths/adapters/token_adapter/adapter.py,sha256=aAfcMpxlG5W9UbYQ4mPks0o7A1KsrYyMZzWw-1dQz8Q,3729
|
|
42
|
+
wayfinder_paths/adapters/token_adapter/examples.json,sha256=bvwP9XL9c_endFlMQgkavXh_IzNEEUyJd4gh5QjrcqY,2944
|
|
43
|
+
wayfinder_paths/adapters/token_adapter/test_adapter.py,sha256=k3N_em0cgkyL_k3YF6W17trDten8nD5hoE1Tpx9OJC8,4505
|
|
43
44
|
wayfinder_paths/conftest.py,sha256=pqDNijXn9_zmbAdkt_2a18UQLjtsDkNTBJVTgC6H2nA,1136
|
|
44
45
|
wayfinder_paths/core/__init__.py,sha256=AJK8oS2dCVuJ2pmSxqXOCvuWacNaVEU3yALEqsD3rog,398
|
|
45
46
|
wayfinder_paths/core/adapters/BaseAdapter.py,sha256=bzc3ER7aKOsmk9cxyoJxGdI54eibbpcMC8nGYJUrsp0,2033
|
|
@@ -50,40 +51,38 @@ wayfinder_paths/core/analytics/__init__.py,sha256=AtcSpt2vPpCNgdDaFDLhyZZpKa0QXK
|
|
|
50
51
|
wayfinder_paths/core/analytics/bootstrap.py,sha256=lb_PjL4Vh3O2F8eXgvAbnAFevJczRF59ODG-dxtpCZ8,1782
|
|
51
52
|
wayfinder_paths/core/analytics/stats.py,sha256=qE6h0j8TZAbqbVpDeYlVKe0YbV5CENQcHbREzKyZ_s8,1426
|
|
52
53
|
wayfinder_paths/core/analytics/test_analytics.py,sha256=DNkVTsbWPLc9I1eeCD5wsPPqUDgN-npbGRhBgMKn3GM,5580
|
|
53
|
-
wayfinder_paths/core/clients/
|
|
54
|
-
wayfinder_paths/core/clients/
|
|
55
|
-
wayfinder_paths/core/clients/
|
|
56
|
-
wayfinder_paths/core/clients/
|
|
57
|
-
wayfinder_paths/core/clients/
|
|
58
|
-
wayfinder_paths/core/clients/
|
|
59
|
-
wayfinder_paths/core/clients/
|
|
60
|
-
wayfinder_paths/core/clients/
|
|
61
|
-
wayfinder_paths/core/clients/
|
|
62
|
-
wayfinder_paths/core/clients/
|
|
63
|
-
wayfinder_paths/core/clients/
|
|
64
|
-
wayfinder_paths/core/
|
|
65
|
-
wayfinder_paths/core/config.py,sha256=ktogrNlE4DSf1DZONN4_C-sjjuoMFqQtS7chx2KDVYY,15382
|
|
54
|
+
wayfinder_paths/core/clients/BRAPClient.py,sha256=aqsEDbTbf0D4SOQ1AoB3RPc6R8vt5PYkrTb7eEidfAg,4124
|
|
55
|
+
wayfinder_paths/core/clients/ClientManager.py,sha256=xllc8KIQvA6S3dx05Exw0Vh1PAeKPDSE832vaLmBwwg,4245
|
|
56
|
+
wayfinder_paths/core/clients/HyperlendClient.py,sha256=7BWqW2OwX_3JWXAQUMrsprwLusYBQ60LRToLOoVZu40,7912
|
|
57
|
+
wayfinder_paths/core/clients/LedgerClient.py,sha256=keHi1_dRA8kMVIEEcAe8OyDOr-XhoiRJ8eT6wXNz_EI,14327
|
|
58
|
+
wayfinder_paths/core/clients/PoolClient.py,sha256=GPa62hp3ajACyFfTXQpPfBLQVyt8VQX3R-IUJ6wtCis,4333
|
|
59
|
+
wayfinder_paths/core/clients/TokenClient.py,sha256=HyjMJKMxhPefi6A65le5DuGM9leUxYMdvLxTt2FDokI,4077
|
|
60
|
+
wayfinder_paths/core/clients/WalletClient.py,sha256=efvdJlS1fZfvNBU_hXn63mOKoETB0eh1kF6SWTSFWSk,1646
|
|
61
|
+
wayfinder_paths/core/clients/WayfinderClient.py,sha256=gl-YHTYDa5GStg5O2xETiL4dAaCLphRos-btB1rQzVE,4319
|
|
62
|
+
wayfinder_paths/core/clients/__init__.py,sha256=2xpZ4tBYkK0QjpBI88ZB4t4esfIc-enm0LqHdRo479M,1173
|
|
63
|
+
wayfinder_paths/core/clients/protocols.py,sha256=Z0vvce55wfXrSXfuO0Y-s9EfT9zvwUier4-XhwPZSTs,7984
|
|
64
|
+
wayfinder_paths/core/clients/sdk_example.py,sha256=SETyEJ_vw7pJcZVMxBMSjJk9Ag3levyn4WrpDueai_A,3589
|
|
65
|
+
wayfinder_paths/core/config.py,sha256=ADdrYAapSCwpV4ljSziBmxZV2Z2ORsu8ku-_MptSjjc,9060
|
|
66
66
|
wayfinder_paths/core/constants/__init__.py,sha256=upAVwHDgMXJ3DWaAuXo52UZktS8NZ17s5XwVH0qxgzg,591
|
|
67
67
|
wayfinder_paths/core/constants/base.py,sha256=BYQAD72XrsY6WRrOMIlUOpXLVANS7EYaS5Ell4Nj1H4,1551
|
|
68
68
|
wayfinder_paths/core/constants/erc20_abi.py,sha256=3ljIyUl6FesoEa4uprwNo-nF0Q5s73M9WEqXLw6ONI4,3214
|
|
69
69
|
wayfinder_paths/core/constants/hyperlend_abi.py,sha256=nIaqsfMl5-_InYN82pjz0FIKsT-AnNkwz0DIc9VrZSc,4331
|
|
70
70
|
wayfinder_paths/core/constants/moonwell_abi.py,sha256=ALb-kKdfF9aUtEHR8OlqvA-3zJ48N66RvVptTJyCfe4,13135
|
|
71
|
-
wayfinder_paths/core/engine/StrategyJob.py,sha256=
|
|
71
|
+
wayfinder_paths/core/engine/StrategyJob.py,sha256=4H_A3DdTzUUM2e-420I4FpjIhySw_wTJNs3LM_Cf0Xw,5254
|
|
72
72
|
wayfinder_paths/core/engine/__init__.py,sha256=WZ2KWnmOZnBocYrqdwq6EUHp6lmTyrKyXgHSHyQswnU,108
|
|
73
73
|
wayfinder_paths/core/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
wayfinder_paths/core/services/base.py,sha256=94Wvs7Ym7tK9J3k9lEOhSSIC7ptnMJ161dYtF4XTSZ8,4096
|
|
75
|
-
wayfinder_paths/core/services/local_evm_txn.py,sha256=
|
|
76
|
-
wayfinder_paths/core/services/local_token_txn.py,sha256=
|
|
75
|
+
wayfinder_paths/core/services/local_evm_txn.py,sha256=4SHMJz-PrnpLgz94MfchZifPmOlWoDAj_ADFXAWbDD0,12612
|
|
76
|
+
wayfinder_paths/core/services/local_token_txn.py,sha256=rRz2H6IZIUNrPAXoyXe0Qy_TAtTU2VpnHVxu6Im0kW4,8531
|
|
77
77
|
wayfinder_paths/core/services/web3_service.py,sha256=7iR7bfqfUQCQcdfEWVGqy04PZBtZTuzCDpfLt1a-4OI,1485
|
|
78
|
-
wayfinder_paths/core/
|
|
79
|
-
wayfinder_paths/core/strategies/Strategy.py,sha256=nEzry8V-FGSM-S1eBmT35Ba2cVOJn3hNNWenpTMAVv8,9455
|
|
78
|
+
wayfinder_paths/core/strategies/Strategy.py,sha256=1Ntx91B1QjN3jrPS36kpVIE36OzamOIea2n-OOBDdIo,9296
|
|
80
79
|
wayfinder_paths/core/strategies/__init__.py,sha256=2NjvvDw6sIQGUFV4Qo1olXTxUOY3GmCM8Ivz_J1FSmc,157
|
|
81
80
|
wayfinder_paths/core/strategies/base.py,sha256=-s0qeiGZl5CHTUL2PavGXM7ACkNlaa0c4jeZR_4DuBM,155
|
|
82
|
-
wayfinder_paths/core/strategies/descriptors.py,sha256=
|
|
81
|
+
wayfinder_paths/core/strategies/descriptors.py,sha256=2Olef0VWols1CWb-TWcb5pil2rztC0jP6F_Trpv2hIw,1958
|
|
83
82
|
wayfinder_paths/core/utils/__init__.py,sha256=TEylMYHnG37Z3mizSmw28bUm0vyNBFzf0Nc8dB_7l1A,73
|
|
84
|
-
wayfinder_paths/core/utils/evm_helpers.py,sha256=
|
|
85
|
-
wayfinder_paths/core/utils/wallets.py,sha256=
|
|
86
|
-
wayfinder_paths/core/wallets/README.md,sha256=
|
|
83
|
+
wayfinder_paths/core/utils/evm_helpers.py,sha256=EzUOsyGE9DmBp82hsrE_KTopYaSAu161AR-jVoYBC8U,5624
|
|
84
|
+
wayfinder_paths/core/utils/wallets.py,sha256=ccCQ128lDShO265AFMOCdijzPLucWe-Neg5wjLrOsnk,1948
|
|
85
|
+
wayfinder_paths/core/wallets/README.md,sha256=ks3tqO3I69PiOXp4hXfZ7ayupvfS0kB8PW3fBR2bDNA,3700
|
|
87
86
|
wayfinder_paths/core/wallets/WalletManager.py,sha256=sptj0Dya9iM87BDzUktrYM_Mw33xyVJNrRUTVfBjHGw,1870
|
|
88
87
|
wayfinder_paths/core/wallets/__init__.py,sha256=hIuhy64pJOs_8mAP7Zup28goXbT8qjBeeVYMkbqlyu8,315
|
|
89
88
|
wayfinder_paths/policies/enso.py,sha256=oytco04eeGjiRbZPGFE1YpH4NxvV0tfVM14QmlyzjkY,428
|
|
@@ -95,46 +94,46 @@ wayfinder_paths/policies/hyperliquid.py,sha256=hAxNtWdxavwf_a-AnlXMOmEYakkNBkrPT
|
|
|
95
94
|
wayfinder_paths/policies/moonwell.py,sha256=sKWLbruMKiW7Yh1DhXdVPRe0JBP-nooNybRz0G9PgvA,1605
|
|
96
95
|
wayfinder_paths/policies/prjx.py,sha256=6kfZ6OQFroFHYJl4vSWT-svwwfvoHlS_ZrcHt8nmZMU,743
|
|
97
96
|
wayfinder_paths/policies/util.py,sha256=r8xQLPvE3kU21_LG6VbkFI9sUSYltcsKunryZdHOUDA,912
|
|
98
|
-
wayfinder_paths/run_strategy.py,sha256=
|
|
97
|
+
wayfinder_paths/run_strategy.py,sha256=VWW9GIgX1KbNU8gp40qCef0ALbI-BiUoFTVVzBSfTZU,11505
|
|
99
98
|
wayfinder_paths/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
100
|
-
wayfinder_paths/scripts/create_strategy.py,sha256=
|
|
101
|
-
wayfinder_paths/scripts/make_wallets.py,sha256=
|
|
102
|
-
wayfinder_paths/scripts/run_strategy.py,sha256=
|
|
99
|
+
wayfinder_paths/scripts/create_strategy.py,sha256=WQQLBhClfjyLxEaKubQkBqBpSOFESnk1m6WTau9LylQ,5352
|
|
100
|
+
wayfinder_paths/scripts/make_wallets.py,sha256=RuCa9uYAsOzv8TyFdeOH89-SPJVGXwl5RuAqfJesLOk,5237
|
|
101
|
+
wayfinder_paths/scripts/run_strategy.py,sha256=xXa9Ch7mf1UXSO2UqyUZ6_IJG0TOjoYPyTzCU1U56TM,4450
|
|
103
102
|
wayfinder_paths/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
104
103
|
wayfinder_paths/strategies/basis_trading_strategy/README.md,sha256=rTUXQ2owEoPmXlfHcJfRFCwcQxlU3a4hOJGN5kaWWQ0,7176
|
|
105
104
|
wayfinder_paths/strategies/basis_trading_strategy/__init__.py,sha256=kVcehFjBUtoi5xzSHI56jtDghsy0nYl6XIE6BI1l6aI,79
|
|
106
105
|
wayfinder_paths/strategies/basis_trading_strategy/constants.py,sha256=PJ1WtSALxiuW1FXx-BF30ciFISEhO5VBfrSZyfhPuz0,45
|
|
107
106
|
wayfinder_paths/strategies/basis_trading_strategy/examples.json,sha256=q2wlAH8Gr-LUJeamKzWL1EtChL3TBWe0HQ4_P-VCdqQ,429
|
|
108
|
-
wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py,sha256=
|
|
109
|
-
wayfinder_paths/strategies/basis_trading_strategy/strategy.py,sha256=
|
|
110
|
-
wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py,sha256=
|
|
107
|
+
wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py,sha256=jjXv-w-uXdkw3-eSUgMmWCE7cPCRrkhyD4_TQjOnRO0,38640
|
|
108
|
+
wayfinder_paths/strategies/basis_trading_strategy/strategy.py,sha256=LpThF7HZ5eU2uqt08k5jMaaJYCSu79x5a7Z430-5KYw,161167
|
|
109
|
+
wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py,sha256=PWTJf2sqNb4BkKQytr_teqOqiV5n_7Fh5fPeZtr9Ito,40149
|
|
111
110
|
wayfinder_paths/strategies/basis_trading_strategy/types.py,sha256=rlbouTUOVPLfGPzMbsf-fUmMcn0R_OsG-IdfiBJmmqI,845
|
|
112
111
|
wayfinder_paths/strategies/config.py,sha256=5dv-8tWwoxH3Sxd9jtiw90shrLipEe3UlU-IYUBfciM,2762
|
|
113
|
-
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md,sha256=
|
|
112
|
+
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md,sha256=3dOmUCjs_zu4TgPhis0WG-U1XP_dl9aEGi49EkW_-jw,4180
|
|
114
113
|
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json,sha256=GbVo2p6QiG6M7Ma5s671lw8G9JwnMl1h0n9mrtt-ZS8,164
|
|
115
|
-
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py,sha256=
|
|
116
|
-
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py,sha256=
|
|
117
|
-
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md,sha256=
|
|
114
|
+
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py,sha256=Uwq0ca_1_xnlFqmEtdoC_ok44LvWQcqoCFD3vXc6xZ8,92388
|
|
115
|
+
wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py,sha256=YFyfls9HjlB5DbzcPWa7_OFbAJrW7i_HWhGtA6_YXPo,17067
|
|
116
|
+
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md,sha256=fv4uLA0Ioxp_LS35aFLhVCPJPoG_uvEYV89KYKmWv_o,4516
|
|
118
117
|
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json,sha256=kgNRdZcqne8XTm-Y8Hv1a1pdajRQsey4Qhd5La-iWss,164
|
|
119
|
-
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py,sha256=
|
|
120
|
-
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py,sha256=
|
|
121
|
-
wayfinder_paths/strategies/stablecoin_yield_strategy/README.md,sha256=
|
|
118
|
+
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py,sha256=G5V57vH9vpkLvSvkbVbowrwuD-qZr7WKhCRsDsyvED4,125713
|
|
119
|
+
wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py,sha256=UOR6bEC5Y2fiOu4idgK8TqlFgt7QazVo82QS3iVp9nA,31715
|
|
120
|
+
wayfinder_paths/strategies/stablecoin_yield_strategy/README.md,sha256=ZiHXmnyvh85sC-X1a_HzUcUZRvNEjwbmrSQkRIK8OQQ,4980
|
|
122
121
|
wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json,sha256=pL1DNFEvYvXKK7xXD5oQYFPQj3Cm1ocKnk6r_iZk0IY,423
|
|
123
|
-
wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py,sha256=
|
|
124
|
-
wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py,sha256=
|
|
125
|
-
wayfinder_paths/templates/adapter/README.md,sha256=
|
|
122
|
+
wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py,sha256=mCNN-HBsf880If1Eaglsn9xB4nG-mZN15MKMZqxpHbw,77232
|
|
123
|
+
wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py,sha256=gEw7kEeC9-TPTbsbAjhalsNQEcAdwelh_w8fT0i_bW0,21085
|
|
124
|
+
wayfinder_paths/templates/adapter/README.md,sha256=pat-Xdvu1y8-neKcgvW8ygVlCkuj2OdHLgp1prJDRkY,2894
|
|
126
125
|
wayfinder_paths/templates/adapter/adapter.py,sha256=UGPvD8SNcrEtYQXRTUxvK9WZ9Bzx1Xwb8sr9zSbqnuc,763
|
|
127
126
|
wayfinder_paths/templates/adapter/examples.json,sha256=KLHy3AgPIplAaZN0qY2A-HBMa1xXkMhIyusORovTD9w,79
|
|
128
127
|
wayfinder_paths/templates/adapter/test_adapter.py,sha256=PeG9ZZwx-cWXCDUKxrvj1cR8ljo9aXrKANZuz2hFAhk,1510
|
|
129
|
-
wayfinder_paths/templates/strategy/README.md,sha256=
|
|
128
|
+
wayfinder_paths/templates/strategy/README.md,sha256=721aGfPsKmQBIzwBcEav2cYWMRKNDnvj1ImKJSmH2MM,4963
|
|
130
129
|
wayfinder_paths/templates/strategy/examples.json,sha256=s8UdlD5uxLITQrRMCqgiaAP0IE0tdnnLfX-Zn-OChIc,135
|
|
131
130
|
wayfinder_paths/templates/strategy/strategy.py,sha256=dso2jhVphsdKNd17JPwnFAFzU01-1kHlWrKPAKIKSWw,2024
|
|
132
|
-
wayfinder_paths/templates/strategy/test_strategy.py,sha256=
|
|
131
|
+
wayfinder_paths/templates/strategy/test_strategy.py,sha256=TWw8NHOLy_dKgffHTK43N5He5gJ-oNUFi5QbSQM3l1k,7591
|
|
133
132
|
wayfinder_paths/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
134
133
|
wayfinder_paths/tests/test_smoke_manifest.py,sha256=kTcIa4qikcspVh2ohQIk0aHUdIvBvcQBfNbm3PNiVvg,1636
|
|
135
134
|
wayfinder_paths/tests/test_test_coverage.py,sha256=9NrZeVmP02D4W7Qc0XjciC05bhvdTCVibYjTGfa_GQk,7893
|
|
136
135
|
wayfinder_paths/tests/test_utils.py,sha256=pxHT0QKFlyJeJo8bFnKXzWcOdi6t8rbJ0JFCBaFCBRQ,2112
|
|
137
|
-
wayfinder_paths-0.1.
|
|
138
|
-
wayfinder_paths-0.1.
|
|
139
|
-
wayfinder_paths-0.1.
|
|
140
|
-
wayfinder_paths-0.1.
|
|
136
|
+
wayfinder_paths-0.1.14.dist-info/LICENSE,sha256=dYKnlkC_xosBAEQNUvB6cHMuhFgcUtN0oBR7E8_aR2Y,1066
|
|
137
|
+
wayfinder_paths-0.1.14.dist-info/METADATA,sha256=1ehMcYQAekFVNY2W_ft-xZFS97MB9BFNslG0vrGFZpc,24314
|
|
138
|
+
wayfinder_paths-0.1.14.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
139
|
+
wayfinder_paths-0.1.14.dist-info/RECORD,,
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Any
|
|
3
|
-
|
|
4
|
-
from loguru import logger
|
|
5
|
-
|
|
6
|
-
from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
|
|
7
|
-
from wayfinder_paths.core.settings import settings
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class AuthClient(WayfinderClient):
|
|
11
|
-
def __init__(self, api_key: str | None = None):
|
|
12
|
-
"""
|
|
13
|
-
Initialize AuthClient.
|
|
14
|
-
|
|
15
|
-
Args:
|
|
16
|
-
api_key: Optional API key for service account authentication.
|
|
17
|
-
If provided, uses API key auth. Otherwise falls back to config.json.
|
|
18
|
-
"""
|
|
19
|
-
super().__init__(api_key=api_key)
|
|
20
|
-
|
|
21
|
-
self.api_base_url = f"{settings.WAYFINDER_API_URL}"
|
|
22
|
-
self.logger = logger.bind(client="AuthClient")
|
|
23
|
-
|
|
24
|
-
def _is_using_api_key(self) -> bool:
|
|
25
|
-
"""Check if API key authentication is being used."""
|
|
26
|
-
if self._api_key:
|
|
27
|
-
return True
|
|
28
|
-
|
|
29
|
-
try:
|
|
30
|
-
creds = self._load_config_credentials()
|
|
31
|
-
if creds.get("api_key"):
|
|
32
|
-
return True
|
|
33
|
-
if os.getenv("WAYFINDER_API_KEY"):
|
|
34
|
-
return True
|
|
35
|
-
except Exception:
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
return False
|
|
39
|
-
|
|
40
|
-
async def authenticate(
|
|
41
|
-
self,
|
|
42
|
-
username: str | None = None,
|
|
43
|
-
password: str | None = None,
|
|
44
|
-
*,
|
|
45
|
-
refresh_token: str | None = None,
|
|
46
|
-
) -> dict[str, Any]:
|
|
47
|
-
"""
|
|
48
|
-
Obtain an access token via username/password or refresh token.
|
|
49
|
-
|
|
50
|
-
Expected endpoints:
|
|
51
|
-
- POST {api_base_url}/token/ (username, password) -> { access, refresh }
|
|
52
|
-
- POST {api_base_url}/token/refresh/ (refresh) -> { access }
|
|
53
|
-
"""
|
|
54
|
-
if refresh_token:
|
|
55
|
-
self.logger.debug(
|
|
56
|
-
"AuthClient.authenticate -> POST /token/refresh (refresh provided)"
|
|
57
|
-
)
|
|
58
|
-
url = f"{self.api_base_url}/auth/token/refresh/"
|
|
59
|
-
payload = {"refresh": refresh_token}
|
|
60
|
-
elif username and password:
|
|
61
|
-
self.logger.debug(
|
|
62
|
-
f"AuthClient.authenticate -> POST /token (username provided={bool(username)})"
|
|
63
|
-
)
|
|
64
|
-
url = f"{self.api_base_url}/auth/token/"
|
|
65
|
-
payload = {"username": username, "password": password}
|
|
66
|
-
else:
|
|
67
|
-
raise ValueError(
|
|
68
|
-
"Credentials required: provide username+password or refresh_token"
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
response = await self._request("POST", url, json=payload)
|
|
72
|
-
response.raise_for_status()
|
|
73
|
-
data = response.json()
|
|
74
|
-
|
|
75
|
-
access = data.get("access") or data.get("access_token")
|
|
76
|
-
refresh = data.get("refresh") or data.get("refresh_token")
|
|
77
|
-
if access or refresh:
|
|
78
|
-
self.set_tokens(access, refresh)
|
|
79
|
-
self.logger.debug(
|
|
80
|
-
f"AuthClient.authenticate <- success (access={'yes' if access else 'no'}, refresh={'yes' if refresh else 'no'})"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
return data
|